diff --git a/app/assets/api/schemas_out.py b/app/assets/api/schemas_out.py index f36447856..db7efbd4b 100644 --- a/app/assets/api/schemas_out.py +++ b/app/assets/api/schemas_out.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timezone from typing import Any from pydantic import BaseModel, ConfigDict, Field, field_serializer @@ -20,7 +20,11 @@ class AssetSummary(BaseModel): @field_serializer("created_at", "updated_at", "last_access_time") def _serialize_datetime(self, v: datetime | None, _info): - return v.isoformat() if v else None + if v is None: + return None + if v.tzinfo is None: + v = v.replace(tzinfo=timezone.utc) + return v.isoformat() class AssetsList(BaseModel): @@ -41,7 +45,11 @@ class AssetUpdated(BaseModel): @field_serializer("updated_at") def _serialize_updated_at(self, v: datetime | None, _info): - return v.isoformat() if v else None + if v is None: + return None + if v.tzinfo is None: + v = v.replace(tzinfo=timezone.utc) + return v.isoformat() class AssetDetail(BaseModel): @@ -60,7 +68,11 @@ class AssetDetail(BaseModel): @field_serializer("created_at", "last_access_time") def _serialize_datetime(self, v: datetime | None, _info): - return v.isoformat() if v else None + if v is None: + return None + if v.tzinfo is None: + v = v.replace(tzinfo=timezone.utc) + return v.isoformat() class AssetCreated(AssetDetail): diff --git a/app/assets/helpers.py b/app/assets/helpers.py index 3798f3933..4c2b0f681 100644 --- a/app/assets/helpers.py +++ b/app/assets/helpers.py @@ -34,7 +34,7 @@ def escape_sql_like_string(s: str, escape: str = "!") -> tuple[str, str]: def get_utc_now() -> datetime: - """Naive UTC timestamp (no tzinfo). We always treat DB datetimes as UTC.""" + """Naive UTC timestamp (no tzinfo) for DB columns declared with timezone=False.""" return datetime.now(timezone.utc).replace(tzinfo=None) diff --git a/app/database/models.py b/app/database/models.py index e7572677a..aefcfdcf2 100644 --- a/app/database/models.py +++ b/app/database/models.py @@ -1,5 +1,5 @@ from typing import Any -from datetime import datetime +from datetime import datetime, timezone from sqlalchemy.orm import DeclarativeBase class Base(DeclarativeBase): @@ -13,6 +13,8 @@ def to_dict(obj: Any, include_none: bool = False) -> dict[str, Any]: if val is None and not include_none: continue if isinstance(val, datetime): + if val.tzinfo is None: + val = val.replace(tzinfo=timezone.utc) out[field] = val.isoformat() else: out[field] = val