182 lines
6.0 KiB
Python
182 lines
6.0 KiB
Python
"""
|
|
Abstract base classes for API route and event handling.
|
|
|
|
This module provides core abstractions for route configuration and factory,
|
|
with support for authentication and event handling.
|
|
"""
|
|
|
|
from typing import Optional, Dict, Any, List, Type, Union, ClassVar, Tuple, TypeVar
|
|
from dataclasses import dataclass, field
|
|
from pydantic import BaseModel
|
|
|
|
ResponseModel = TypeVar('ResponseModel', bound=BaseModel)
|
|
|
|
|
|
@dataclass
|
|
class EndpointFactoryConfig:
|
|
"""Configuration class for API endpoints.
|
|
|
|
Attributes:
|
|
endpoint: URL path for this endpoint
|
|
method: HTTP method (GET, POST, etc.)
|
|
summary: Short description for API documentation
|
|
description: Detailed description for API documentation
|
|
is_auth_required: Whether authentication is required
|
|
is_event_required: Whether event handling is required
|
|
request_model: Expected request model type
|
|
extra_options: Additional endpoint options
|
|
response_model: Expected response model type
|
|
"""
|
|
endpoint: str
|
|
method: str
|
|
summary: str
|
|
description: str
|
|
is_auth_required: bool
|
|
is_event_required: bool
|
|
request_model: Type[BaseModel]
|
|
extra_options: Dict[str, Any] = field(default_factory=dict)
|
|
response_model: Optional[Type[BaseModel]] = None
|
|
|
|
|
|
@dataclass
|
|
class RouteFactoryConfig:
|
|
"""Configuration class for API route factories.
|
|
|
|
Attributes:
|
|
name: Route name
|
|
tags: List of tags for API documentation
|
|
prefix: URL prefix for all endpoints in this route
|
|
include_in_schema: Whether to include in OpenAPI schema
|
|
endpoints: List of endpoint configurations
|
|
extra_options: Additional route options
|
|
"""
|
|
name: str
|
|
tags: Union[str, List[str]]
|
|
prefix: str
|
|
include_in_schema: bool = True
|
|
endpoints: List[EndpointFactoryConfig] = field(default_factory=list)
|
|
extra_options: Dict[str, Any] = field(default_factory=dict)
|
|
|
|
def __post_init__(self):
|
|
"""Validate and normalize configuration after initialization."""
|
|
if isinstance(self.tags, str):
|
|
self.tags = [self.tags]
|
|
|
|
def as_dict(self) -> Dict[str, Any]:
|
|
"""Convert configuration to dictionary format."""
|
|
return {
|
|
"name": self.name,
|
|
"tags": self.tags,
|
|
"prefix": self.prefix,
|
|
"include_in_schema": self.include_in_schema,
|
|
"endpoints": [
|
|
{
|
|
"endpoint": ep.endpoint,
|
|
"method": ep.method,
|
|
"summary": ep.summary,
|
|
"description": ep.description,
|
|
"is_auth_required": ep.is_auth_required,
|
|
"is_event_required": ep.is_event_required,
|
|
"response_model": ep.response_model.__name__ if ep.response_model else None,
|
|
"request_model": ep.request_model.__name__,
|
|
"extra_options": ep.extra_options
|
|
}
|
|
for ep in self.endpoints
|
|
],
|
|
"extra_options": self.extra_options
|
|
}
|
|
|
|
|
|
class ActionsSchema:
|
|
"""Base class for defining API action schemas.
|
|
|
|
This class handles endpoint registration and validation in the database.
|
|
Subclasses should implement specific validation logic.
|
|
"""
|
|
def __init__(self, endpoint: str):
|
|
"""Initialize with an API endpoint path.
|
|
|
|
Args:
|
|
endpoint: The API endpoint path (e.g. "/users/create")
|
|
"""
|
|
self.endpoint = endpoint
|
|
|
|
def retrieve_action_from_endpoint(self) -> Dict[str, Any]:
|
|
"""Retrieve the endpoint registration from the database.
|
|
|
|
Returns:
|
|
Dict containing the endpoint registration data
|
|
|
|
Raises:
|
|
HTTPException: If endpoint is not found in database
|
|
"""
|
|
raise NotImplementedError("Subclasses must implement retrieve_action_from_endpoint")
|
|
|
|
|
|
class ActionsSchemaFactory:
|
|
"""Factory class for creating and validating action schemas.
|
|
|
|
This class ensures proper initialization and validation of API endpoints
|
|
through their action schemas.
|
|
"""
|
|
def __init__(self, action: ActionsSchema):
|
|
"""Initialize with an action schema.
|
|
|
|
Args:
|
|
action: The action schema to initialize
|
|
|
|
Raises:
|
|
HTTPException: If action initialization fails
|
|
"""
|
|
self.action = action
|
|
self.action_match = self.action.retrieve_action_from_endpoint()
|
|
|
|
|
|
class MethodToEvent:
|
|
"""Base class for mapping methods to API events with type safety.
|
|
|
|
This class provides a framework for handling API events with proper
|
|
type checking for tokens and response models.
|
|
|
|
Type Parameters:
|
|
TokenType: Type of authentication token
|
|
ResponseModel: Type of response model
|
|
"""
|
|
action_key: ClassVar[Optional[str]] = None
|
|
event_type: ClassVar[Optional[str]] = None
|
|
event_description: ClassVar[str] = ""
|
|
event_category: ClassVar[str] = ""
|
|
__event_keys__: ClassVar[Dict[str, str]] = {}
|
|
__event_validation__: ClassVar[List[Tuple[Type[ResponseModel], List[Dict[str, Any]]]]] = []
|
|
|
|
@classmethod
|
|
def retrieve_language_parameters(
|
|
cls, language: str, function_code: str
|
|
) -> Dict[str, str]:
|
|
"""Retrieve language-specific parameters for an event.
|
|
|
|
Args:
|
|
language: Language code (e.g. 'tr', 'en')
|
|
function_code: Function identifier
|
|
|
|
Returns:
|
|
Dictionary of language-specific field mappings
|
|
"""
|
|
validation_dict = dict(cls.__event_validation__)
|
|
if function_code not in validation_dict:
|
|
return {}
|
|
|
|
event_response_model, event_language_models = validation_dict[function_code]
|
|
|
|
# Collect language-specific field mappings
|
|
language_models = {}
|
|
for model in event_language_models:
|
|
language_models.update(model.get(language, model.get("tr", {})))
|
|
|
|
# Map response model fields to language-specific values
|
|
return {
|
|
field: language_models[field]
|
|
for field in event_response_model.model_fields
|
|
if field in language_models
|
|
}
|