error response due to language models are updated

This commit is contained in:
2025-01-15 13:39:17 +03:00
parent ad0b9aa218
commit 25539c56cc
17 changed files with 163 additions and 208 deletions

View File

@@ -17,21 +17,11 @@ from prometheus_fastapi_instrumentator import Instrumentator
from app_handler import setup_middleware, get_uvicorn_config
print("Loading app.py module...")
# Initialize FastAPI application
app = create_app(routers=routers)
# Setup Prometheus metrics
Instrumentator().instrument(app=app).expose(app=app)
# Configure middleware and exception handlers
setup_middleware(app)
app = create_app(routers=routers) # Initialize FastAPI application
Instrumentator().instrument(app=app).expose(app=app) # Setup Prometheus metrics
setup_middleware(app) # Configure middleware and exception handlers
if __name__ == "__main__":
print("Starting server from __main__...")
# Run the application with Uvicorn
uvicorn_config = get_uvicorn_config()
print(f"Using config: {uvicorn_config}")
uvicorn_config = get_uvicorn_config() # Run the application with Uvicorn
uvicorn.Server(uvicorn.Config(**uvicorn_config)).run()

View File

@@ -12,14 +12,8 @@ from typing import Dict, Any
from fastapi.middleware.cors import CORSMiddleware
from fastapi import FastAPI, Request, HTTPException, status
from fastapi.responses import JSONResponse
from ErrorHandlers.bases import (
BaseErrorModelClass,
StatusesModelClass,
LanguageModelClass,
)
from ErrorHandlers import statuses
from middleware.auth_middleware import MiddlewareModule
from ErrorHandlers.Exceptions.api_exc import HTTPExceptionApi
from middleware.auth_middleware import RequestTimingMiddleware
def setup_cors_middleware(app: FastAPI) -> None:
@@ -38,33 +32,6 @@ def setup_cors_middleware(app: FastAPI) -> None:
)
async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
"""
Handle HTTP exceptions and return formatted error responses.
Args:
request: FastAPI request object
exc: HTTP exception instance
Returns:
JSONResponse: Formatted error response
"""
error_code = getattr(exc, "error_code", None)
if error_code:
status_code = StatusesModelClass.retrieve_error_by_code(error_code)
error_message = LanguageModelClass.retrieve_error_by_code(
error_code, request.headers.get("accept-language", "en")
)
else:
status_code = exc.status_code
error_message = str(exc.detail)
return JSONResponse(
status_code=status_code,
content={"detail": error_message, "error_code": error_code},
)
async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
"""
Handle generic exceptions and return formatted error responses.
@@ -89,7 +56,12 @@ def setup_exception_handlers(app: FastAPI) -> None:
Args:
app: FastAPI application instance
"""
app.add_exception_handler(HTTPException, http_exception_handler)
from ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApiHandler
custom_exception_handler = HTTPExceptionApiHandler(response_model=JSONResponse)
app.add_exception_handler(
HTTPExceptionApi, custom_exception_handler.handle_exception
)
app.add_exception_handler(Exception, generic_exception_handler)
@@ -101,7 +73,7 @@ def setup_middleware(app: FastAPI) -> None:
app: FastAPI application instance
"""
setup_cors_middleware(app)
app.add_middleware(MiddlewareModule.RequestTimingMiddleware)
app.add_middleware(RequestTimingMiddleware)
setup_exception_handlers(app)
@@ -118,4 +90,4 @@ def get_uvicorn_config() -> Dict[str, Any]:
"port": 41575,
"log_level": "info",
"reload": True,
}
}

View File

@@ -8,6 +8,7 @@ This module provides functionality to create and configure a FastAPI application
- Response class configuration
- Security requirements for protected endpoints
"""
from types import ModuleType
from typing import Any, Dict, List, Optional, Union
from fastapi import FastAPI, APIRouter
@@ -36,10 +37,7 @@ def setup_security_schema() -> Dict[str, Any]:
def configure_route_security(
path: str,
method: str,
schema: Dict[str, Any],
protected_paths: List[str]
path: str, method: str, schema: Dict[str, Any], protected_paths: List[str]
) -> None:
"""
Configure security requirements for a specific route.
@@ -113,7 +111,7 @@ def create_app(routers: ModuleType) -> FastAPI:
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):
if any(d.__name__ == "auth_required" for d in route.dependencies):
protected_paths.append(route.path)
# Include routers
@@ -142,7 +140,7 @@ def create_app(routers: ModuleType) -> FastAPI:
route.path,
route.methods.pop().lower(),
openapi_schema,
protected_paths
protected_paths,
)
app.openapi_schema = openapi_schema

View File

@@ -8,7 +8,7 @@ and a middleware for request timing measurements.
from time import perf_counter
from typing import Callable, Optional, Dict, Any, Tuple
from functools import wraps
from fastapi import HTTPException, Request, Response, status
from fastapi import Request, Response
from starlette.middleware.base import BaseHTTPMiddleware
from AllConfigs.Token.config import Auth
from ErrorHandlers.ErrorHandlers.api_exc_handler import HTTPExceptionApi
@@ -21,7 +21,6 @@ class MiddlewareModule:
This class provides:
- Token extraction and validation
- Authentication decorator for endpoints
- Request timing middleware
"""
@staticmethod
@@ -40,23 +39,15 @@ class MiddlewareModule:
"""
auth_header = request.headers.get(Auth.ACCESS_TOKEN_TAG)
if not auth_header:
raise HTTPExceptionApi(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="No authorization header",
)
raise HTTPExceptionApi(error_code="HTTP_401_UNAUTHORIZED", lang="tr")
try:
scheme, token = auth_header.split()
if scheme.lower() != "bearer":
raise HTTPExceptionApi(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication scheme",
)
raise HTTPExceptionApi(error_code="HTTP_401_UNAUTHORIZED", lang="tr")
return scheme, token
except ValueError:
raise HTTPExceptionApi(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token format"
)
raise HTTPExceptionApi(error_code="HTTP_401_UNAUTHORIZED", lang="tr")
@staticmethod
async def validate_token(token: str) -> Dict[str, Any]:
@@ -78,10 +69,7 @@ class MiddlewareModule:
# return jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
return {"user_id": "test", "role": "user"} # Placeholder
except Exception as e:
raise HTTPExceptionApi(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=f"Token validation failed: {str(e)}",
)
raise HTTPExceptionApi(error_code="HTTP_401_UNAUTHORIZED", lang="tr")
@classmethod
def auth_required(cls, func: Callable) -> Callable:
@@ -122,58 +110,44 @@ class MiddlewareModule:
return await func(request, *args, **kwargs)
except HTTPExceptionApi:
raise
raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr")
except Exception as e:
raise HTTPExceptionApi(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=f"Authentication failed: {str(e)}",
)
raise HTTPExceptionApi(error_code="NOT_AUTHORIZED", lang="tr")
return wrapper
class RequestTimingMiddleware(BaseHTTPMiddleware):
class RequestTimingMiddleware(BaseHTTPMiddleware):
"""
Middleware for measuring and logging request timing.
Only handles timing, no authentication.
"""
async def dispatch(self, request: Request, call_next: Callable) -> Response:
"""
Middleware for measuring and logging request timing.
Only handles timing, no authentication.
Process each request through the middleware.
Args:
request: FastAPI request object
call_next: Next middleware in the chain
Returns:
Response: Processed response with timing headers
"""
start_time = perf_counter()
async def dispatch(self, request: Request, call_next: Callable) -> Response:
"""
Process each request through the middleware.
# Process the request
response = await call_next(request)
Args:
request: FastAPI request object
call_next: Next middleware in the chain
# Add timing information to response headers
end_time = perf_counter()
elapsed = (end_time - start_time) * 1000 # Convert to milliseconds
Returns:
Response: Processed response with timing headers
"""
start_time = perf_counter()
response.headers.update(
{
"request-start": f"{start_time:.6f}",
"request-end": f"{end_time:.6f}",
"request-duration": f"{elapsed:.2f}ms",
}
)
# Process the request
response = await call_next(request)
# Add timing information to response headers
self._add_timing_headers(response, start_time)
return response
@staticmethod
def _add_timing_headers(response: Response, start_time: float) -> None:
"""
Add request timing information to response headers.
Args:
response: FastAPI response object
start_time: Time when request processing started
"""
end_time = perf_counter()
elapsed = (end_time - start_time) * 1000 # Convert to milliseconds
response.headers.update(
{
"request-start": f"{start_time:.6f}",
"request-end": f"{end_time:.6f}",
"request-duration": f"{elapsed:.2f}ms",
}
)
return response

View File

@@ -173,15 +173,17 @@ class OpenAPISchemaCreator:
# Add security schemes
if "components" not in openapi_schema:
openapi_schema["components"] = {}
openapi_schema["components"]["securitySchemes"] = self._create_security_schemes()
openapi_schema["components"][
"securitySchemes"
] = self._create_security_schemes()
# Configure route security and responses
for route in self.app.routes:
if isinstance(route, APIRoute) and route.include_in_schema:
path = str(route.path)
methods = [method.lower() for method in route.methods]
for method in methods:
self.configure_route_security(path, method, openapi_schema)
@@ -206,4 +208,4 @@ def create_openapi_schema(app: FastAPI) -> Dict[str, Any]:
Dict[str, Any]: Complete OpenAPI schema
"""
creator = OpenAPISchemaCreator(app)
return creator.create_schema()
return creator.create_schema()

View File

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

View File

@@ -7,16 +7,16 @@ 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"}
# Initialize and include test routes
def init_test_routes():
return test_route