--- title: zerogpu-transport-spike sdk: gradio sdk_version: 6.19.0 python_version: '3.10' app_file: app.py hardware: zero-gpu --- # ZeroGPU Transport Spike Purpose: validate the highest-risk assumption in the document-conversion design plan (§8.2, §18, §22.1): one Hugging Face ZeroGPU Space can host custom HTTP routes (`/v1` health/job/SSE/cancellation), custom `/v1` routes decorated with `@spaces.GPU`, and page-scoped Gradio `@spaces.GPU` API functions in the same app. This spike is intentionally isolated from production backends. It does not run OCR. It only exercises transport, queueing, cancellation state, and event replay. ## What This Proves Pass criteria: - `GET /v1/health/live` returns `200` without entering the ZeroGPU queue. - `POST /v1/jobs` creates an in-memory job and emits `job.created`. - `GET /v1/jobs/{job_id}/events` streams valid SSE events. - `DELETE /v1/jobs/{job_id}` marks the job cancelling/cancelled and future page calls fail with a stable cancellation response. - `POST /v1/jobs/{job_id}/pages/{page_number}/run` is callable as a custom REST route wrapped with `@spaces.GPU(duration=5)`. - `run_page` is callable as a Gradio API function wrapped with `@spaces.GPU(duration=5)`, validating the fallback transport. - Calling either page transport for several pages emits `page.started`, `page.completed`, and `job.completed` events visible through the custom SSE route. - A client can call custom routes and the Gradio GPU function against the same Space origin. Fail criteria: - Custom SSE is blocked or buffered by the Space/Gradio stack. - `DELETE` routes are unavailable or conflict with Gradio routing. - `@spaces.GPU` custom routes or API functions cannot coexist with custom `/v1` routes. - Gradio queue event behavior prevents reliable page-level orchestration. If this fails, Milestone 1 should redesign the transport around Gradio API functions plus Gradio's native event stream instead of real REST + custom SSE. ## Deployment Create a throwaway Hugging Face Space with ZeroGPU hardware and this directory as the app source. The `README.md` front matter above is the Space configuration. Using the authenticated HF CLI: ```bash hf repo create giarom/zerogpu-transport-spike --repo-type space --space-sdk gradio --exist-ok hf upload giarom/zerogpu-transport-spike spikes/zerogpu_transport . --repo-type space \ --commit-message "Update ZeroGPU transport spike" ``` ## Manual Test Replace `SPACE_URL` with the deployed Space URL. ```bash curl -s https://SPACE_URL/v1/health/live curl -s -X POST https://SPACE_URL/v1/jobs -H 'content-type: application/json' -d '{"pages":3}' curl -N https://SPACE_URL/v1/jobs//events curl -s -X POST https://SPACE_URL/v1/jobs//pages/1/run ``` In a second terminal, call the Gradio function with `@gradio/client` or the generated API docs: ```js import { Client } from "@gradio/client"; const client = await Client.connect("https://SPACE_URL"); await client.predict("/run_page", { job_id: "", page_number: 1 }); await client.predict("/run_page", { job_id: "", page_number: 2 }); await client.predict("/run_page", { job_id: "", page_number: 3 }); ``` Then test cancellation: ```bash curl -s -X DELETE https://SPACE_URL/v1/jobs/ ``` ## Automated Test After deployment, run the validator from the repository root: ```bash python spikes/zerogpu_transport/validate_transport.py https://giarom-zerogpu-transport-spike.hf.space --mode rest python spikes/zerogpu_transport/validate_transport.py https://giarom-zerogpu-transport-spike.hf.space --mode gradio ``` `--mode rest` is the primary path because it matches the Marker `/v1` adapter. `--mode gradio` validates the fallback design if custom REST GPU routes fail. ## Notes - State is intentionally in memory, matching the current Milestone 0 assumption that a Space restart loses workspace state (§10.5). - Cancellation is operative for future page submissions. It cannot guarantee force-killing an already-running ZeroGPU allocation, which matches §22.4.