event to functon handler completed

This commit is contained in:
2025-01-15 19:18:11 +03:00
parent 25539c56cc
commit 76d286b519
55 changed files with 1271 additions and 1092 deletions

View File

@@ -10,14 +10,53 @@ This module initializes and configures the FastAPI application with:
"""
import uvicorn
import routers
from create_file import create_app
from fastapi import FastAPI
from create_routes import get_all_routers
from prometheus_fastapi_instrumentator import Instrumentator
from app_handler import setup_middleware, get_uvicorn_config
from create_file import setup_security_schema, configure_route_security
from fastapi.openapi.utils import get_openapi
app = create_app(routers=routers) # Initialize FastAPI application
def create_app() -> FastAPI:
"""Create and configure the FastAPI application."""
app = FastAPI()
# Get all routers and protected routes from the new configuration
routers, protected_routes = get_all_routers()
# Include all routers
for router in routers:
app.include_router(router)
# Configure OpenAPI schema with security
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="WAG Management API",
version="4.0.0",
description="WAG Management API Service",
routes=app.routes,
)
# Add security scheme
openapi_schema.update(setup_security_schema())
# Configure security for protected routes
for path, methods in protected_routes.items():
for method in methods:
configure_route_security(path, method, openapi_schema, list(protected_routes.keys()))
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
return app
app = create_app() # Initialize FastAPI application
Instrumentator().instrument(app=app).expose(app=app) # Setup Prometheus metrics
setup_middleware(app) # Configure middleware and exception handlers

View File

@@ -9,15 +9,14 @@ This module provides functionality to create and configure a FastAPI application
- Security requirements for protected endpoints
"""
from types import ModuleType
from typing import Any, Dict, List, Optional, Union
from typing import Any, Dict, List, Tuple
from fastapi import FastAPI, APIRouter
from fastapi.responses import JSONResponse, RedirectResponse
from fastapi.openapi.utils import get_openapi
from fastapi.routing import APIRoute
from AllConfigs.main import MainConfig as Config
from middleware.auth_middleware import MiddlewareModule
from AllConfigs.main import MainConfig as Config
from create_routes import get_all_routers
def setup_security_schema() -> Dict[str, Any]:
"""
@@ -27,15 +26,18 @@ def setup_security_schema() -> Dict[str, Any]:
Dict[str, Any]: Security schema configuration
"""
return {
"Bearer": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT",
"description": "Enter the token",
"components": {
"securitySchemes": {
"Bearer": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT",
"description": "Enter the token"
}
}
}
}
def configure_route_security(
path: str, method: str, schema: Dict[str, Any], protected_paths: List[str]
) -> None:
@@ -49,42 +51,13 @@ def configure_route_security(
protected_paths: List of paths that require authentication
"""
if path in protected_paths:
if "paths" not in schema:
schema["paths"] = {}
if "paths" in schema and path in schema["paths"]:
if method.lower() in schema["paths"][path]:
schema["paths"][path][method.lower()]["security"] = [{"Bearer": []}]
if path not in schema["paths"]:
schema["paths"][path] = {}
if method not in schema["paths"][path]:
schema["paths"][path][method] = {}
schema["paths"][path][method]["security"] = [{"Bearer": []}]
def get_routers(routers_module: ModuleType) -> List[APIRouter]:
def create_app() -> FastAPI:
"""
Extract all routers from the routers module.
Args:
routers_module: Module containing router definitions
Returns:
List[APIRouter]: List of router instances
"""
routers = []
for attr_name in dir(routers_module):
attr = getattr(routers_module, attr_name)
if isinstance(attr, APIRouter):
routers.append(attr)
return routers
def create_app(routers: ModuleType) -> FastAPI:
"""
Create and configure a FastAPI application.
Args:
routers: Module containing router definitions
Create and configure a FastAPI application with dynamic route creation.
Returns:
FastAPI: Configured FastAPI application instance
@@ -95,53 +68,39 @@ def create_app(routers: ModuleType) -> FastAPI:
description=Config.DESCRIPTION,
default_response_class=JSONResponse,
)
# Add home route that redirects to API documentation
@app.get("/", include_in_schema=False, summary=str(Config.DESCRIPTION))
async def home() -> RedirectResponse:
"""Redirect root path to API documentation."""
return RedirectResponse(url="/docs")
# Get all routers
router_instances = get_routers(routers)
# Find protected paths
protected_paths = []
for router in router_instances:
for route in router.routes:
if isinstance(route, APIRoute):
# Check if the route has auth_required decorator
if any(d.__name__ == "auth_required" for d in route.dependencies):
protected_paths.append(route.path)
# Include routers
for router in router_instances:
# Get all routers and protected routes using the dynamic route creation
routers, protected_routes = get_all_routers()
# Include all routers
for router in routers:
app.include_router(router)
# Configure custom OpenAPI schema
# Configure OpenAPI schema with security
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title=Config.TITLE,
version="1.0.0",
description=Config.DESCRIPTION,
title="WAG Management API",
version="4.0.0",
description="WAG Management API Service",
routes=app.routes,
)
# Add security schemes
openapi_schema["components"] = {"securitySchemes": setup_security_schema()}
# Add security scheme
security_schema = setup_security_schema()
openapi_schema.update(security_schema)
# Configure security for each route
for route in app.routes:
if isinstance(route, APIRoute):
configure_route_security(
route.path,
route.methods.pop().lower(),
openapi_schema,
protected_paths,
)
# Configure security for protected routes
for path, methods in protected_routes.items():
for method in methods:
configure_route_security(path, method, openapi_schema, list(protected_routes.keys()))
app.openapi_schema = openapi_schema
return app.openapi_schema

