Utils API
This module contains helper functions for parsing dates and formatting HTTP headers.
Date Parsing
The library supports multiple date formats via the DateInput type alias:
- ISO 8601 Strings:
"2024-01-01", "2024-01-01T12:00:00Z"
- Date/Datetime Objects:
datetime.date(2024, 1, 1), datetime.datetime(2024, 1, 1, 12, 0, 0)
- Integers/Floats: Unix timestamps
All dates are internally converted to UTC timestamps for the Deprecation header (as per RFC 9745) and HTTP-date format for the Sunset header.
Reference
fastapi_deprecation.utils
Format date for 'Deprecation' header (RFC 9745).
Format: @ (RFC 9651 Date)
Source code in src/fastapi_deprecation/utils.py
| def format_deprecation_date(value: DateInput) -> str:
"""
Format date for 'Deprecation' header (RFC 9745).
Format: @<timestamp> (RFC 9651 Date)
"""
dt = parse_date(value)
timestamp = int(dt.timestamp())
return f"@{timestamp}"
|
Format date for 'Sunset' header (RFC 8594).
Format: HTTP-date (RFC 7231)
Source code in src/fastapi_deprecation/utils.py
| def format_sunset_date(value: DateInput) -> str:
"""
Format date for 'Sunset' header (RFC 8594).
Format: HTTP-date (RFC 7231)
"""
dt = parse_date(value)
return format_datetime(dt, usegmt=True)
|
parse_date(value)
Parse input into a timezone-aware UTC datetime object.
Supports:
- datetime (converted to UTC)
- date (converted to UTC midnight)
- str (parsed via dateutil, assumed UTC if allowed, or local if implied)
- int/float (Unix timestamp)
Source code in src/fastapi_deprecation/utils.py
| def parse_date(value: DateInput) -> datetime:
"""
Parse input into a timezone-aware UTC datetime object.
Supports:
- datetime (converted to UTC)
- date (converted to UTC midnight)
- str (parsed via dateutil, assumed UTC if allowed, or local if implied)
- int/float (Unix timestamp)
"""
if isinstance(value, datetime):
if value.tzinfo is None:
# Assume UTC for naive to avoid "it works on my machine" issues.
return value.replace(tzinfo=timezone.utc)
return value.astimezone(timezone.utc)
if isinstance(value, date):
return datetime(value.year, value.month, value.day, tzinfo=timezone.utc)
if isinstance(value, (int, float)):
return datetime.fromtimestamp(value, tz=timezone.utc)
if isinstance(value, str):
try:
dt = dateutil.parser.parse(value)
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
return dt.astimezone(timezone.utc)
except (ValueError, OverflowError):
raise ValueError(f"Invalid date string: {value}")
raise TypeError(f"Unsupported date type: {type(value)}")
|