Skip to content
Back to skills

Gradio

ASecurity

Build and deploy ML demo interfaces with proper state management, queuing, and production patterns.

  • 14 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 7, 2026
devopspythonapiperformance

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 7, 2026

npx -y skills add modbender/skill-library-mcp --skill gradio --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Gradio?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Gradio
[![Security: A β€” Skills Directory](https://www.skillsdirectory.com/api/skills/modbender-gradio/badge)](https://www.skillsdirectory.com/skills/modbender-gradio)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: Gradio
description: Build and deploy ML demo interfaces with proper state management, queuing, and production patterns.
metadata: {"clawdbot":{"emoji":"🎨","requires":{"bins":["python3"]},"os":["linux","darwin","win32"]}}
---

# Gradio Patterns

## Interface vs Blocks
- `gr.Interface` is for single-function demos β€” use `gr.Blocks` for anything with multiple steps, conditional UI, or custom layout
- Blocks gives you `.click()`, `.change()`, `.submit()` event handlers β€” Interface only has one function
- Mixing Interface inside Blocks works but creates confusing state β€” pick one pattern per app

## State Management
- `gr.State()` creates per-session state β€” it resets when the user refreshes the page
- State values must be JSON-serializable or Gradio silently drops them β€” no custom classes without serialization
- Pass State as both input AND output to persist changes: `fn(state) -> state` β€” forgetting the output loses updates
- Global variables shared across users cause race conditions β€” always use `gr.State()` for user-specific data

## Queuing and Concurrency
- Without `.queue()`, long-running functions block all other users β€” always call `demo.queue()` before `.launch()`
- `concurrency_limit=1` on a function serializes calls β€” use for GPU-bound inference that can't parallelize
- `max_size` in queue limits waiting users β€” without it, memory grows unbounded under load
- Generator functions with `yield` enable streaming β€” but they hold a queue slot until complete

## File Handling
- Uploaded files are temp paths that get deleted after the request β€” copy them if you need persistence
- `gr.File(type="binary")` returns bytes, `type="filepath"` returns a string path β€” mismatching causes silent failures
- Return `gr.File(value="path/to/file")` for downloads, not raw bytes β€” the component handles content-disposition headers
- File uploads have a default 200MB limit β€” set `max_file_size` in `launch()` to change it

## Component Traps
- `gr.Dropdown(value=None)` with `allow_custom_value=False` crashes if the user submits nothing β€” set a default or make it optional
- `gr.Image(type="pil")` returns a PIL Image, `type="numpy"` returns an array, `type="filepath"` returns a path β€” inconsistent inputs break functions
- `gr.Chatbot` expects list of tuples `[(user, bot), ...]` β€” returning just strings doesn't render
- `visible=False` components still run their functions β€” use `gr.update(interactive=False)` to disable without hiding

## Authentication
- `auth=("user", "pass")` is plaintext in code β€” use `auth=auth_function` for production with proper credential checking
- Auth applies to the whole app β€” there's no per-route or per-component auth without custom middleware
- `share=True` with auth still exposes auth to Gradio's servers β€” use your own tunnel for sensitive apps

## Deployment
- `share=True` creates a 72-hour public URL through Gradio's servers β€” not for production, just demos
- Environment variables in local dev don't exist in Hugging Face Spaces β€” use Spaces secrets or the Settings UI
- `server_name="0.0.0.0"` to accept external connections β€” default `127.0.0.1` only allows localhost
- Behind a reverse proxy, set `root_path="/subpath"` or assets and API routes break

## Events and Updates
- Return `gr.update(value=x, visible=True)` to modify component properties β€” returning just the value only changes value
- Chain events with `.then()` for sequential operations β€” parallel `.click()` handlers race
- `every=5` on a function polls every 5 seconds β€” but it holds connections open, scale carefully
- `trigger_mode="once"` prevents double-clicks from firing twice β€” default allows rapid duplicate submissions

## Performance
- `cache_examples=True` pre-computes example outputs at startup β€” speeds up demos but increases load time
- Large model loading in the function runs per-request β€” load in global scope or use `gr.State` with initialization
- `batch=True` with `max_batch_size=N` groups concurrent requests β€” essential for GPU throughput

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…