PSA / app /main.py
Hammad712's picture
Initial clean deployment: removed binary bloat
7e431a1
import time
from datetime import datetime
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from app.routers import execution
from app.core.config import get_config # Assuming your config loader is here
# 1. LIFESPAN MANAGER (The "Warm-Up" Phase)
# Replaces the deprecated @app.on_event("startup")
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Execute setup logic before the API starts accepting requests.
"""
config = get_config()
print(f"πŸš€ [Startup] RiverGen AI Engine ({config.MODEL_NAME}) is warming up...")
# Optional: Pre-initialize heavy objects here (Database pools, LLM clients)
# from app.core.config import get_groq_client
# get_groq_client()
yield # API is running now
print("πŸ›‘ [Shutdown] Cleaning up resources...")
# 2. INITIALIZE APP
app = FastAPI(
title="RiverGen AI Engine API",
description="Enterprise orchestration API for executing queries across SQL, NoSQL, and Streaming sources.",
version="1.0.0",
lifespan=lifespan, # Attach startup logic
docs_url="/docs",
redoc_url="/redoc"
)
# 3. MIDDLEWARE (Security & Tracing)
# A. CORS (Allow Frontend Access)
origins = [
"http://localhost:3000", # React Localhost
"https://app.rivergen.ai", # Production Frontend
"https://staging.rivergen.ai" # Staging
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins, # Restrict this in Prod! Don't use ["*"]
allow_credentials=True,
allow_methods=["GET", "POST", "OPTIONS"],
allow_headers=["*"],
)
# B. Request ID & Timing Middleware
# Adds X-Process-Time header and ensures logs can be traced
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
# 4. ROUTERS
app.include_router(execution.router, prefix="/api/v1")
# 5. ENDPOINTS
@app.get("/health", tags=["Monitoring"])
def health_check():
"""
Dynamic health check for load balancers.
"""
return {
"status": "healthy",
"timestamp": datetime.now().isoformat(), # βœ… FIXED: Dynamic time
"engine": "RiverGen-v1",
"uptime_check": True
}
@app.get("/", tags=["General"])
def read_root():
return {
"message": "RiverGen AI Engine is running.",
"docs": "/docs",
"health": "/health"
}
if __name__ == "__main__":
import uvicorn
# In production, you usually run this via: uvicorn main:app --workers 4
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)