wag-managment-api-service-v.../ApiEvents/abstract_class.py

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
}