finagent / app /main.py
omgy's picture
Update app/main.py
48194e0 verified
"""
Main FastAPI application for FinAgent backend.
Chat2Sanction - AI-powered loan processing platform.
"""
import os
from contextlib import asynccontextmanager
from app.config import settings
from app.routers import admin, auth, chat, loan
from app.utils.logger import setup_logger
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
# Setup logger
logger = setup_logger("finagent", log_file="finagent.log")
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Lifespan context manager for startup and shutdown events.
"""
# Startup
logger.info("=" * 80)
logger.info(f"Starting {settings.APP_NAME} v{settings.APP_VERSION}")
logger.info("=" * 80)
logger.info(f"Environment: {'Development' if settings.DEBUG else 'Production'}")
logger.info(f"Firebase Project: {settings.FIREBASE_PROJECT_ID}")
logger.info(f"LLM Model: {getattr(settings, 'GEMINI_MODEL', 'Not configured')}")
# Initialize services
try:
from app.agents.master_agent import master_agent
from app.services.firebase_service import firebase_service
from app.services.pdf_service import pdf_service
from app.services.session_service import session_service
from app.services.underwriting_service import underwriting_service
logger.info("All services initialized successfully")
except Exception as e:
logger.error(f"Failed to initialize services: {str(e)}")
# Create output directories
os.makedirs(settings.PDF_OUTPUT_DIR, exist_ok=True)
logger.info(f"PDF output directory: {settings.PDF_OUTPUT_DIR}")
logger.info("✓ Application startup complete")
logger.info("=" * 80)
yield
# Shutdown
logger.info("=" * 80)
logger.info("Shutting down application")
logger.info("=" * 80)
# Create FastAPI app
app = FastAPI(
title=settings.APP_NAME,
description="AI-powered loan processing platform with conversational interface",
version=settings.APP_VERSION,
lifespan=lifespan,
docs_url="/api/docs",
redoc_url="/api/redoc",
openapi_url="/api/openapi.json",
)
# Configure CORS
app.add_middleware(
CORSMiddleware,
allow_origins=settings.ALLOWED_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Health check endpoint
@app.get("/")
async def root():
"""Root endpoint with API information."""
return {
"name": settings.APP_NAME,
"version": settings.APP_VERSION,
"status": "running",
"docs": "/api/docs",
}
@app.get("/health")
async def health_check():
"""Health check endpoint."""
from app.services.firebase_service import firebase_service
return {
"status": "healthy",
"firebase": "connected" if firebase_service.initialized else "disconnected",
"gemini": "configured" if settings.GOOGLE_API_KEY else "not configured",
}
# Include routers
app.include_router(auth.router, prefix="/api/auth", tags=["Authentication"])
app.include_router(chat.router, prefix="/api/chat", tags=["Chat"])
app.include_router(loan.router, prefix="/api/loan", tags=["Loans"])
app.include_router(admin.router, prefix="/api/admin", tags=["Admin"])
# Global exception handler
@app.exception_handler(Exception)
async def global_exception_handler(request, exc):
"""Global exception handler for unhandled errors."""
logger.error(f"Unhandled exception: {str(exc)}", exc_info=True)
return JSONResponse(
status_code=500,
content={
"error": "Internal server error",
"detail": str(exc) if settings.DEBUG else "An unexpected error occurred",
},
)
# Request logging middleware
@app.middleware("http")
async def log_requests(request, call_next):
"""Log all HTTP requests."""
from time import time
start_time = time()
# Process request
response = await call_next(request)
# Log request
duration = (time() - start_time) * 1000 # Convert to milliseconds
logger.info(
f"{request.method} {request.url.path} - {response.status_code} ({duration:.2f}ms)"
)
return response
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"app.main:app",
host=settings.HOST,
port=settings.PORT,
reload=settings.DEBUG,
workers=settings.WORKERS,
)