feat: initial commit

This commit is contained in:
2025-05-09 19:15:53 +05:30
commit 80c61dc127
54 changed files with 2195 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
from fastapi import Request, status
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.exceptions import HTTPException as StarletteHTTPException
import traceback
from exceptions import (
ApiException,
BusinessValidationException,
ValidationException
)
from schemas.ApiResponse import ApiResponse
class ErrorHandlerMiddleware(BaseHTTPMiddleware):
"""Middleware for handling exceptions globally in the application."""
async def dispatch(self, request: Request, call_next):
try:
return await call_next(request)
except Exception as exc:
return self.handle_exception(exc)
def handle_exception(self, exc: Exception) -> JSONResponse:
if isinstance(exc, ApiException):
return JSONResponse(
status_code=exc.status_code,
content=ApiResponse.from_api_exception(exc)
)
elif isinstance(exc, StarletteHTTPException):
return JSONResponse(
status_code=exc.status_code,
content=ApiResponse(
message=str(exc.detail),
error=str(traceback.format_exc())
).model_dump(exclude_none=True)
)
elif isinstance(exc, (ValidationException, BusinessValidationException)):
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content=ApiResponse(
message=str(exc),
error=str(traceback.format_exc())
).model_dump(exclude_none=True)
)
elif isinstance(exc, RequestValidationError):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=ApiResponse(
message="Validation error",
error=str(exc.errors())
).model_dump(exclude_none=True)
)
else:
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=ApiResponse(
message=str(exc),
error=str(traceback.format_exc())
).model_dump(exclude_none=True)
)
# Exception handlers for FastAPI
def configure_exception_handlers(app):
"""Configure exception handlers for the FastAPI application."""
@app.exception_handler(ApiException)
async def api_exception_handler(request: Request, exc: ApiException):
return JSONResponse(
status_code=exc.status_code,
content=ApiResponse.from_api_exception(exc)
)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content=ApiResponse(
message="Validation error",
error=str(exc.errors())
).model_dump(exclude_none=True)
)
@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request: Request, exc: StarletteHTTPException):
return JSONResponse(
status_code=exc.status_code,
content=ApiResponse(
message=str(exc.detail),
error=str(traceback.format_exc())
).model_dump(exclude_none=True)
)
@app.exception_handler(BusinessValidationException)
async def business_validation_exception_handler(request: Request, exc: BusinessValidationException):
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content=ApiResponse(
message=str(exc),
error=str(traceback.format_exc())
).model_dump(exclude_none=True)
)
@app.exception_handler(ValidationException)
async def custom_validation_exception_handler(request: Request, exc: ValidationException):
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content=ApiResponse(
message=str(exc),
error=str(traceback.format_exc())
).model_dump(exclude_none=True)
)
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content=ApiResponse(
message=str(exc),
error=str(traceback.format_exc())
).model_dump(exclude_none=True)
)
View File
+27
View File
@@ -0,0 +1,27 @@
from fastapi import HTTPException, Depends
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from services.jwtService import verify_jwt_token
from services.userServices import UserServices
from fastapi import Request
security = HTTPBearer()
async def auth_required(request: Request ,credentials: HTTPAuthorizationCredentials = Depends(security)):
"""
Dependency function to verify JWT token for protected routes
"""
if credentials.scheme != "Bearer":
raise HTTPException(status_code=401, detail="Invalid authentication scheme")
payload = verify_jwt_token(credentials.credentials)
if payload is None:
raise HTTPException(status_code=401, detail="Invalid authentication token")
# Get user from database
user = UserServices().get_user(payload["user_id"])
# set user to request state
request.state.user = user
request.state.payload = payload
return True