124 lines
3.9 KiB
Python
124 lines
3.9 KiB
Python
"""
|
|
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",
|
|
},
|
|
}
|
|
}
|
|
)
|