41 lines
1011 B
Python
41 lines
1011 B
Python
from datetime import datetime, timezone, timedelta
|
|
from typing import Annotated
|
|
|
|
from pydantic import BaseModel, BeforeValidator
|
|
|
|
CST = timezone(timedelta(hours=8))
|
|
|
|
|
|
def _strip_tz(v: datetime | str | None) -> datetime | None:
|
|
if v is None:
|
|
return None
|
|
try:
|
|
dt = v if isinstance(v, datetime) else datetime.fromisoformat(str(v))
|
|
if dt.tzinfo is not None:
|
|
if dt.tzinfo.utcoffset(None) == timedelta(0):
|
|
dt = dt.astimezone(CST)
|
|
return dt.replace(tzinfo=None)
|
|
return dt
|
|
except (ValueError, TypeError):
|
|
return v if isinstance(v, datetime) else None
|
|
|
|
|
|
NaiveDatetime = Annotated[datetime, BeforeValidator(_strip_tz)]
|
|
NaiveDatetimeOptional = Annotated[datetime | None, BeforeValidator(_strip_tz)]
|
|
|
|
|
|
class ErrorResponse(BaseModel):
|
|
detail: str
|
|
|
|
|
|
class PaginationParams(BaseModel):
|
|
page: int = 1
|
|
page_size: int = 20
|
|
|
|
|
|
class PaginatedResponse(BaseModel):
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
items: list
|