Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/rotator_library/usage_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1211,6 +1211,23 @@ def _format_timestamp_local(self, ts: Optional[float]) -> Optional[str]:
except (OSError, ValueError, OverflowError):
return None

def _format_timestamp_iso(self, ts: Optional[float]) -> Optional[str]:
"""
Format Unix timestamp as ISO 8601 UTC string for API responses.

Args:
ts: Unix timestamp or None

Returns:
Formatted string like "2025-12-07T14:30:17Z" or None
"""
if ts is None:
return None
try:
return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat()
except (OSError, ValueError, OverflowError):
return None
Comment on lines +1214 to +1229
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation of isoformat() on a timezone-aware datetime will produce a +00:00 offset instead of the Z suffix mentioned in the docstring. Additionally, it may include microseconds if the timestamp has them. For a cleaner API response that matches the docstring, consider:

Suggested change
def _format_timestamp_iso(self, ts: Optional[float]) -> Optional[str]:
"""
Format Unix timestamp as ISO 8601 UTC string for API responses.
Args:
ts: Unix timestamp or None
Returns:
Formatted string like "2025-12-07T14:30:17Z" or None
"""
if ts is None:
return None
try:
return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat()
except (OSError, ValueError, OverflowError):
return None
try:
return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z")
except (OSError, ValueError, OverflowError):


def _add_readable_timestamps(self, data: Dict) -> Dict:
"""
Add human-readable timestamp fields to usage data before saving.
Expand Down Expand Up @@ -3723,6 +3740,9 @@ async def get_stats_for_endpoint(
"approx_cost": model_stats.get("approx_cost", 0.0),
"window_start_ts": model_stats.get("window_start_ts"),
"quota_reset_ts": model_stats.get("quota_reset_ts"),
"reset_time_iso": self._format_timestamp_iso(
model_stats.get("quota_reset_ts")
),
Comment on lines 3741 to +3745
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with reset_time_iso, consider adding window_start_iso as well. This provides a readable format for both key time metrics in the response.

Suggested change
"window_start_ts": model_stats.get("window_start_ts"),
"quota_reset_ts": model_stats.get("quota_reset_ts"),
"reset_time_iso": self._format_timestamp_iso(
model_stats.get("quota_reset_ts")
),
"window_start_ts": model_stats.get("window_start_ts"),
"window_start_iso": self._format_timestamp_iso(
model_stats.get("window_start_ts")
),
"quota_reset_ts": model_stats.get("quota_reset_ts"),
"reset_time_iso": self._format_timestamp_iso(
model_stats.get("quota_reset_ts")
),

# Quota baseline fields (Antigravity-specific)
"baseline_remaining_fraction": model_stats.get(
"baseline_remaining_fraction"
Expand Down
Loading