Justin Wood commited on
Commit
94d3997
·
1 Parent(s): 85c4e5d

Switch to Docker SDK — clean FastAPI + ZeroGPU, no Gradio conflict

Browse files
Files changed (4) hide show
  1. Dockerfile +18 -0
  2. README.md +2 -4
  3. app.py +7 -16
  4. requirements.txt +1 -1
Dockerfile ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ WORKDIR /app
4
+
5
+ # System deps for OpenCV and trimesh
6
+ RUN apt-get update && apt-get install -y --no-install-recommends \
7
+ libgl1 libglib2.0-0 git \
8
+ && rm -rf /var/lib/apt/lists/*
9
+
10
+ # Install Python deps
11
+ COPY requirements.txt .
12
+ RUN pip install --no-cache-dir -r requirements.txt
13
+
14
+ # Copy app
15
+ COPY . .
16
+
17
+ EXPOSE 7860
18
+ CMD ["uvicorn", "app:asgi_app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -3,14 +3,12 @@ title: Jiggle Physics Backend
3
  emoji: 🎯
4
  colorFrom: purple
5
  colorTo: indigo
6
- sdk: gradio
7
- sdk_version: "5.0.0"
8
- app_file: app.py
9
  pinned: false
10
  license: mit
11
  ---
12
 
13
- REST API for the Jiggle Physics Simulator. Endpoints mounted on Gradio's FastAPI instance for ZeroGPU compatibility.
14
 
15
  | Endpoint | Method | What it does |
16
  |---|---|---|
 
3
  emoji: 🎯
4
  colorFrom: purple
5
  colorTo: indigo
6
+ sdk: docker
 
 
7
  pinned: false
8
  license: mit
9
  ---
10
 
11
+ REST API for the Jiggle Physics Simulator. Runs FastAPI + ZeroGPU (Docker SDK).
12
 
13
  | Endpoint | Method | What it does |
14
  |---|---|---|
app.py CHANGED
@@ -1,27 +1,21 @@
1
  """
2
- Jiggle Physics Simulator — HuggingFace Space backend
3
- ZeroGPU pattern: routes are added to Gradio's underlying FastAPI instance.
4
- Deploy with sdk: gradio and ZeroGPU hardware selected in Space settings.
5
  """
6
  import base64
7
  import io
8
  import json
9
  from typing import Optional
10
 
11
- import gradio as gr
12
  import spaces
13
  import numpy as np
14
- from fastapi import File, Form, UploadFile, HTTPException
15
  from fastapi.middleware.cors import CORSMiddleware
16
  from fastapi.responses import Response
17
  from PIL import Image
18
 
19
- # ── Minimal Gradio UI (required for ZeroGPU Spaces) ──────────────────────────
20
- with gr.Blocks(title="Jiggle Physics API") as demo:
21
- gr.Markdown("## Jiggle Physics ML API\nREST endpoints: `/segment` `/depth` `/reconstruct`")
22
 
23
- # Grab Gradio's underlying FastAPI app and add CORS
24
- app = demo.app
25
  app.add_middleware(
26
  CORSMiddleware,
27
  allow_origins=["*"],
@@ -29,6 +23,9 @@ app.add_middleware(
29
  allow_headers=["*"],
30
  )
31
 
 
 
 
32
 
33
  def _load_image(upload: UploadFile) -> Image.Image:
34
  data = upload.file.read()
@@ -141,7 +138,6 @@ async def reconstruct(
141
  flat.extend([current] * run)
142
  current = not current
143
  mask = np.array(flat, dtype=bool).reshape(shape)
144
-
145
  bbox_list = json.loads(bbox)
146
 
147
  try:
@@ -154,8 +150,3 @@ async def reconstruct(
154
  raise HTTPException(status_code=500, detail=str(e))
155
 
156
  return Response(content=glb_bytes, media_type="application/octet-stream")
157
-
158
-
159
- # ── Entry point ───────────────────────────────────────────────────────────────
160
- if __name__ == "__main__":
161
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
  """
2
+ Jiggle Physics Simulator — HuggingFace Space backend (Docker SDK)
3
+ ZeroGPU works with Docker Spaces @spaces.GPU allocates A10G per request.
 
4
  """
5
  import base64
6
  import io
7
  import json
8
  from typing import Optional
9
 
 
10
  import spaces
11
  import numpy as np
12
+ from fastapi import FastAPI, File, Form, UploadFile, HTTPException
13
  from fastapi.middleware.cors import CORSMiddleware
14
  from fastapi.responses import Response
15
  from PIL import Image
16
 
17
+ app = FastAPI(title="Jiggle Physics ML API")
 
 
18
 
 
 
19
  app.add_middleware(
20
  CORSMiddleware,
21
  allow_origins=["*"],
 
23
  allow_headers=["*"],
24
  )
25
 
26
+ # Export for uvicorn CMD in Dockerfile
27
+ asgi_app = app
28
+
29
 
30
  def _load_image(upload: UploadFile) -> Image.Image:
31
  data = upload.file.read()
 
138
  flat.extend([current] * run)
139
  current = not current
140
  mask = np.array(flat, dtype=bool).reshape(shape)
 
141
  bbox_list = json.loads(bbox)
142
 
143
  try:
 
150
  raise HTTPException(status_code=500, detail=str(e))
151
 
152
  return Response(content=glb_bytes, media_type="application/octet-stream")
 
 
 
 
 
requirements.txt CHANGED
@@ -1,4 +1,3 @@
1
- gradio>=5.0.0
2
  fastapi
3
  uvicorn
4
  python-multipart
@@ -11,3 +10,4 @@ trimesh
11
  pygltflib
12
  opencv-python-headless
13
  spaces
 
 
 
1
  fastapi
2
  uvicorn
3
  python-multipart
 
10
  pygltflib
11
  opencv-python-headless
12
  spaces
13
+ scipy