File size: 2,531 Bytes
eacbbc9
 
 
 
 
 
 
 
 
 
 
 
e2dbb45
eacbbc9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e2dbb45
eacbbc9
 
b90a0f7
eacbbc9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e2dbb45
 
 
 
 
 
 
 
 
 
 
 
eacbbc9
 
e2dbb45
 
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
"""
Main FastAPI application entry point
"""
import os
import logging
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from contextlib import asynccontextmanager

from app.routers import vqa
from app.services.model_service import ModelService
from app.config import settings

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# Initialize model service in a lifespan context manager
@asynccontextmanager
async def lifespan(app: FastAPI):
    # Load model on startup
    logger.info("Loading VQA model...")
    app.state.model_service = ModelService()
    app.state.model_service.load_model()
    logger.info("VQA model loaded successfully")
    yield
    # Clean up resources on shutdown
    logger.info("Shutting down...")

# Initialize FastAPI app
app = FastAPI(
    title="VizWiz VQA API",
    description="API for Visual Question Answering on images",
    version="1.0.0",
    lifespan=lifespan
)

# Add CORS middleware with more permissive settings for Hugging Face Spaces
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://vizwiz.vercel.app/"],  # Allow all origins
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Mount static files directory if it exists
static_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), "static")
if os.path.exists(static_dir):
    app.mount("/static", StaticFiles(directory=static_dir), name="static")

# Include routers
app.include_router(vqa.router)

# Health check endpoint
@app.get("/health")
async def health_check():
    """Health check endpoint for monitoring the service"""
    if not hasattr(app.state, "model_service") or not app.state.model_service.is_model_loaded():
        raise HTTPException(status_code=503, detail="Model not loaded")
    return {"status": "healthy", "model_loaded": True}

# Root endpoint for Hugging Face Spaces
@app.get("/")
async def root():
    """Root endpoint returning basic info about the API"""
    return {
        "name": "VizWiz Visual Question Answering API",
        "description": "API for visual question answering on images",
        "documentation": "/docs",
        "health_check": "/health",
        "version": "1.0.0"
    }

if __name__ == "__main__":
    import uvicorn
    port = settings.PORT
    uvicorn.run("app.main:app", host="0.0.0.0", port=port, reload=False)