programmingwithabdullah/todo-aipowered
0
1from contextlib import asynccontextmanager2from fastapi import FastAPI3from fastapi.middleware.cors import CORSMiddleware4from fastapi.middleware.trustedhost import TrustedHostMiddleware5from starlette.middleware.base import BaseHTTPMiddleware6from starlette.responses import Response7from settings import settings8from routes import tasks, auth, oauth, users, conversation9from database import engine10from sqlmodel import SQLModel11import time12from fastapi.exceptions import RequestValidationError13from fastapi.requests import Request14from fastapi.responses import JSONResponse15 16 17class SecurityHeadersMiddleware(BaseHTTPMiddleware):18 async def dispatch(self, request, call_next):19 response = await call_next(request)20 # Add security headers21 response.headers["X-Content-Type-Options"] = "nosniff"22 response.headers["X-Frame-Options"] = "DENY"23 response.headers["X-XSS-Protection"] = "1; mode=block"24 response.headers["Strict-Transport-Security"] = (25 "max-age=31536000; includeSubDomains"26 )27 return response28 29 30def create_app() -> FastAPI:31 """Create and configure the FastAPI application."""32 app = FastAPI(title=settings.app_name, debug=settings.debug, version="1.0.0")33 34 # Add security headers middleware35 app.add_middleware(SecurityHeadersMiddleware)36 37 # Configure CORS38 app.add_middleware(39 CORSMiddleware,40 allow_origins=[41 settings.frontend_url42 ], # Restrict to your frontend's domain in production43 allow_credentials=True,44 allow_methods=["*"],45 allow_headers=["*"],46 )47 48 # Include API routes49 app.include_router(tasks.router, prefix=settings.api_prefix, tags=["tasks"])50 app.include_router(auth.router, prefix=settings.api_prefix, tags=["auth"])51 app.include_router(oauth.router, prefix=settings.api_prefix, tags=["oauth"])52 app.include_router(users.router, prefix=settings.api_prefix, tags=["users"])53 app.include_router(conversation.router, prefix=settings.api_prefix, tags=["chat"])54 55 return app56 57 58# Create the main application instance59app = create_app()60 61 62@app.on_event("startup")63async def on_startup():64 """Create database tables on startup."""65 SQLModel.metadata.create_all(bind=engine)66 67 68@app.exception_handler(RequestValidationError)69async def validation_exception_handler(request: Request, exc: RequestValidationError):70 print(f"Validation error: {exc.errors()}")71 print(f"Request body: {await request.body()}")72 return JSONResponse(73 status_code=422,74 content={"detail": exc.errors(), "body": str(exc.body)},75 )76 77 78if __name__ == "__main__":79 import uvicorn80 81 uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)82 