huggingface-gradio について
huggingface-gradioは、GradioのPython APIでインタラクティブなWeb UIや機械学習デモを構築するためのスキルです。開発者向けに、UIパターン、コンポーネント、イベント処理、クライアントの利用方法を扱います。
主な機能
- 01InterfaceとBlocksでUIを構築
- 02チャットボットUIを作成
- 03入出力コンポーネントを設定
- 04イベントを関数に接続
- 05PythonおよびJSクライアントを利用
活用シーン
- 01インタラクティブな機械学習デモの作成
- 02チャットボットWeb UIの構築
- 03コンポーネントとイベントの構成
- 04クライアントからアプリに接続
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ huggingface/ skills --skill gradioインストール後、Claude Code で/gradioを入力して読み込まれたか確認します。
同梱ファイルexamples.md
詳細
Gradio
Gradio は、インタラクティブな Web UI や ML デモを構築するための Python ライブラリです。このスキルでは、コア API、パターン、使用例を扱います。
ガイド
特定のトピックに関する詳細なガイドです(関連する場合に参照してください)。
- クイックスタート
- Interface クラス
- Blocks とイベントリスナー
- レイアウトの制御
- Blocks のその他の機能
- カスタム CSS と JS
- 出力のストリーミング
- 入力のストリーミング
- アプリの共有
- カスタム HTML コンポーネント
- Python クライアントの入門
- JS クライアントの入門
コアパターン
Interface(高レベル):関数を入力/出力コンポーネントでラップします。
import gradio as gr
def greet(name):
return f"Hello {name}!"
gr.Interface(fn=greet, inputs="text", outputs="text").launch()
Blocks(低レベル):イベントの接続を明示的に指定できる柔軟なレイアウトです。
import gradio as gr
with gr.Blocks() as demo:
name = gr.Textbox(label="Name")
output = gr.Textbox(label="Greeting")
btn = gr.Button("Greet")
btn.click(fn=lambda n: f"Hello {n}!", inputs=name, outputs=output)
demo.launch()
ChatInterface:チャットボット UI 向けの高レベルなラッパーです。
import gradio as gr
def respond(message, history):
return f"You said: {message}"
gr.ChatInterface(fn=respond).launch()
主なコンポーネントのシグネチャ
Textbox(value: str | I18nData | Callable | None = None, type: Literal['text', 'password', 'email'] = "text", lines: int = 1, max_lines: int | None = None, placeholder: str | I18nData | None = None, label: str | I18nData | None = None, info: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, autofocus: bool = False, autoscroll: bool = True, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", text_align: Literal['left', 'right'] | None = None, rtl: bool = False, buttons: list[Literal['copy'] | Button] | None = None, max_length: int | None = None, submit_btn: str | bool | None = False, stop_btn: str | bool | None = False, html_attributes: InputHTMLAttributes | None = None)
ユーザーが文字列を入力したり、文字列の出力を表示したりするためのテキストエリアを作成します。
Number(value: float | Callable | None = None, label: str | I18nData | None = None, placeholder: str | I18nData | None = None, info: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", buttons: list[Button] | None = None, precision: int | None = None, minimum: float | None = None, maximum: float | None = None, step: float = 1)
ユーザーが数値を入力したり、数値の出力を表示したりするための数値フィールドを作成します。
Slider(minimum: float = 0, maximum: float = 100, value: float | Callable | None = None, step: float | None = None, precision: int | None = None, label: str | I18nData | None = None, info: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", randomize: bool = False, buttons: list[Literal['reset']] | None = None)
{minimum} から {maximum} までの範囲を {step} 刻みで調整できるスライダーを作成します。
Checkbox(value: bool | Callable = False, label: str | I18nData | None = None, info: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", buttons: list[Button] | None = None)
True または False に設定できるチェックボックスを作成します。
Dropdown(choices: Sequence[str | int | float | tuple[str, str | int | float]] | None = None, value: str | int | float | Sequence[str | int | float] | Callable | DefaultValue | None = DefaultValue(), type: Literal['value', 'index'] = "value", multiselect: bool | None = None, allow_custom_value: bool = False, max_choices: int | None = None, filterable: bool = True, label: str | I18nData | None = None, info: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", buttons: list[Button] | None = None)
選択肢から単一または複数の項目を選択する(入力コンポーネントの場合)、または表示する(出力コンポーネントの場合)ドロップダウンを作成します。
Radio(choices: Sequence[str | int | float | tuple[str, str | int | float]] | None = None, value: str | int | float | Callable | None = None, type: Literal['value', 'index'] = "value", label: str | I18nData | None = None, info: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", rtl: bool = False, buttons: list[Button] | None = None)
文字列または数値型のラジオボタンを作成します。選択できる項目は1つだけです。
Image(value: str | PIL.Image.Image | np.ndarray | Callable | None = None, format: str = "webp", height: int | str | None = None, width: int | str | None = None, image_mode: Literal['1', 'L', 'P', 'RGB', 'RGBA', 'CMYK', 'YCbCr', 'LAB', 'HSV', 'I', 'F'] | None = "RGB", sources: list[Literal['upload', 'webcam', 'clipboard']] | Literal['upload', 'webcam', 'clipboard'] | None = None, type: Literal['numpy', 'pil', 'filepath'] = "numpy", label: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, buttons: list[Literal['download', 'share', 'fullscreen'] | Button] | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, streaming: bool = False, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", webcam_options: WebcamOptions | None = None, placeholder: str | None = None, watermark: WatermarkOptions | None = None)
画像をアップロード(入力)したり、画像を表示(出力)したりするための画像コンポーネントを作成します。
Audio(value: str | Path | tuple[int, np.ndarray] | Callable | None = None, sources: list[Literal['upload', 'microphone']] | Literal['upload', 'microphone'] | None = None, type: Literal['numpy', 'filepath'] = "numpy", label: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, streaming: bool = False, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", format: Literal['wav', 'mp3'] | None = None, autoplay: bool = False, editable: bool = True, buttons: list[Literal['download', 'share'] | Button] | None = None, waveform_options: WaveformOptions | dict | None = None, loop: bool = False, recording: bool = False, subtitles: str | Path | list[dict[str, Any]] | None = None, playback_position: float = 0)
音声をアップロード/録音(入力)したり、音声を表示(出力)したりするための音声コンポーネントを作成します。
Video(value: str | Path | Callable | None = None, format: str | None = None, sources: list[Literal['upload', 'webcam']] | Literal['upload', 'webcam'] | None = None, height: int | str | None = None, width: int | str | None = None, label: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", webcam_options: WebcamOptions | None = None, include_audio: bool | None = None, autoplay: bool = False, buttons: list[Literal['download', 'share'] | Button] | None = None, loop: bool = False, streaming: bool = False, watermark: WatermarkOptions | None = None, subtitles: str | Path | list[dict[str, Any]] | None = None, playback_position: float = 0)
動画をアップロード/録画(入力)したり、動画を表示(出力)したりするための動画コンポーネントを作成します。
File(value: str | list[str] | Callable | None = None, file_count: Literal['single', 'multiple', 'directory'] = "single", file_types: list[str] | None = None, type: Literal['filepath', 'binary'] = "filepath", label: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, height: int | str | float | None = None, interactive: bool | None = None, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", allow_reordering: bool = False, buttons: list[Button] | None = None)
1 つ以上の一般的なファイルをアップロード(入力として使用する場合)、またはダウンロード用の一般的なファイルや URL を表示する出力コンポーネントを作成します。
Chatbot(value: list[MessageDict | Message] | Callable | None = None, label: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, container: bool = True, scale: int | None = None, min_width: int = 160, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, autoscroll: bool = True, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", height: int | str | None = 400, resizable: bool = False, max_height: int | str | None = None, min_height: int | str | None = None, editable: Literal['user', 'all'] | None = None, latex_delimiters: list[dict[str, str | bool]] | None = None, rtl: bool = False, buttons: list[Literal['share', 'copy', 'copy_all'] | Button] | None = None, watermark: str | None = None, avatar_images: tuple[str | Path | None, str | Path | None] | None = None, sanitize_html: bool = True, render_markdown: bool = True, feedback_options: list[str] | tuple[str, ...] | None = ('Like', 'Dislike'), feedback_value: Sequence[str | None] | None = None, line_breaks: bool = True, layout: Literal['panel', 'bubble'] | None = None, placeholder: str | None = None, examples: list[ExampleMessage] | None = None, allow_file_downloads: <class 'inspect._empty'> = True, group_consecutive_messages: bool = True, allow_tags: list[str] | bool = True, reasoning_tags: list[tuple[str, str]] | None = None, like_user_message: bool = False)
ユーザーが送信したメッセージと応答を表示するチャットボットを作成します。
Button(value: str | I18nData | Callable = "Run", every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, variant: Literal['primary', 'secondary', 'stop', 'huggingface'] = "secondary", size: Literal['sm', 'md', 'lg'] = "lg", icon: str | Path | None = None, link: str | None = None, link_target: Literal['_self', '_blank', '_parent', '_top'] = "_self", visible: bool | Literal['hidden'] = True, interactive: bool = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", scale: int | None = None, min_width: int | None = None)
任意の .click() イベントを割り当てられるボタンを作成します。
Markdown(value: str | I18nData | Callable | None = None, label: str | I18nData | None = None, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool | None = None, rtl: bool = False, latex_delimiters: list[dict[str, str | bool]] | None = None, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", sanitize_html: bool = True, line_breaks: bool = False, header_links: bool = False, height: int | str | None = None, max_height: int | str | None = None, min_height: int | str | None = None, buttons: list[Literal['copy']] | None = None, container: bool = False, padding: bool = False)
任意の Markdown 出力をレンダリングするために使用します。
HTML(value: Any | Callable | None = None, label: str | I18nData | None = None, html_template: str = "${value}", css_template: str = "", js_on_load: str | None = "element.addEventListener('click', function() { trigger('click') });", apply_default_css: bool = True, every: Timer | float | None = None, inputs: Component | Sequence[Component] | set[Component] | None = None, show_label: bool = False, visible: bool | Literal['hidden'] = True, elem_id: str | None = None, elem_classes: list[str] | str | None = None, render: bool = True, key: int | str | tuple[int | str, ...] | None = None, preserved_by_key: list[str] | str | None = "value", min_height: int | None = None, max_height: int | None = None, container: bool = False, padding: bool = False, autoscroll: bool = False, buttons: list[Button] | None = None, server_functions: list[Callable] | None = None, props: Any)
任意の HTML を使ってコンポーネントを作成します。
カスタム HTML コンポーネント
既存のコンポーネントを大幅にカスタマイズする必要がある場合や、Gradio に存在しないコンポーネントが必要な場合は、gr.HTML で作成できます。html_template(${} の JS 式および {{}} の Handlebars 構文)、スコープ付きスタイルを指定する css_template、インタラクティブ機能を指定する js_on_load に対応しています。props.value でコンポーネントの値を更新し、trigger('event_name') で Gradio イベントを発火できます。再利用するには、gr.HTML をサブクラス化し、API/MCP をサポートする api_info() を定義します。詳細なガイドを参照してください。
この種のコンポーネントの作成方法と使用方法を示す例を以下に示します。
import gradio as gr
class StarRating(gr.HTML):
def __init__(self, label, value=0, **kwargs):
html_template = """
<h2>${label} rating:</h2>
${Array.from({length: 5}, (_, i) => `<img class='${i < value ? '' : 'faded'}' src='https://upload.wikimedia.org/wikipedia/commons/d/df/Award-star-gold-3d.svg'>`).join('')}
"""
css_template = """
img { height: 50px; display: inline-block; cursor: pointer; }
.faded { filter: grayscale(100%); opacity: 0.3; }
"""
js_on_load = """
const imgs = element.querySelectorAll('img');
imgs.forEach((img, index) => {
img.addEventListener('click', () => {
props.value = index + 1;
});
});
"""
super().__init__(value=value, label=label, html_template=html_template, css_template=css_template, js_on_load=js_on_load, **kwargs)
def api_info(self):
return {"type": "integer", "minimum": 0, "maximum": 5}
with gr.Blocks() as demo:
gr.Markdown("# Restaurant Review")
food_rating = StarRating(label="Food", value=3)
service_rating = StarRating(label="Service", value=3)
ambience_rating = StarRating(label="Ambience", value=3)
average_btn = gr.Button("Calculate Average Rating")
rating_output = StarRating(label="Average", value=3)
def calculate_average(food, service, ambience):
return round((food + service + ambience) / 3)
average_btn.click(
fn=calculate_average,
inputs=[food_rating, service_rating, ambience_rating],
outputs=rating_output
)
demo.launch()
イベントリスナー
すべてのイベントリスナーは同じシグネチャを共有します。
component.event_name(
fn: Callable | None | Literal["decorator"] = "decorator",
inputs: Component | Sequence[Component] | set[Component] | None = None,
outputs: Component | Sequence[Component] | set[Component] | None = None,
api_name: str | None = None,
api_description: str | None | Literal[False] = None,
scroll_to_output: bool = False,
show_progress: Literal["full", "minimal", "hidden"] = "full",
show_progress_on: Component | Sequence[Component] | None = None,
queue: bool = True,
batch: bool = False,
max_batch_size: int = 4,
preprocess: bool = True,
postprocess: bool = True,
cancels: dict[str, Any] | list[dict[str, Any]] | None = None,
trigger_mode: Literal["once", "multiple", "always_last"] | None = None,
js: str | Literal[True] | None = None,
concurrency_limit: int | None | Literal["default"] = "default",
concurrency_id: str | None = None,
api_visibility: Literal["public", "private", "undocumented"] = "public",
time_limit: int | None = None,
stream_every: float = 0.5,
key: int | str | tuple[int | str, ...] | None = None,
validator: Callable | None = None,
) -> Dependency
コンポーネントごとにサポートされるイベント:
- AnnotatedImage:select
- Audio:stream, change, clear, play, pause, stop, pause, start_recording, pause_recording, stop_recording, upload, input
- BarPlot:select, double_click
- BrowserState:change
- Button:click
- Chatbot:change, select, like, retry, undo, example_select, option_select, clear, copy, edit
- Checkbox:change, input, select
- CheckboxGroup:change, input, select
- ClearButton:click
- Code:change, input, focus, blur
- ColorPicker:change, input, submit, focus, blur
- Dataframe:change, input, select, edit
- Dataset:click, select
- DateTime:change, submit
- DeepLinkButton:click
- Dialogue:change, input, submit
- DownloadButton:click
- Dropdown:change, input, select, focus, blur, key_up
- DuplicateButton:click
- File:change, select, clear, upload, delete, download
- FileExplorer:change, input, select
- Gallery:select, upload, change, delete, preview_close, preview_open
- HTML:change, input, click, double_click, submit, stop, edit, clear, play, pause, end, start_recording, pause_recording, stop_recording, focus, blur, upload, release, select, stream, like, example_select, option_select, load, key_up, apply, delete, tick, undo, retry, expand, collapse, download, copy
- HighlightedText:change, select
- Image:clear, change, stream, select, upload, input
- ImageEditor:clear, change, input, select, upload, apply
- ImageSlider:clear, change, stream, select, upload, input
- JSON:change
- Label:change, select
- LinePlot:select, double_click
- LoginButton:click
- Markdown:change, copy
- Model3D:change, upload, edit, clear
- MultimodalTextbox:change, input, select, submit, focus, blur, stop
- Navbar:change
- Number:change, input, submit, focus, blur
- ParamViewer:change, upload
- Plot:change
- Radio:select, change, input
- ScatterPlot:select, double_click
- SimpleImage:clear, change, upload
- Slider:change, input, release
- State:change
- Textbox:change, input, select, submit, focus, blur, stop, copy
- Timer:tick
- UploadButton:click, upload
- Video:change, clear, start_recording, stop_recording, stop, play, pause, end, upload, input
予測 CLI
gradio CLI には、Gradio アプリをプログラムから操作するための info コマンドと predict コマンドが含まれています。これらは、ワークフローで Spaces を使用する必要があるコーディングエージェントにとって特に便利です。
gradio info — エンドポイントとパラメーターを確認する
gradio info <space_id_or_url>
すべてのエンドポイント、そのパラメーター(型とデフォルト値を含む)、および戻り値を説明する JSON ペイロードを返します。
gradio info gradio/calculator
# {
# "/predict": {
# "parameters": [
# {"name": "num1", "required": true, "default": null, "type": {"type": "number"}},
# {"name": "operation", "required": true, "default": null, "type": {"enum": ["add", "subtract", "multiply", "divide"], "type": "string"}},
# {"name": "num2", "required": true, "default": null, "type": {"type": "number"}}
# ],
# "returns": [{"name": "output", "type": {"type": "number"}}],
# "description": ""
# }
# }
ファイル型のパラメーターには "type": "filepath" が表示され、"meta": {"_type": "gradio.FileData"} を含めるよう指示されます。これは、ファイルがリモートサーバーにアップロードされることを示します。
gradio predict — 予測を送信する
gradio predict <space_id_or_url> <endpoint> <json_payload>
名前付きの出力キーを含む JSON オブジェクトを返します。
# Simple numeric prediction
gradio predict gradio/calculator /predict '{"num1": 5, "operation": "multiply", "num2": 3}'
# {"output": 15}
# Image generation
gradio predict black-forest-labs/FLUX.2-dev /infer '{"prompt": "A majestic dragon"}'
# {"Result": "/tmp/gradio/.../image.webp", "Seed": 1117868604}
# File upload (must include meta key)
gradio predict gradio/image_mod /predict '{"image": {"path": "/path/to/image.png", "meta": {"_type": "gradio.FileData"}}}'
# {"output": "/tmp/gradio/.../output.png"}
どちらのコマンドも、プライベート Spaces にアクセスするための --token を受け付けます。
参考資料
- エンドツーエンドの例 — 動作する完全なアプリ