File size: 3,711 Bytes
832348e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
#!/usr/bin/env python3
"""
FRED ML - Main Application Entry Point
Production-grade FastAPI application for economic data analysis
"""
import logging
import os
from contextlib import asynccontextmanager
import uvicorn
from fastapi import Depends, FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from config.settings import FRED_API_KEY
from src.analysis.advanced_analytics import AdvancedAnalytics
from src.core.fred_client import FREDDataCollectorV2
# Configure logging
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
# Global variables for application state
collector = None
analytics = None
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Application lifespan manager"""
# Startup
global collector, analytics
logger.info("Starting FRED ML application...")
if not FRED_API_KEY:
logger.error("FRED_API_KEY not configured")
raise ValueError("FRED_API_KEY environment variable is required")
collector = FREDDataCollectorV2(api_key=FRED_API_KEY)
logger.info("FRED Data Collector initialized")
yield
# Shutdown
logger.info("Shutting down FRED ML application...")
# Create FastAPI application
app = FastAPI(
title="FRED ML API",
description="Economic Data Analysis API using Federal Reserve Economic Data",
version="1.0.0",
lifespan=lifespan,
)
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
async def root():
"""Root endpoint"""
return {"message": "FRED ML API", "version": "1.0.0", "status": "running"}
@app.get("/health")
async def health_check():
"""Health check endpoint"""
return {"status": "healthy"}
@app.get("/ready")
async def readiness_check():
"""Readiness check endpoint"""
if collector is None:
raise HTTPException(status_code=503, detail="Service not ready")
return {"status": "ready"}
@app.get("/api/v1/indicators")
async def get_indicators():
"""Get available economic indicators"""
if collector is None:
raise HTTPException(status_code=503, detail="Service not ready")
return {
"indicators": list(collector.indicators.keys()),
"descriptions": collector.indicators,
}
@app.post("/api/v1/analyze")
async def analyze_data(
series_ids: list[str], start_date: str = None, end_date: str = None
):
"""Analyze economic data for specified series"""
if collector is None:
raise HTTPException(status_code=503, detail="Service not ready")
try:
df, summary = collector.run_analysis(
series_ids=series_ids, start_date=start_date, end_date=end_date
)
return {
"status": "success",
"data_shape": df.shape if df is not None else None,
"summary": summary.to_dict() if summary is not None else None,
}
except Exception as e:
logger.error(f"Analysis failed: {e}")
raise HTTPException(status_code=500, detail=str(e))
@app.get("/api/v1/status")
async def get_status():
"""Get application status"""
return {
"api_key_configured": bool(FRED_API_KEY),
"collector_initialized": collector is not None,
"environment": os.getenv("ENVIRONMENT", "development"),
}
if __name__ == "__main__":
port = int(os.getenv("PORT", 8000))
uvicorn.run(
"src.main:app",
host="0.0.0.0",
port=port,
reload=os.getenv("ENVIRONMENT") == "development",
)
|