| """
|
| Custom middleware for the application
|
| """
|
| from fastapi import Request
|
| from starlette.middleware.base import BaseHTTPMiddleware
|
| from starlette.responses import Response
|
| import logging
|
| import time
|
| from typing import Callable
|
|
|
| logger = logging.getLogger(__name__)
|
|
|
| class RequestLoggerMiddleware(BaseHTTPMiddleware):
|
| """Middleware for logging requests"""
|
|
|
| async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
| start_time = time.time()
|
|
|
|
|
| method = request.method
|
| url = str(request.url)
|
|
|
| try:
|
|
|
| response = await call_next(request)
|
|
|
|
|
| process_time = time.time() - start_time
|
|
|
|
|
| logger.info(
|
| f"Request: {method} {url} - Status: {response.status_code} - "
|
| f"Processing Time: {process_time:.3f}s"
|
| )
|
|
|
| return response
|
|
|
| except Exception as e:
|
| logger.error(
|
| f"Request failed: {method} {url} - Error: {str(e)}"
|
| )
|
| raise
|
|
|
| class ErrorHandlerMiddleware(BaseHTTPMiddleware):
|
| """Middleware for handling errors"""
|
|
|
| async def dispatch(self, request: Request, call_next: Callable) -> Response:
|
| try:
|
| return await call_next(request)
|
| except Exception as e:
|
|
|
| logger.error(f"Unhandled error: {str(e)}", exc_info=True)
|
|
|
|
|
| return Response(
|
| content={"detail": "Internal server error"},
|
| status_code=500
|
| )
|
|
|