f5_model_final / app /main.py
EL GHAFRAOUI AYOUB
C
4099797
raw
history blame
3.07 kB
from fastapi import FastAPI, Request, HTTPException
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from .routes import invoices
from app.db.database import init_db, rate_limiter
import os
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
from dotenv import load_dotenv
import logging
from typing import Callable
import time
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Load environment variables
load_dotenv()
# Get the absolute path to the app directory
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
class RateLimitMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next: Callable):
# Get client IP
client_ip = request.client.host
# Check rate limit
if not rate_limiter.is_allowed(client_ip):
logger.warning(f"Rate limit exceeded for IP: {client_ip}")
raise HTTPException(
status_code=429,
detail="Too many requests. Please try again later."
)
# Process request
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
# Log request details
logger.info(
f"Request: {request.method} {request.url.path} "
f"Client: {client_ip} "
f"Process time: {process_time:.2f}s"
)
return response
app = FastAPI(
title="Invoice Generator",
description="API for generating invoices",
version="1.0.0"
)
# Add rate limiting middleware
app.add_middleware(RateLimitMiddleware)
# Configure CORS with more specific settings
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # In production, replace with specific domains
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
max_age=3600, # Cache preflight requests for 1 hour
)
# Mount static files with absolute path
app.mount("/static", StaticFiles(directory=os.path.join(BASE_DIR, "app/static")), name="static")
# Templates with absolute path
templates = Jinja2Templates(directory=os.path.join(BASE_DIR, "app/templates"))
# Include routers
app.include_router(invoices.router)
@app.on_event("startup")
async def startup_event():
logger.info("Starting application...")
await init_db()
logger.info("Application started successfully")
@app.on_event("shutdown")
async def shutdown_event():
logger.info("Shutting down application...")
# Root endpoint to serve the HTML page
@app.get("/")
async def root(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
# Health check endpoint
@app.get("/health")
async def health_check():
return {"status": "healthy", "timestamp": time.time()}
@app.get("/history")
async def history_page(request: Request):
return templates.TemplateResponse("history.html", {"request": request})