QuantScaleAI / api /app.py
AJAY KASU
Refactor: Replace regex sector exclusion with LLM-based Intent Parser
2750cce
from fastapi import FastAPI, HTTPException, Depends
from core.schema import OptimizationRequest, OptimizationResult
from main import QuantScaleSystem
import logging
app = FastAPI(title="QuantScale AI API", version="1.0.0")
logger = logging.getLogger("API")
# Singleton System
system = QuantScaleSystem()
from fastapi.responses import RedirectResponse
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
# Mount static files
app.mount("/static", StaticFiles(directory="api/static"), name="static")
@app.get("/")
def root():
"""Serves the AI Interface."""
return FileResponse('api/static/index.html')
@app.get("/health")
def health_check():
return {"status": "healthy", "service": "QuantScale AI Direct Indexing"}
def parse_constraints_with_llm(user_prompt: str) -> list:
"""
Dedicated parser function in the API layer.
Maps natural language to exact GICS sectors.
"""
return system.ai_reporter.parse_intent(user_prompt)
@app.post("/optimize", response_model=dict)
def optimize_portfolio(request: OptimizationRequest):
"""
Optimizes a portfolio based on exclusions and generates an AI Attribution report.
"""
try:
# If the request contains a raw prompt but no sectors, parse it here
if request.user_prompt and not request.excluded_sectors:
request.excluded_sectors = parse_constraints_with_llm(request.user_prompt)
result = system.run_pipeline(request)
if not result:
raise HTTPException(status_code=500, detail="Pipeline failed to execute.")
return {
"client_id": request.client_id,
"allocations": result['optimization'].weights,
"tracking_error": result['optimization'].tracking_error,
"attribution_narrative": result['commentary']
}
except Exception as e:
logger.error(f"API Error: {e}")
raise HTTPException(status_code=500, detail=str(e))