View File

@@ -0,0 +1,119 @@
"""
Route configuration and factory module.
Handles dynamic route creation based on configurations.
"""
from typing import Optional, Dict, Any, List, Callable, TypeVar, ParamSpec
P = ParamSpec('P') # For function parameters
R = TypeVar('R') # For return type
from dataclasses import dataclass
from functools import wraps
from fastapi import APIRouter, Request
from fastapi.routing import APIRoute
from middleware.auth_middleware import MiddlewareModule
from pydantic import BaseModel
from AllConfigs.main import MainConfig as Config
from ApiEvents.EventServiceApi.route_configs import get_route_configs
@dataclass
class EndpointFactoryConfig:
endpoint: str
method: str
summary: str
description: str
endpoint_function: Callable[P, R] # Now accepts any parameters and return type
response_model: Optional[type] = None
request_model: Optional[type] = None
is_auth_required: bool = True
is_event_required: bool = False
extra_options: Dict[str, Any] = None
def __post_init__(self):
if self.extra_options is None:
self.extra_options = {}
class EnhancedEndpointFactory:
def __init__(self, router_config: dict):
self.router = APIRouter(
prefix=router_config['prefix'],
tags=router_config['tags'],
include_in_schema=router_config.get('include_in_schema', True)
)
self.endpoints = router_config['endpoints']
self.protected_routes: Dict[str, List[str]] = {}
def create_endpoint(self, config: EndpointFactoryConfig):
"""
Create an endpoint directly from the configuration.
Args:
config: EndpointFactoryConfig instance containing endpoint configuration
"""
endpoint_path = config.endpoint
endpoint_function = config.endpoint_function
if config.is_auth_required:
endpoint_function = MiddlewareModule.auth_required(endpoint_function)
# Track protected routes
full_path = f"{self.router.prefix}{endpoint_path}"
if full_path not in self.protected_routes:
self.protected_routes[full_path] = []
self.protected_routes[full_path].append(config.method.lower())
# Register the endpoint with FastAPI router
getattr(self.router, config.method.lower())(
endpoint_path,
response_model=config.response_model,
summary=config.summary,
description=config.description,
**config.extra_options
)(endpoint_function)
def get_router(self) -> APIRouter:
"""Get the configured router."""
return self.router
def get_protected_routes(self) -> Dict[str, List[str]]:
"""Get the protected routes mapping."""
return self.protected_routes
async def health_check(request: Request):
"""Default health check endpoint."""
return {"status": "healthy", "message": "Service is running"}
async def ping_test(request: Request, service_name: str = "base-router"):
"""Default ping test endpoint."""
return {"ping": "pong", "service": service_name}
def get_all_routers() -> tuple[List[APIRouter], Dict[str, List[str]]]:
"""
Get all configured routers and their protected routes.
Returns:
tuple: (routers, protected_routes)
"""
routers = []
all_protected_routes = {}
# Get route configurations from the registry
route_configs = get_route_configs()
for config in route_configs:
factory = EnhancedEndpointFactory(config)
# Create endpoints from configuration
for endpoint_config in config['endpoints']:
factory.create_endpoint(endpoint_config)
# Add router and protected routes
routers.append(factory.get_router())
all_protected_routes.update(factory.get_protected_routes())
return routers, all_protected_routes

View File

@@ -113,6 +113,7 @@ class MiddlewareModule:
raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr")
except Exception as e:
raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr")
return wrapper

View File

@@ -1,3 +0,0 @@
from .base_router import test_route
__all__ = ["test_route"]

View File

@@ -1,22 +0,0 @@
"""
Base router configuration and setup.
"""
from fastapi import APIRouter, Request
from middleware.auth_middleware import MiddlewareModule
# Create test router
test_route = APIRouter(prefix="/test", tags=["Test"])
test_route.include_router(test_route, include_in_schema=True)
@test_route.get("/health")
@MiddlewareModule.auth_required
async def health_check(request: Request):
return {"status": "healthy", "message": "Service is running"}
@test_route.get("/ping")
async def ping_test():
return {"ping": "pong", "service": "base-router"}