Gradio video generation app: Sume API key in a Space secret
Build a Gradio video generation app on the Sume API: the key stays in a Hugging Face Space secret, a generator polls the job, and gr.Video plays it.

To build a Gradio video generation app on the Sume API, read the key from an environment variable (a Hugging Face Space secret once hosted), write a generator that POSTs the prompt to https://api.sume.com/v1/videos and yields the job's status while it polls, then download the MP4 to a temp file and return its path to a gr.Video output.
Sume has no Gradio package or plugin; the app makes plain HTTPS calls with Requests. Sume facts come from Video Generation, Jobs and results, and Authentication; Gradio and Hugging Face facts come from Gradio's quickstart, queuing, streaming outputs, sharing, and file access guides and Hugging Face's Spaces overview, all read on 2026-09-27. The submit, poll, and download loop is explained step by step in Text-to-video API in Python.
What does the Gradio app look like?
One generator function and a Blocks layout, on Python 3.10 or later with pip install --upgrade gradio. Gradio accepts a generator the same way as a regular function and shows the sequence of values it yields, so the status box changes while the job runs.
The function downloads the MP4 because gr.Video displays a file path, and an unsigned_urls entry is an API route that the docs call with your key:
import os, tempfile, time, requests
import gradio as gr
AUTH = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
def make_video(prompt):
r = requests.post("https://api.sume.com/v1/videos", headers=AUTH, timeout=30,
json={"model": "sume/auto", "prompt": prompt})
r.raise_for_status()
job, deadline = r.json(), time.monotonic() + 20 * 60
while job["status"] not in ("completed", "failed", "cancelled") and time.monotonic() < deadline:
yield f"{job['id']}: {job['status']}", None
time.sleep(30)
job = requests.get(job["polling_url"], headers=AUTH, timeout=30).json()
if job["status"] != "completed":
yield f"{job['id']}: {job['status']} {job.get('error', '')}", None
return
path = os.path.join(tempfile.mkdtemp(), "video.mp4")
with open(path, "wb") as f:
f.write(requests.get(job["unsigned_urls"][0], headers=AUTH, timeout=300).content)
yield f"{job['id']}: completed", path
with gr.Blocks() as demo:
prompt, status, video = gr.Textbox(label="Prompt"), gr.Textbox(label="Status"), gr.Video()
gr.Button("Generate").click(make_video, prompt, [status, video], concurrency_limit=4)
demo.launch()Where does the Sume API key live?
In the server's environment, never in the page. Gradio's docs note that with a share link, all computation keeps running on your own computer while people use the app from their browsers, and Sume's docs say to keep API keys on trusted servers and out of frontend JavaScript.
- On Hugging Face Spaces, add
SUME_API_KEYas a secret in the Space's settings. Secrets are private, can't be read back from the settings page once set, and aren't added to Spaces duplicated from yours. Variables, by contrast, are public and are copied. - Both reach a Gradio app as environment variables, so the same
os.environlookup works in the Space and on your own machine once you export the key there. - Don't hard-code it. Hugging Face warns Space owners when its Secrets Scanner finds hard-coded secrets, and a key that shows up in logs or chat history should be rotated.
Who can spend Sume credits through the app?
Anyone who can reach it: every click submits a paid job on your key. Sume's docs say to validate user input and enforce your own authorization before forwarding requests.
- A public Space lets anyone view the source and use the running app. A protected Space hides the code, but the app stays public; a private Space is open only to the owner and collaborators.
- Share links are publicly accessible and expire after 1 week.
demo.launch(auth=(username, password))puts a login in front of the app. Gradio calls this a basic layer of access control, without rate limiting, and agr.LoginButtonalone restricts no one.- Each event is also an API endpoint named after its function by default, so the button isn't the only way in. Gradio suggests rate limits, by IP address or Hugging Face username, for public apps.
- The finished MP4 goes into Gradio's cache, and any file in the cache is available by URL to all users of the running app.
Which Gradio settings matter for long video jobs?
Video generation typically takes 30 seconds to several minutes, and the docs suggest polling about every 30 seconds. The code's 20-minute deadline ends the wait, not the job: a client-side deadline does not cancel it, and it keeps running and still bills, so the status line shows the job id for picking it up later. Video job concurrency and queueing covers how many Sume jobs run at once.
Three Gradio settings decide how the wait feels for users:
| Setting | Gradio's docs | For a Sume app |
|---|---|---|
concurrency_limit on .click() | Default: 1 at a time per event | Raise it, so one user's long job doesn't queue everyone else. Sume applies its own per-workspace job limits. |
gr.Video output | Expects a str or Path file path | Return the downloaded MP4's path from a temp directory; Gradio moves it into its cache. |
share in launch() | Default: False | Leave it off for anything that spends money; host on a Space with a secret instead. |
Sources
- Video Generation
- Jobs and results
- Authentication
- Gradio: Quickstart (read 2026-09-27)
- Gradio: Queuing (read 2026-09-27)
- Gradio: Streaming outputs (read 2026-09-27)
- Gradio: Sharing your app (read 2026-09-27)
- Gradio: File access (read 2026-09-27)
- Gradio: Video component (read 2026-09-27)
- Gradio: Button component (read 2026-09-27)
- Hugging Face: Spaces overview (read 2026-09-27)
Related posts
More in Integrations
- Inngest wait for event: resume when a Sume video run ends
Start a Sume run in step.run, turn its webhook into an Inngest event with a transform, then step.waitForEvent on the run id with a 2h timeout.
- LangChain video generation tool that runs a Sume Format
A LangChain @tool can start a Sume Format run, cap its spend, key it for safe retries, and return a run id the agent checks until the video is ready.
- LlamaIndex image generation tool with the Sume Image API
Wrap POST /v1/images in a LlamaIndex FunctionTool: send sume/auto and a prompt, return URLs on a 200, and hand back the job id on a 202.
- Make.com AI video scenario with Sume: HTTP and a webhook
Split a Make.com AI video scenario in two: Make a request starts a Sume run; a custom webhook takes the signed result and checks it with sha256().
Written by Sume