""" Base classes for controllers and schemas. All domain controllers and Pydantic models should inherit from these. """ from abc import ABC, abstractmethod from datetime import datetime from typing import Any from fastapi import APIRouter from pydantic import BaseModel, ConfigDict class BaseController(ABC): """ Base controller with lazy router instantiation. All domain controllers inherit from this and implement create_router(). Usage: class UsersController(BaseController): def __init__(self): super().__init__(prefix="/users", tags=["Users"]) def create_router(self) -> APIRouter: router = APIRouter(prefix=self.prefix, tags=self.tags) @router.get("/") async def list_users(): return [] return router users_controller = UsersController() """ def __init__(self, prefix: str, tags: list[str]): self.prefix = prefix self.tags = tags self._router = None @abstractmethod def create_router(self) -> APIRouter: """Create and configure the FastAPI router with all routes.""" pass @property def router(self) -> APIRouter: """Lazy router instantiation.""" if self._router is None: self._router = self.create_router() return self._router class BaseSchema(BaseModel): """ Base Pydantic model with standardized configuration. All domain schemas should inherit from this. """ model_config = ConfigDict( strict=False, populate_by_name=True, use_enum_values=True, validate_assignment=True, json_encoders={ datetime: lambda v: v.isoformat() if v else None } ) def dict_without_none(self) -> dict[str, Any]: """Return model as dict, excluding None values.""" return {k: v for k, v in self.model_dump().items() if v is not None}