mirror of
https://github.com/hanzoai/python-sdk.git
synced 2026-10-27 04:20:09 +00:00
114 lines
3.0 KiB
Python
114 lines
3.0 KiB
Python
"""Human-readable timeout parsing utilities."""
|
|
|
|
import re
|
|
from typing import Union
|
|
|
|
|
|
def parse_timeout(timeout_str: Union[str, int, float]) -> float:
|
|
"""Parse timeout from human-readable string or numeric value.
|
|
|
|
Supports formats like:
|
|
- "2min", "5m", "120s", "30sec", "1.5h", "0.5hr"
|
|
- 120 (seconds as number)
|
|
- "120" (seconds as string)
|
|
|
|
Args:
|
|
timeout_str: Timeout value as string or number
|
|
|
|
Returns:
|
|
Timeout in seconds as float
|
|
|
|
Raises:
|
|
ValueError: If format is not recognized
|
|
"""
|
|
if isinstance(timeout_str, (int, float)):
|
|
return float(timeout_str)
|
|
|
|
if isinstance(timeout_str, str):
|
|
# Handle pure numeric strings
|
|
try:
|
|
return float(timeout_str)
|
|
except ValueError:
|
|
pass
|
|
|
|
# Handle human-readable formats
|
|
timeout_str = timeout_str.lower().strip()
|
|
|
|
# Regex patterns for different time units
|
|
patterns = [
|
|
# Hours: 1h, 1.5hr, 2hour, 3hours
|
|
(r"^(\d*\.?\d+)\s*h(?:r|our|ours)?$", 3600),
|
|
# Minutes: 2m, 5min, 10mins, 1.5minute
|
|
(r"^(\d*\.?\d+)\s*m(?:in|ins|inute|inutes)?$", 60),
|
|
# Seconds: 30s, 120sec, 45secs, 60second, 90seconds
|
|
(r"^(\d*\.?\d+)\s*s(?:ec|ecs|econd|econds)?$", 1),
|
|
]
|
|
|
|
for pattern, multiplier in patterns:
|
|
match = re.match(pattern, timeout_str)
|
|
if match:
|
|
value = float(match.group(1))
|
|
return value * multiplier
|
|
|
|
# If no pattern matches, raise error
|
|
raise ValueError(
|
|
f"Invalid timeout format: '{timeout_str}'. "
|
|
f"Supported formats: 2min, 5m, 120s, 30sec, 1.5h, 0.5hr, or numeric seconds."
|
|
)
|
|
|
|
raise ValueError(f"Unsupported timeout type: {type(timeout_str)}")
|
|
|
|
|
|
def format_timeout(seconds: float) -> str:
|
|
"""Format timeout seconds into human-readable string.
|
|
|
|
Args:
|
|
seconds: Timeout in seconds
|
|
|
|
Returns:
|
|
Human-readable string like "2m", "90s", "1.5h"
|
|
"""
|
|
if seconds >= 3600: # >= 1 hour
|
|
hours = seconds / 3600
|
|
if hours.is_integer():
|
|
return f"{int(hours)}h"
|
|
else:
|
|
return f"{hours:.1f}h"
|
|
elif seconds >= 60: # >= 1 minute
|
|
minutes = seconds / 60
|
|
if minutes.is_integer():
|
|
return f"{int(minutes)}m"
|
|
else:
|
|
return f"{minutes:.1f}m"
|
|
else: # < 1 minute
|
|
if seconds.is_integer():
|
|
return f"{int(seconds)}s"
|
|
else:
|
|
return f"{seconds:.1f}s"
|
|
|
|
|
|
# Test the parser
|
|
if __name__ == "__main__":
|
|
test_cases = [
|
|
"2min",
|
|
"5m",
|
|
"120s",
|
|
"30sec",
|
|
"1.5h",
|
|
"0.5hr",
|
|
"90",
|
|
120,
|
|
3600.0,
|
|
"1hour",
|
|
"2hours",
|
|
"30seconds",
|
|
]
|
|
|
|
for case in test_cases:
|
|
try:
|
|
result = parse_timeout(case)
|
|
formatted = format_timeout(result)
|
|
print(f"{case} -> {result}s ({formatted})")
|
|
except ValueError as e:
|
|
print(f"{case} -> ERROR: {e}")
|