File size: 3,595 Bytes
c49b21b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, HTMLResponse
import uvicorn
import logging
import sys
from src.api.routes.health import health_status
from src.api.routes.isrunning import is_running

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(sys.stdout)
    ]
)

logger = logging.getLogger(__name__)

app = FastAPI(
    title="AdvisorAI Data API",
    description="API for AdvisorAI data pipeline and health monitoring",
    version="1.0.0"
)

# Add CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.exception_handler(Exception)
async def global_exception_handler(request, exc):
    logger.error(f"Global exception handler caught: {exc}", exc_info=True)
    return JSONResponse(
        status_code=500,
        content={"detail": "Internal server error", "error": str(exc)}
    )

@app.get('/health')
def health():
    """Enhanced health check endpoint"""
    try:
        return health_status()
    except Exception as e:
        logger.error(f"Health check failed: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Health check failed: {str(e)}")

# Route to check if there are any JSON files under data/merged/features (relative path)
@app.get('/status')
def status():
    """Check if the data pipeline is running and has recent data"""
    try:
        return is_running()
    except Exception as e:
        logger.error(f"Status check failed: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Status check failed: {str(e)}")

@app.get('/', response_class=HTMLResponse)
def root():
        """Root endpoint returns simple HTML so HF Spaces iframe can render it."""
        html = """
        <!doctype html>
        <html lang="en">
        <head>
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>AdvisorAI Data API</title>
            <style>
                body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; padding: 24px; }
                code { background: #f5f5f5; padding: 2px 4px; border-radius: 4px; }
                .links a { margin-right: 12px; }
            </style>
        </head>
        <body>
            <h1>AdvisorAI Data API</h1>
            <p>Service is running.</p>
            <div class="links">
                <a href="/health">/health</a>
                <a href="/status">/status</a>
                <a href="/api">/api (JSON)</a>
            </div>
        </body>
        </html>
        """
        return HTMLResponse(content=html, status_code=200)

@app.get('/api')
def api_root():
        """JSON root for programmatic clients."""
        return {
                "message": "AdvisorAI Data API",
                "version": "1.0.0",
                "endpoints": {
                        "/health": "Health check with system metrics",
                        "/status": "Data pipeline status",
                        "/api": "This JSON endpoint",
                        "/": "HTML landing page for Spaces"
                }
        }

if __name__ == "__main__":
    uvicorn.run(
        "src.api.main:app",
        host="0.0.0.0",
        port=10000,
        workers=1,
        timeout_keep_alive=30,
        access_log=True
    )