MohdUmar0223 commited on
Commit
4faa043
·
verified ·
1 Parent(s): c817825

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -70
app.py CHANGED
@@ -230,82 +230,79 @@ with gr.Blocks(title="AQI Intelligence Engine — HF ZeroGPU Edition", theme=gr.
230
  """
231
  )
232
 
 
 
233
  from starlette.responses import JSONResponse
234
  from starlette.requests import Request
235
 
236
- # Initialize the Gradio queue — this creates the underlying FastAPI app object
237
- # MUST be called before registering REST routes on demo.app
238
- demo.queue()
239
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
- def register_api_routes(gradio_app):
242
- """Register custom REST API endpoints on the Gradio FastAPI app."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
- @gradio_app.post("/api/v1/forecast")
245
- async def api_forecast(request: Request):
246
- """REST API endpoint for historical AQI prediction."""
247
- try:
248
- payload = await request.json()
249
- from services.forecast.service import forecast_aqi
250
- aqi_hist = payload.get("aqi_history", [])
251
- lat = payload.get("lat")
252
- lon = payload.get("lon")
253
- res = await forecast_aqi(aqi_hist, lat=lat, lon=lon)
254
- return JSONResponse(res)
255
- except Exception as e:
256
- logger.error(f"API Forecast error: {e}")
257
- return JSONResponse({"error": str(e)}, status_code=400)
258
-
259
- @gradio_app.post("/api/v1/analyze-image")
260
- async def api_analyze_image(request: Request):
261
- """REST API endpoint for satellite image pollution breakdown."""
262
- try:
263
- payload = await request.json()
264
- import base64
265
- from services.vision.service import detect_pollution_sources
266
- base64_str = payload.get("image_base64", "")
267
- if not base64_str:
268
- return JSONResponse({"error": "No image_base64 provided"}, status_code=400)
269
- if "," in base64_str:
270
- base64_str = base64_str.split(",", 1)[1]
271
- img_bytes = base64.b64decode(base64_str)
272
- pil_img = Image.open(io.BytesIO(img_bytes)).convert("RGB")
273
- res = await detect_pollution_sources(pil_img)
274
- return JSONResponse(res)
275
- except Exception as e:
276
- logger.error(f"API Vision error: {e}")
277
- return JSONResponse({"error": str(e)}, status_code=400)
278
-
279
- @gradio_app.get("/api/v1/health")
280
- async def api_health(request: Request):
281
- """Health check endpoint."""
282
- return JSONResponse({
283
- "status": "ok",
284
- "device": get_device(),
285
- "timestamp": datetime.now(timezone.utc).isoformat(),
286
- "version": "2.0.0",
287
- })
288
-
289
-
290
- # Register REST API routes on the Gradio underlying FastAPI app
291
- try:
292
- from fastapi.middleware.cors import CORSMiddleware
293
- # Explicitly configure CORS on the underlying FastAPI app to allow direct requests from the browser
294
- demo.app.add_middleware(
295
- CORSMiddleware,
296
- allow_origins=["*"],
297
- allow_credentials=True,
298
- allow_methods=["*"],
299
- allow_headers=["*"],
300
- )
301
- register_api_routes(demo.app)
302
- logger.info("CORS middleware and REST API routes registered successfully on Gradio FastAPI app.")
303
- except Exception as e:
304
- logger.warning(f"Could not register REST API routes or CORS (will be available via Gradio only): {e}")
305
 
306
- # Export Gradio demo as root app object for Hugging Face ZeroGPU SDK
307
- app = demo
308
 
309
  if __name__ == "__main__":
 
310
  # Local development only — on HF Spaces, uvicorn runs the app directly
311
- demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
 
230
  """
231
  )
232
 
233
+ from fastapi import FastAPI
234
+ from fastapi.middleware.cors import CORSMiddleware
235
  from starlette.responses import JSONResponse
236
  from starlette.requests import Request
237
 
238
+ # Create the FastAPI app
239
+ app = FastAPI(title="AQI Intelligence Engine API")
240
+
241
+ # Configure CORS directly on the FastAPI app
242
+ app.add_middleware(
243
+ CORSMiddleware,
244
+ allow_origins=["*"],
245
+ allow_credentials=True,
246
+ allow_methods=["*"],
247
+ allow_headers=["*"],
248
+ )
249
+
250
+ # Register REST API routes on the FastAPI app
251
+ @app.post("/api/forecast")
252
+ @app.post("/api/v1/forecast")
253
+ async def api_forecast(request: Request):
254
+ """REST API endpoint for historical AQI prediction."""
255
+ try:
256
+ payload = await request.json()
257
+ from services.forecast.service import forecast_aqi
258
+ aqi_hist = payload.get("aqi_history", [])
259
+ lat = payload.get("lat")
260
+ lon = payload.get("lon")
261
+ res = await forecast_aqi(aqi_hist, lat=lat, lon=lon)
262
+ return JSONResponse(res)
263
+ except Exception as e:
264
+ logger.error(f"API Forecast error: {e}")
265
+ return JSONResponse({"error": str(e)}, status_code=400)
266
 
267
+ @app.post("/api/analyze-image")
268
+ @app.post("/api/v1/analyze-image")
269
+ async def api_analyze_image(request: Request):
270
+ """REST API endpoint for satellite image pollution breakdown."""
271
+ try:
272
+ payload = await request.json()
273
+ import base64
274
+ from services.vision.service import detect_pollution_sources
275
+ base64_str = payload.get("image_base64", "")
276
+ if not base64_str:
277
+ return JSONResponse({"error": "No image_base64 provided"}, status_code=400)
278
+ if "," in base64_str:
279
+ base64_str = base64_str.split(",", 1)[1]
280
+ img_bytes = base64.b64decode(base64_str)
281
+ pil_img = Image.open(io.BytesIO(img_bytes)).convert("RGB")
282
+ res = await detect_pollution_sources(pil_img)
283
+ return JSONResponse(res)
284
+ except Exception as e:
285
+ logger.error(f"API Vision error: {e}")
286
+ return JSONResponse({"error": str(e)}, status_code=400)
287
+
288
+ @app.get("/api/health")
289
+ @app.get("/api/v1/health")
290
+ async def api_health(request: Request):
291
+ """Health check endpoint."""
292
+ return JSONResponse({
293
+ "status": "ok",
294
+ "device": get_device(),
295
+ "timestamp": datetime.now(timezone.utc).isoformat(),
296
+ "version": "2.0.0",
297
+ })
298
 
299
+ # Initialize the Gradio queue — this creates the underlying FastAPI app object
300
+ demo.queue()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
 
302
+ # Mount the Gradio app onto the FastAPI app at root path
303
+ app = gr.mount_gradio_app(app, demo, path="/")
304
 
305
  if __name__ == "__main__":
306
+ import uvicorn
307
  # Local development only — on HF Spaces, uvicorn runs the app directly
308
+ uvicorn.run(app, host="0.0.0.0", port=7860)