""" Base request models for API endpoints. This module provides base request models that can be used across different endpoints to ensure consistent request handling and validation. """ from typing import Dict, Any, Generic, TypeVar, Optional, get_args, get_origin from pydantic import RootModel, BaseModel, Field, ConfigDict T = TypeVar("T") class BaseRequestModel(RootModel[T]): """Base model for all API requests. This model can be extended to create specific request models for different endpoints. """ model_config = ConfigDict( json_schema_extra={"example": {}} # Will be populated by subclasses ) @classmethod def model_json_schema(cls, *args, **kwargs): schema = super().model_json_schema(*args, **kwargs) if hasattr(cls, "__orig_bases__"): generic_type = get_args(cls.__orig_bases__[0])[0] if generic_type and hasattr(generic_type, "model_json_schema"): type_schema = generic_type.model_json_schema() if "properties" in type_schema: schema["properties"] = type_schema["properties"] if "required" in type_schema: schema["required"] = type_schema["required"] if "title" in type_schema: schema["title"] = type_schema["title"] if "example" in type_schema: schema["example"] = type_schema["example"] elif "properties" in type_schema: schema["example"] = { key: prop.get("example", "string") for key, prop in type_schema["properties"].items() } schema["type"] = "object" return schema @property def data(self) -> T: return self.root class DictRequestModel(RootModel[Dict[str, Any]]): """Request model for endpoints that accept dictionary data.""" model_config = ConfigDict( json_schema_extra={ "example": { "key1": "value1", "key2": "value2", "nested": {"inner_key": "inner_value"}, } } ) @classmethod def model_json_schema(cls, *args, **kwargs): schema = super().model_json_schema(*args, **kwargs) schema.update( { "title": "Dictionary Request Model", "type": "object", "properties": { "key1": {"type": "string", "example": "value1"}, "key2": {"type": "string", "example": "value2"}, "nested": { "type": "object", "properties": { "inner_key": {"type": "string", "example": "inner_value"} }, }, }, "example": { "key1": "value1", "key2": "value2", "nested": {"inner_key": "inner_value"}, }, } ) return schema @property def data(self) -> Dict[str, Any]: return self.root class SuccessResponse(BaseModel): """Standard success response model.""" token: str = Field(..., example="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...") user_info: Dict[str, Any] = Field( ..., example={ "id": "123", "username": "john.doe", "email": "john@example.com", "role": "user", }, ) model_config = ConfigDict( json_schema_extra={ "example": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user_info": { "id": "123", "username": "john.doe", "email": "john@example.com", "role": "user", }, } } )