utils.py
 1  """
 2  Utility functions for workflow execution.
 3  """
 4  
 5  import re
 6  from typing import Union
 7  
 8  
 9  def parse_duration(duration_str: Union[str, int, float]) -> float:
10      """
11      Parse duration string to seconds.
12  
13      Supports formats:
14      - '5s', '30s' - seconds
15      - '1m', '5m' - minutes
16      - '1h', '2h' - hours
17      - '1d' - days
18      - Plain numbers (int/float) treated as seconds
19      - '30' (string without suffix) treated as seconds
20  
21      Args:
22          duration_str: Duration as string (e.g., '5s', '1m') or number
23  
24      Returns:
25          Duration in seconds as float
26  
27      Raises:
28          ValueError: If format is invalid
29      """
30      # Handle numeric input directly
31      if isinstance(duration_str, (int, float)):
32          return float(duration_str)
33  
34      # Handle string input
35      duration_str = str(duration_str).strip().lower()
36  
37      # Try to match duration pattern
38      match = re.match(r"^(\d+(?:\.\d+)?)\s*(s|m|h|d)?$", duration_str)
39      if not match:
40          raise ValueError(
41              f"Invalid duration format: '{duration_str}'. "
42              "Expected format: number with optional suffix (s/m/h/d), e.g., '30s', '5m', '1h'"
43          )
44  
45      value = float(match.group(1))
46      unit = match.group(2) or "s"  # Default to seconds if no suffix
47  
48      multipliers = {
49          "s": 1,
50          "m": 60,
51          "h": 3600,
52          "d": 86400,
53      }
54  
55      return value * multipliers[unit]