Spaces:
Sleeping
Sleeping
| """ | |
| Building Detection API β FastAPI Backend for Hugging Face Spaces. | |
| Endpoints: | |
| GET / β Health check + model info | |
| GET /health β Health check | |
| POST /detect β Detect buildings in a polygon area | |
| """ | |
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from pydantic import BaseModel, Field | |
| from typing import List, Optional | |
| import uvicorn | |
| from model_manager import load_model, get_model_info | |
| from inference import detect_buildings | |
| # ========================================== | |
| # === App Setup === | |
| # ========================================== | |
| app = FastAPI( | |
| title="ποΈ Building Detection API", | |
| description="Detect buildings from satellite imagery using Mask R-CNN V5", | |
| version="1.0.0", | |
| ) | |
| # Allow CORS for Vercel frontend | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], # In production, restrict to your Vercel domain | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # ========================================== | |
| # === Request / Response Models === | |
| # ========================================== | |
| class DetectRequest(BaseModel): | |
| coordinates: List[List[float]] = Field( | |
| ..., | |
| description="Polygon coordinates as [[lng, lat], ...] in GeoJSON format", | |
| example=[[31.24, 30.04], [31.25, 30.04], [31.25, 30.05], [31.24, 30.05]], | |
| ) | |
| threshold: Optional[float] = Field( | |
| default=0.5, | |
| ge=0.1, | |
| le=0.95, | |
| description="Detection confidence threshold", | |
| ) | |
| use_v51: Optional[bool] = Field( | |
| default=True, | |
| description="Enable V5.1 pipeline (MobileSAM + SigLIP) for better accuracy", | |
| ) | |
| class DetectResponse(BaseModel): | |
| geojson: dict | |
| stats: dict | |
| class HealthResponse(BaseModel): | |
| status: str | |
| model: dict | |
| # ========================================== | |
| # === Startup Event === | |
| # ========================================== | |
| async def startup(): | |
| """Load model when the server starts.""" | |
| print("π Starting Building Detection API...") | |
| load_model() | |
| print("β API ready!") | |
| # ========================================== | |
| # === Endpoints === | |
| # ========================================== | |
| async def root(): | |
| """Health check and model info.""" | |
| return { | |
| "status": "π’ online", | |
| "model": get_model_info(), | |
| } | |
| async def health(): | |
| """Health check endpoint.""" | |
| return { | |
| "status": "π’ online", | |
| "model": get_model_info(), | |
| } | |
| async def detect(request: DetectRequest): | |
| """ | |
| Detect buildings in the specified polygon area. | |
| Send polygon coordinates in GeoJSON format [[lng, lat], ...]. | |
| Returns a GeoJSON FeatureCollection with detected building polygons. | |
| """ | |
| try: | |
| result = detect_buildings( | |
| coordinates=request.coordinates, | |
| threshold=request.threshold, | |
| use_v51=request.use_v51, | |
| ) | |
| if "error" in result: | |
| raise HTTPException(status_code=400, detail=result["error"]) | |
| return result | |
| except HTTPException: | |
| raise | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"Processing error: {str(e)}") | |
| # ========================================== | |
| # === Run === | |
| # ========================================== | |
| if __name__ == "__main__": | |
| uvicorn.run(app, host="0.0.0.0", port=7860) | |