85 lines
1.9 KiB
Python
85 lines
1.9 KiB
Python
from __future__ import annotations
|
|
|
|
import uuid
|
|
from datetime import datetime
|
|
from typing import Any, Generic, TypeVar
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
class BaseSchema(BaseModel):
|
|
"""Base schema with common configuration."""
|
|
|
|
model_config = ConfigDict(
|
|
from_attributes=True,
|
|
populate_by_name=True,
|
|
str_strip_whitespace=True,
|
|
)
|
|
|
|
|
|
class PaginationParams(BaseModel):
|
|
"""Pagination query parameters."""
|
|
|
|
page: int = Field(default=1, ge=1, description="Page number")
|
|
page_size: int = Field(default=20, ge=1, le=100, description="Items per page")
|
|
|
|
@property
|
|
def offset(self) -> int:
|
|
return (self.page - 1) * self.page_size
|
|
|
|
|
|
class PaginatedResponse(BaseSchema, Generic[T]):
|
|
"""Paginated response wrapper."""
|
|
|
|
items: list[T]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
total_pages: int
|
|
|
|
@classmethod
|
|
def create(cls, items: list[T], total: int, page: int, page_size: int) -> PaginatedResponse[T]:
|
|
total_pages = (total + page_size - 1) // page_size if page_size > 0 else 0
|
|
return cls(
|
|
items=items,
|
|
total=total,
|
|
page=page,
|
|
page_size=page_size,
|
|
total_pages=total_pages,
|
|
)
|
|
|
|
|
|
class ErrorResponse(BaseSchema):
|
|
"""Standard error response."""
|
|
|
|
detail: str
|
|
error_code: str | None = None
|
|
errors: list[dict[str, Any]] | None = None
|
|
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
|
|
|
|
|
class SuccessResponse(BaseSchema):
|
|
"""Standard success response."""
|
|
|
|
message: str
|
|
data: dict[str, Any] | None = None
|
|
|
|
|
|
class HealthResponse(BaseSchema):
|
|
"""Health check response."""
|
|
|
|
status: str
|
|
version: str
|
|
environment: str
|
|
database: str
|
|
redis: str
|
|
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
|
|
|
|
|
class IDResponse(BaseSchema):
|
|
"""Response containing just an ID."""
|
|
|
|
id: uuid.UUID
|