deepdetection / app.py
akagtag's picture
Suppress asyncio fd shutdown noise in Space logs
4f52ddf
from __future__ import annotations
import os
import sys
import time
import traceback
from typing import Any
import gradio as gr
from fastapi import File, UploadFile
from fastapi.responses import RedirectResponse
from starlette.middleware import Middleware
from fastapi.middleware.cors import CORSMiddleware
from src.api.main import detect_image as api_detect_image
from src.api.main import detect_video as api_detect_video
from src.api.main import health as api_health
from src.api.main import health_models as api_health_models
from src.types import DetectionResponse
_default_unraisablehook = sys.unraisablehook
def _suppress_asyncio_fd_shutdown_noise(unraisable) -> None:
exc = unraisable.exc_value
if (
isinstance(exc, ValueError)
and str(exc) == "Invalid file descriptor: -1"
and getattr(unraisable.object, "__name__", "") == "__del__"
):
return
_default_unraisablehook(unraisable)
sys.unraisablehook = _suppress_asyncio_fd_shutdown_noise
def _install_excepthook() -> None:
def handle_exception(exc_type, exc_value, exc_tb):
traceback.print_exception(exc_type, exc_value, exc_tb)
sys.excepthook = handle_exception
def _normalize_gradio_env() -> None:
os.environ["GRADIO_SSR_MODE"] = "False"
os.environ.pop("GRADIO_NODE_SERVER_PORT", None)
def _build_demo() -> gr.Blocks:
with gr.Blocks(title="GenAI-DeepDetect") as demo:
gr.Markdown(
"""
# GenAI-DeepDetect
Gradio frontend with API routes attached to the same app for your external frontend.
Available API endpoints:
- `GET /api/health`
- `GET /api/health/models`
- `POST /api/detect/image`
- `POST /api/detect/video`
"""
)
return demo
def _attach_api_routes(app: Any) -> None:
async def health() -> dict:
return await api_health()
async def api_health_route() -> dict:
return await health()
async def health_models() -> dict[str, object]:
return await api_health_models()
async def api_health_models_route() -> dict[str, object]:
return await health_models()
async def detect_image(file: UploadFile = File(...)) -> DetectionResponse:
return await api_detect_image(file)
async def api_detect_image_route(file: UploadFile = File(...)) -> DetectionResponse:
return await detect_image(file)
async def detect_video(file: UploadFile = File(...)) -> DetectionResponse:
return await api_detect_video(file)
async def api_detect_video_route(file: UploadFile = File(...)) -> DetectionResponse:
return await detect_video(file)
async def gradio_compat_redirect() -> RedirectResponse:
return RedirectResponse(url="/", status_code=307)
app.add_api_route("/health", health, methods=["GET"])
app.add_api_route("/api/health", api_health_route, methods=["GET"])
app.add_api_route("/health/models", health_models, methods=["GET"])
app.add_api_route("/api/health/models", api_health_models_route, methods=["GET"])
app.add_api_route(
"/detect/image",
detect_image,
methods=["POST"],
response_model=DetectionResponse,
)
app.add_api_route(
"/api/detect/image",
api_detect_image_route,
methods=["POST"],
response_model=DetectionResponse,
)
app.add_api_route(
"/detect/video",
detect_video,
methods=["POST"],
response_model=DetectionResponse,
)
app.add_api_route(
"/api/detect/video",
api_detect_video_route,
methods=["POST"],
response_model=DetectionResponse,
)
app.add_api_route("/gradio", gradio_compat_redirect, methods=["GET"])
demo = _build_demo().queue()
if __name__ == "__main__":
_install_excepthook()
_normalize_gradio_env()
try:
app, _, _ = demo.launch(
prevent_thread_lock=True,
show_error=True,
ssr_mode=False,
app_kwargs={
"docs_url": "/docs",
"redoc_url": "/redoc",
"middleware": [
Middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
],
},
)
_attach_api_routes(app)
while True:
time.sleep(60)
except Exception:
traceback.print_exc()
sys.exit(1)