File size: 2,247 Bytes
54d3696
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import torch
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from src.api.model_manager import ModelManager
from src.api.router import router


# global instances — shared across all requests
model_manager: ModelManager = None
device: torch.device = None


@asynccontextmanager
async def lifespan(app: FastAPI):
    """
    Lifespan context manager — runs startup and shutdown logic.
    Replaces the deprecated @app.on_event("startup") pattern.

    Startup: load models into memory before serving any requests.
    Shutdown: clean up resources.
    """
    global model_manager, device

    # --- startup ---
    print("Starting CV Multitask Pipeline API...")
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    print(f"Device: {device}")

    model_manager = ModelManager()
    available = model_manager.get_available_versions()
    print(f"Available model versions: {available}")

    # load all available versions on startup
    for version in available:
        success = model_manager.load_version(version)
        if success:
            print(f"Loaded model {version} successfully")
        else:
            print(f"Failed to load model {version}")

    print("API ready to serve requests.")
    yield

    # --- shutdown ---
    print("Shutting down API...")
    for version in model_manager.get_loaded_versions():
        model_manager.unload_version(version)
    print("Shutdown complete.")


app = FastAPI(
    title="CV Multitask Pipeline",
    description=(
        "Multi-task computer vision API — simultaneous object "
        "classification and detection using EfficientNet-B0 backbone "
        "with custom task heads."
    ),
    version="1.0.0",
    lifespan=lifespan,
)

# CORS — allows the Gradio UI and other frontends to call this API
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# register all routes
app.include_router(router)


@app.get("/")
async def root():
    return {
        "name": "CV Multitask Pipeline API",
        "version": "1.0.0",
        "docs": "/docs",
        "health": "/health",
    }