π¦ ClawHub
Gradio
by @ivangdavila
Build and deploy ML demo interfaces with proper state management, queuing, and production patterns.
TERMINAL
clawhub install gradioπ About This Skill
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.click(), .change(), .submit() event handlers β Interface only has one functionState Management
gr.State() creates per-session state β it resets when the user refreshes the pagefn(state) -> state β forgetting the output loses updatesgr.State() for user-specific dataQueuing and Concurrency
.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 parallelizemax_size in queue limits waiting users β without it, memory grows unbounded under loadyield enable streaming β but they hold a queue slot until completeFile Handling
gr.File(type="binary") returns bytes, type="filepath" returns a string path β mismatching causes silent failuresgr.File(value="path/to/file") for downloads, not raw bytes β the component handles content-disposition headersmax_file_size in launch() to change itComponent Traps
gr.Dropdown(value=None) with allow_custom_value=False crashes if the user submits nothing β set a default or make it optionalgr.Image(type="pil") returns a PIL Image, type="numpy" returns an array, type="filepath" returns a path β inconsistent inputs break functionsgr.Chatbot expects list of tuples [(user, bot), ...] β returning just strings doesn't rendervisible=False components still run their functions β use gr.update(interactive=False) to disable without hidingAuthentication
auth=("user", "pass") is plaintext in code β use auth=auth_function for production with proper credential checkingshare=True with auth still exposes auth to Gradio's servers β use your own tunnel for sensitive appsDeployment
share=True creates a 72-hour public URL through Gradio's servers β not for production, just demosserver_name="0.0.0.0" to accept external connections β default 127.0.0.1 only allows localhostroot_path="/subpath" or assets and API routes breakEvents and Updates
gr.update(value=x, visible=True) to modify component properties β returning just the value only changes value.then() for sequential operations β parallel .click() handlers raceevery=5 on a function polls every 5 seconds β but it holds connections open, scale carefullytrigger_mode="once" prevents double-clicks from firing twice β default allows rapid duplicate submissionsPerformance
cache_examples=True pre-computes example outputs at startup β speeds up demos but increases load timegr.State with initializationbatch=True with max_batch_size=N groups concurrent requests β essential for GPU throughput