Files
labFusion/services/service-adapters/utils/time_formatter.py
GSRN 7eaea39928
Some checks failed
Integration Tests / integration-tests (push) Failing after 20s
Integration Tests / performance-tests (push) Has been skipped
Service Adapters (Python FastAPI) / test (3.11) (push) Failing after 24s
Service Adapters (Python FastAPI) / test (3.12) (push) Failing after 25s
Service Adapters (Python FastAPI) / test (3.13) (push) Failing after 25s
Service Adapters (Python FastAPI) / build (push) Has been skipped
fix: Clean up whitespace and improve code formatting across service adapters
### Summary of Changes
- Removed unnecessary whitespace and standardized formatting in multiple files, including `main.py`, `logging_middleware.py`, `general.py`, and various health checker implementations.
- Enhanced readability and maintainability of the codebase by ensuring consistent formatting practices.

### Expected Results
- Improved code clarity, making it easier for developers to read and understand the service adapters' code.
- Streamlined the codebase, facilitating future updates and maintenance.
2025-09-18 13:02:46 +02:00

200 lines
5.5 KiB
Python

"""
Time Formatting Utilities
This module provides utilities for formatting time durations and timestamps
into human-readable formats for the frontend.
"""
import re
from datetime import datetime, timezone
from typing import Optional, Union
def format_uptime_for_frontend(uptime_value: Optional[str]) -> str:
"""
Format uptime value for frontend display in "Xd Xh Xm" format.
Args:
uptime_value: Raw uptime value (timestamp, epoch, duration string, etc.)
Returns:
Formatted uptime string like "2d 5h 30m" or "0d 0h" if invalid
"""
if not uptime_value:
return "0d 0h"
try:
# Try to parse as timestamp (ISO format)
if _is_timestamp(uptime_value):
return _format_timestamp_uptime(uptime_value)
# Try to parse as epoch timestamp
if _is_epoch(uptime_value):
return _format_epoch_uptime(uptime_value)
# Try to parse as duration string (e.g., "2h 30m", "5d 2h 15m")
if _is_duration_string(uptime_value):
return _format_duration_string(uptime_value)
# Try to parse as numeric seconds
if _is_numeric_seconds(uptime_value):
return _format_seconds_uptime(float(uptime_value))
# If none of the above, return as-is or default
return uptime_value if len(uptime_value) < 50 else "0d 0h"
except Exception:
return "0d 0h"
def _is_timestamp(value: str) -> bool:
"""Check if value is an ISO timestamp."""
try:
datetime.fromisoformat(value.replace("Z", "+00:00"))
return True
except (ValueError, AttributeError):
return False
def _is_epoch(value: str) -> bool:
"""Check if value is an epoch timestamp."""
try:
float(value)
return len(value) >= 10 and float(value) > 1000000000 # Reasonable epoch range
except (ValueError, TypeError):
return False
def _is_duration_string(value: str) -> bool:
"""Check if value is a duration string like '2h 30m' or '5d 2h 15m'."""
# Look for patterns like "2h 30m", "5d 2h 15m", "1d 2h 3m 4s"
pattern = r"^\d+[dhms]\s*(\d+[dhms]\s*)*$"
return bool(re.match(pattern, value.strip()))
def _is_numeric_seconds(value: str) -> bool:
"""Check if value is numeric seconds."""
try:
float(value)
return True
except (ValueError, TypeError):
return False
def _format_timestamp_uptime(timestamp: str) -> str:
"""Format timestamp uptime (time since timestamp)."""
try:
# Parse timestamp
dt = datetime.fromisoformat(timestamp.replace("Z", "+00:00"))
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
# Calculate time difference
now = datetime.now(timezone.utc)
diff = now - dt
return _format_timedelta(diff)
except Exception:
return "0d 0h"
def _format_epoch_uptime(epoch_str: str) -> str:
"""Format epoch timestamp uptime."""
try:
epoch = float(epoch_str)
dt = datetime.fromtimestamp(epoch, tz=timezone.utc)
now = datetime.now(timezone.utc)
diff = now - dt
return _format_timedelta(diff)
except Exception:
return "0d 0h"
def _format_duration_string(duration: str) -> str:
"""Format duration string to standardized format."""
try:
# Parse duration string like "2h 30m" or "5d 2h 15m"
total_seconds = _parse_duration_string(duration)
return _format_seconds_uptime(total_seconds)
except Exception:
return "0d 0h"
def _format_seconds_uptime(seconds: float) -> str:
"""Format seconds to "Xd Xh Xm" format."""
return _format_timedelta_from_seconds(seconds)
def _parse_duration_string(duration: str) -> float:
"""Parse duration string to total seconds."""
total_seconds = 0
# Extract days
days_match = re.search(r"(\d+)d", duration)
if days_match:
total_seconds += int(days_match.group(1)) * 86400
# Extract hours
hours_match = re.search(r"(\d+)h", duration)
if hours_match:
total_seconds += int(hours_match.group(1)) * 3600
# Extract minutes
minutes_match = re.search(r"(\d+)m", duration)
if minutes_match:
total_seconds += int(minutes_match.group(1)) * 60
# Extract seconds
seconds_match = re.search(r"(\d+)s", duration)
if seconds_match:
total_seconds += int(seconds_match.group(1))
return total_seconds
def _format_timedelta(td) -> str:
"""Format timedelta to "Xd Xh Xm" format."""
total_seconds = int(td.total_seconds())
return _format_timedelta_from_seconds(total_seconds)
def _format_timedelta_from_seconds(total_seconds: Union[int, float]) -> str:
"""Format total seconds to "Xd Xh Xm" format."""
if total_seconds < 0:
return "0d 0h"
# Convert to int to avoid decimal places
total_seconds = int(total_seconds)
days = total_seconds // 86400
hours = (total_seconds % 86400) // 3600
minutes = (total_seconds % 3600) // 60
# Only show days if > 0
if days > 0:
return f"{days}d {hours}h {minutes}m"
elif hours > 0:
return f"{hours}h {minutes}m"
else:
return f"{minutes}m"
def format_response_time(seconds: Optional[float]) -> str:
"""
Format response time for display.
Args:
seconds: Response time in seconds
Returns:
Formatted response time string
"""
if seconds is None:
return "N/A"
if seconds < 1:
return f"{seconds * 1000:.0f}ms"
else:
return f"{seconds:.2f}s"