File size: 1,906 Bytes
86f402d | 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 | """
SkinProAI FastAPI Backend
"""
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from pathlib import Path
import sys
# Add project root to path for model imports
sys.path.insert(0, str(Path(__file__).parent.parent))
from backend.routes import patients, lesions, analysis, chat
app = FastAPI(title="SkinProAI API", version="1.0.0")
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# API routes — analysis must be registered BEFORE patients so the literal
# /gradcam route is not shadowed by the parameterised /{patient_id} route.
app.include_router(analysis.router, prefix="/api/patients", tags=["analysis"])
app.include_router(chat.router, prefix="/api/patients", tags=["chat"])
app.include_router(patients.router, prefix="/api/patients", tags=["patients"])
app.include_router(lesions.router, prefix="/api/patients", tags=["lesions"])
# Ensure upload directories exist
UPLOADS_DIR = Path(__file__).parent.parent / "data" / "uploads"
UPLOADS_DIR.mkdir(parents=True, exist_ok=True)
# Serve uploaded images
if UPLOADS_DIR.exists():
app.mount("/uploads", StaticFiles(directory=str(UPLOADS_DIR)), name="uploads")
# Serve React build (production)
BUILD_DIR = Path(__file__).parent.parent / "web" / "dist"
if BUILD_DIR.exists():
app.mount("/", StaticFiles(directory=str(BUILD_DIR), html=True), name="static")
@app.on_event("shutdown")
async def shutdown_event():
from backend.services.analysis_service import get_analysis_service
svc = get_analysis_service()
if svc.agent.mcp_client:
svc.agent.mcp_client.stop()
@app.get("/api/health")
def health_check():
return {"status": "ok"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
|