|
| 1 | +# Spaces as API endpoints |
| 2 | + |
| 3 | +Every Gradio Space on Hugging Face is automatically available as an API endpoint. You can call it from Python, JavaScript, or any HTTP client. If you can use a Space in your browser, you can call it as an API. |
| 4 | + |
| 5 | +## Quick start |
| 6 | + |
| 7 | +Install the Python client and call any public Space: |
| 8 | + |
| 9 | +```bash |
| 10 | +pip install --upgrade gradio_client |
| 11 | +``` |
| 12 | + |
| 13 | +```python |
| 14 | +from gradio_client import Client |
| 15 | + |
| 16 | +client = Client("abidlabs/en2fr", token="hf_...") |
| 17 | +result = client.predict("Hello, world!", api_name="/predict") |
| 18 | +print(result) # "Bonjour, le monde!" |
| 19 | +``` |
| 20 | + |
| 21 | +## View available API endpoints |
| 22 | + |
| 23 | +Every Gradio Space has a "Use via API" link in the footer. Click it to see: |
| 24 | + |
| 25 | +- All available endpoints and their names |
| 26 | +- Parameter types and descriptions |
| 27 | +- Auto-generated code snippets for Python and JavaScript |
| 28 | +- An API Recorder that generates code from your UI interactions |
| 29 | + |
| 30 | +Every Space also exposes an OpenAPI specification at: |
| 31 | + |
| 32 | +``` |
| 33 | +https://<space-subdomain>.hf.space/gradio_api/openapi.json |
| 34 | +``` |
| 35 | + |
| 36 | +For example: `https://abidlabs-en2fr.hf.space/gradio_api/openapi.json` |
| 37 | + |
| 38 | +This is useful to understand the full API schema and integrate it into your own applications. |
| 39 | + |
| 40 | +You can also inspect endpoints programmatically: |
| 41 | + |
| 42 | +```python |
| 43 | +from gradio_client import Client |
| 44 | + |
| 45 | +client = Client("abidlabs/whisper", token="hf_...") |
| 46 | +client.view_api() # Prints all endpoints with parameters |
| 47 | +``` |
| 48 | + |
| 49 | +## Python client |
| 50 | + |
| 51 | +### Installation |
| 52 | + |
| 53 | +```bash |
| 54 | +pip install --upgrade gradio_client |
| 55 | +``` |
| 56 | + |
| 57 | +Requires Python 3.10+. |
| 58 | + |
| 59 | +### Connect to a Space |
| 60 | + |
| 61 | +```python |
| 62 | +from gradio_client import Client |
| 63 | + |
| 64 | +# Public Space |
| 65 | +client = Client("username/space-name") |
| 66 | + |
| 67 | +# Private Space (requires token) |
| 68 | +client = Client("username/private-space", token="hf_xxxxx") |
| 69 | +``` |
| 70 | + |
| 71 | +> [!TIP] |
| 72 | +> Get your Hugging Face token at [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens). For private Spaces, you need a token with **READ** permissions. |
| 73 | +
|
| 74 | +### Make Predictions |
| 75 | + |
| 76 | +**Synchronous (blocking):** |
| 77 | + |
| 78 | +```python |
| 79 | +result = client.predict("Hello", api_name="/predict") |
| 80 | +``` |
| 81 | + |
| 82 | +**Asynchronous (non-blocking):** |
| 83 | + |
| 84 | +```python |
| 85 | +job = client.submit("Hello", api_name="/predict") |
| 86 | +# Do other work... |
| 87 | +result = job.result() # Get result when ready |
| 88 | +``` |
| 89 | + |
| 90 | +### Handle Files |
| 91 | + |
| 92 | +Use `handle_file()` for any file inputs: |
| 93 | + |
| 94 | +```python |
| 95 | +from gradio_client import Client, handle_file |
| 96 | + |
| 97 | +client = Client("abidlabs/whisper", token="hf_...") |
| 98 | + |
| 99 | +# From local file |
| 100 | +result = client.predict(audio=handle_file("audio.wav"), api_name="/predict") |
| 101 | + |
| 102 | +# From URL |
| 103 | +result = client.predict(audio=handle_file("https://example.com/audio.wav"), api_name="/predict") |
| 104 | +``` |
| 105 | + |
| 106 | +### Monitor Job Status |
| 107 | + |
| 108 | +```python |
| 109 | +job = client.submit("Hello", api_name="/predict") |
| 110 | + |
| 111 | +# Check status |
| 112 | +status = job.status() |
| 113 | +print(f"Queue position: {status.rank}, ETA: {status.eta}") |
| 114 | + |
| 115 | +# Check if complete |
| 116 | +if job.done(): |
| 117 | + result = job.result() |
| 118 | + |
| 119 | +# Cancel a pending job |
| 120 | +job.cancel() |
| 121 | +``` |
| 122 | + |
| 123 | +### Streaming/Generator Endpoints |
| 124 | + |
| 125 | +For endpoints that yield multiple outputs: |
| 126 | + |
| 127 | +```python |
| 128 | +job = client.submit(prompt="Write a story", api_name="/generate") |
| 129 | + |
| 130 | +# Iterate over streaming outputs |
| 131 | +for output in job: |
| 132 | + print(output) |
| 133 | +``` |
| 134 | + |
| 135 | +## JavaScript client |
| 136 | + |
| 137 | +### Installation |
| 138 | + |
| 139 | +```bash |
| 140 | +npm i @gradio/client |
| 141 | +``` |
| 142 | + |
| 143 | +Or use via CDN: |
| 144 | + |
| 145 | +```html |
| 146 | +<script type="module"> |
| 147 | + import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js"; |
| 148 | +</script> |
| 149 | +``` |
| 150 | + |
| 151 | +### Connect and Predict |
| 152 | + |
| 153 | +```javascript |
| 154 | +import { Client } from "@gradio/client"; |
| 155 | + |
| 156 | +const app = await Client.connect("abidlabs/en2fr", { token: "hf_..." }); |
| 157 | +const result = await app.predict("/predict", ["Hello"]); |
| 158 | +console.log(result.data); |
| 159 | +``` |
| 160 | + |
| 161 | +### Handle Files |
| 162 | + |
| 163 | +```javascript |
| 164 | +import { Client, handle_file } from "@gradio/client"; |
| 165 | + |
| 166 | +const app = await Client.connect("abidlabs/whisper", { token: "hf_..." }); |
| 167 | +const result = await app.predict("/predict", [ |
| 168 | + handle_file("https://example.com/audio.wav") |
| 169 | +]); |
| 170 | +``` |
| 171 | + |
| 172 | +### Stream Results |
| 173 | + |
| 174 | +```javascript |
| 175 | +const job = app.submit("/predict", ["Hello"]); |
| 176 | + |
| 177 | +for await (const message of job) { |
| 178 | + if (message.type === "data") { |
| 179 | + console.log("Result:", message.data); |
| 180 | + } |
| 181 | + if (message.type === "status") { |
| 182 | + console.log("Queue position:", message.position); |
| 183 | + } |
| 184 | +} |
| 185 | +``` |
| 186 | + |
| 187 | +## REST API (curl) |
| 188 | + |
| 189 | +You can also call Gradio Spaces directly via HTTP without any client library. |
| 190 | + |
| 191 | +### Queue-Based API (Recommended) |
| 192 | + |
| 193 | +Most Spaces use a two-step process: |
| 194 | + |
| 195 | +**Step 1: Submit your request** |
| 196 | + |
| 197 | +```bash |
| 198 | +curl -X POST "https://abidlabs-en2fr.hf.space/gradio_api/call/predict" \ |
| 199 | + -H "Content-Type: application/json" \ |
| 200 | + -H "Authorization: Bearer $HF_TOKEN" \ |
| 201 | + -d '{"data": ["Hello, world"]}' |
| 202 | +``` |
| 203 | + |
| 204 | +Response: |
| 205 | +```json |
| 206 | +{"event_id": "abc123"} |
| 207 | +``` |
| 208 | + |
| 209 | +**Step 2: Get the result** |
| 210 | + |
| 211 | +```bash |
| 212 | +curl -N "https://abidlabs-en2fr.hf.space/gradio_api/call/predict/abc123" \ |
| 213 | + -H "Authorization: Bearer $HF_TOKEN" |
| 214 | +``` |
| 215 | + |
| 216 | +Response (Server-Sent Events): |
| 217 | +``` |
| 218 | +event: complete |
| 219 | +data: ["Bonjour, le monde!"] |
| 220 | +``` |
| 221 | + |
| 222 | +The `Authorization` header is required for private Spaces and gives better rate limits on public Spaces. |
| 223 | + |
| 224 | +## ZeroGPU Spaces |
| 225 | + |
| 226 | +ZeroGPU Spaces have usage quotas based on your account type: |
| 227 | + |
| 228 | +| Account Type | Daily GPU Quota | |
| 229 | +|-------------|----------------| |
| 230 | +| Unauthenticated | 2 minutes | |
| 231 | +| Free account | 3.5 minutes | |
| 232 | +| PRO account | 25 minutes | |
| 233 | + |
| 234 | +When you authenticate with your token, your account's GPU quota is consumed. Unauthenticated requests use a shared pool with stricter limits. |
| 235 | + |
| 236 | +> [!TIP] |
| 237 | +> You can [subscribe to PRO](https://huggingface.co/subscribe/pro) for 25 minutes of daily GPU quota and higher queue priority. |
| 238 | +
|
| 239 | +## Common patterns |
| 240 | + |
| 241 | +### FastAPI Integration |
| 242 | + |
| 243 | +```python |
| 244 | +from fastapi import FastAPI |
| 245 | +from gradio_client import Client, handle_file |
| 246 | + |
| 247 | +app = FastAPI() |
| 248 | +client = Client("abidlabs/whisper", token="hf_...") |
| 249 | + |
| 250 | +@app.post("/transcribe/") |
| 251 | +async def transcribe(file_url: str): |
| 252 | + result = client.predict(audio=handle_file(file_url), api_name="/predict") |
| 253 | + return {"transcription": result} |
| 254 | +``` |
| 255 | + |
| 256 | +### Error Handling with Retries |
| 257 | + |
| 258 | +```python |
| 259 | +import time |
| 260 | +from gradio_client import Client |
| 261 | + |
| 262 | +def predict_with_retry(client, *args, max_retries=3, **kwargs): |
| 263 | + for attempt in range(max_retries): |
| 264 | + try: |
| 265 | + return client.predict(*args, **kwargs) |
| 266 | + except Exception as e: |
| 267 | + if attempt < max_retries - 1: |
| 268 | + time.sleep(2 ** attempt) # Exponential backoff |
| 269 | + else: |
| 270 | + raise |
| 271 | + |
| 272 | +client = Client("username/space", token="hf_...") |
| 273 | +result = predict_with_retry(client, "input", api_name="/predict") |
| 274 | +``` |
| 275 | + |
| 276 | +### Calling Spaces from Another Space |
| 277 | + |
| 278 | +When calling a ZeroGPU Space from your own Gradio app, forward the user's authentication: |
| 279 | + |
| 280 | +```python |
| 281 | +import gradio as gr |
| 282 | +from gradio_client import Client |
| 283 | + |
| 284 | +def process(prompt, request: gr.Request): |
| 285 | + x_ip_token = request.headers.get('x-ip-token', '') |
| 286 | + client = Client("owner/zerogpu-space", headers={"x-ip-token": x_ip_token}) |
| 287 | + return client.predict(prompt, api_name="/predict") |
| 288 | + |
| 289 | +demo = gr.Interface(fn=process, inputs="text", outputs="text") |
| 290 | +demo.launch() |
| 291 | +``` |
| 292 | + |
| 293 | +## Find Spaces with semantic search |
| 294 | + |
| 295 | +With thousands of Gradio Spaces available, you can search for the right one by describing what you need: |
| 296 | + |
| 297 | +```bash |
| 298 | +curl -s "https://huggingface.co/api/spaces/semantic-search?q=text+to+speech&sdk=gradio" |
| 299 | +``` |
| 300 | + |
| 301 | +This returns Spaces ranked by semantic relevance, with metadata including the Space ID, likes, and a short description. Use the `sdk=gradio` parameter to filter for Spaces that expose an API. |
| 302 | + |
| 303 | +## Learn more |
| 304 | + |
| 305 | +- [Gradio Python Client Guide](https://www.gradio.app/guides/getting-started-with-the-python-client) |
| 306 | +- [Gradio JavaScript Client Guide](https://www.gradio.app/guides/getting-started-with-the-js-client) |
| 307 | +- [Querying Gradio Apps with curl](https://www.gradio.app/guides/querying-gradio-apps-with-curl) |
| 308 | +- [Spaces ZeroGPU](./spaces-zerogpu) |
0 commit comments