""" 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, Callable from dataclasses import dataclass, field from pydantic import BaseModel ResponseModel = TypeVar('ResponseModel', bound=BaseModel) @dataclass class EndpointFactoryConfig: """Configuration class for API endpoints. Attributes: url_of_endpoint: Full URL path for this endpoint endpoint: URL path for this endpoint method: HTTP method (GET, POST, etc.) summary: Short description for API documentation description: Detailed description for API documentation endpoint_function: Function to handle the endpoint is_auth_required: Whether authentication is required is_event_required: Whether event handling is required extra_options: Additional endpoint options """ url_prefix :str url_endpoint: str url_of_endpoint: str endpoint: str method: str summary: str description: str endpoint_function: Callable is_auth_required: bool = True is_event_required: bool = False extra_options: Dict[str, Any] = field(default_factory=dict) def __post_init__(self): """Post-initialization processing. Apply appropriate wrappers based on auth and event requirements: - If both auth and event required -> wrap with with_token_event - If only auth required -> wrap with MiddlewareModule.auth_required """ # Store url_of_endpoint for the handler self.endpoint_function.url_of_endpoint = self.url_of_endpoint if self.is_auth_required and self.is_event_required: from events.utils import with_token_event self.endpoint_function = with_token_event(self.endpoint_function) elif self.is_auth_required: from DockerApiServices.AllApiNeeds.middleware.auth_middleware import MiddlewareModule self.endpoint_function = MiddlewareModule.auth_required(self.endpoint_function) @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, "endpoint_function": ep.endpoint_function, "is_auth_required": ep.is_auth_required, "is_event_required": ep.is_event_required, "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 }