Gradio

repository·main·Indexed 12 days ago

https://github.com/gradio-app/gradio

An open-source Python package for quickly building and sharing web interfaces for machine learning models, APIs, or Python functions. Includes the @gradio/client JavaScript library and gradio_client Python library for programmatic interaction with Gradio apps, as well as Svelte-based UI components like @gradio/atoms and @gradio/button.

Tokens
317.7K
Snippets
1K
Records
1.4K
Agent score
96%

What's inside Gradio

  1. Overview of the Gradio Ecosystem

    main

    Gradio extends beyond the core Python library with several tools for programmatic access and hosting:

    • gradio_client (Python): Query any Gradio app programmatically using Python.
    • @gradio/client (JavaScript): Query any Gradio app programmatically using JavaScript.
    • Hugging Face Spaces: The primary hosting platform for Gradio applications.
    • Server mode (gradio.Server): Allows building completely custom frontends while using Gradio's backend (queue, streaming, etc.).
  2. Use `@gradio/video` components

    main

    The @gradio/video package provides components for displaying and interacting with video content in Gradio web applications. It includes support for static video playback, interactive video uploading/recording, and a base player for custom implementations.

    Key components include:

    • BaseStaticVideo: Used for displaying a video that does not require user interaction (e.g., a simple playback component).
    • BaseInteractiveVideo: (Implied by imports) For handling interactive video states.
    • BasePlayer: A low-level player component that accepts a src and provides event hooks for playback control.
    • Video: An interactive component that allows users to upload videos or use a webcam source.
    // Example of the component structure for an interactive Video component
    <Video
    	value={_video}
    	{label}
    	{show_label}
    	source="upload"
    	{mirror_webcam}
    	{include_audio}
    	{autoplay}
    	i18n={gradio.i18n}
    >
    	<p>Upload Video Here</p>
    </Video>
  3. Use the Gradio JavaScript Client

    main

    The @gradio/client library provides a programmatic interface to interact with Gradio-hosted APIs. The primary entry point is the Client class, which is used to connect to a specific Gradio application instance.

    Key features include:

    • Client: The main class for connecting to a Gradio app.
    • duplicate: A method for duplicating an existing client or configuration.
    • handle_file: A utility to process various input types (File, string, Blob, or Buffer) into a format compatible with Gradio API calls.
  4. Understand CSS variable naming conventions

    main

    Gradio CSS variables follow a structured naming convention separated by underscores to make them predictable. The pattern is generally:

    1. Target element: e.g., button, slider, block.
    2. Sub-element/Type: e.g., button_primary, block_label.
    3. Property: e.g., background_fill, border_width.
    4. State: e.g., hover, focus.
    5. Dark Mode Suffix: If the value is specific to dark mode, it ends in _dark (e.g., input_border_color_focus_dark).

    Example: button_primary_background_fill_hover.

  5. Enable session stickiness for multiple replicas

    main

    If you are deploying Gradio apps using multiple replicas (e.g., on AWS ECS), you must enable session stickiness (also known as client affinity).

    Why? Gradio's communication protocol requires multiple separate connections from the frontend to the backend to process events correctly. Without stickiness, requests from a single user might be routed to different instances, breaking the application state.

    How to implement:

    • In AWS/Load Balancers, use sessionAffinity: ClientIP.
    • If using Terraform, add a stickiness block to your target group definition.
  6. Create custom input components using `js_on_load`

    main

    You can turn gr.HTML into an interactive input component by providing a js_on_load string containing JavaScript.

    Inside js_on_load, you have access to:

    • trigger(event_name, data): Triggers a Gradio event. data can be a dictionary that is received in Python as a gr.EventData object.
    • props: An object containing the component's current properties (e.g., props.value). Updating props.<prop_name> will re-render the template.
    • upload(file): An async function to upload a JavaScript File object to the Gradio server. It returns { path, url }.
    • watch(prop_name, callback): Runs a callback when a specific prop changes.
    • server: An object providing access to Python functions passed via the server_functions parameter.

    Note on Dynamic Elements: Since js_on_load runs only once on initial render, use event delegation for dynamically created elements:

    element.addEventListener('click', (e) => {
        if (e.target && e.target.matches('.child-element')) {
            props.value = e.target.dataset.value;
        }
    });
    # Python side: listening to a custom event
    def handle_event(evt: gr.EventData):
        print(evt.key)
        print(evt.count)
    
    # Component side
    custom_comp = gr.HTML(
        value="...",
        js_on_load="""
            const btn = document.querySelector('#my-btn');
            btn.addEventListener('click', () => {
                trigger('my_custom_event', { key: 'hello', count: 123 });
            });
        """
    )
    custom_comp.my_custom_event(fn=handle_event, inputs=[], outputs=[])
  7. Structure a custom app with gr.Blocks

    main

    To build custom layouts and complex data flows, use the gr.Blocks() class.

    1. Context Manager: Wrap your app code in a with gr.Blocks() as demo: block.
    2. Components: Create components (like gr.Textbox, gr.Button) inside the with block. They are automatically added to the app.
    3. Event Listeners: Define interactivity by attaching listeners (like .click()) to components. Listeners connect inputs to a function and map the function's return values to outputs.
    import gradio as gr
    
    with gr.Blocks() as demo:
        name = gr.Textbox(label="Name")
        output = gr.Textbox(label="Output")
        greet_btn = gr.Button("Greet")
    
        greet_btn.click(fn=greet, inputs=name, outputs=output)
    
    def greet(name):
        return f"Hello {name}!"
    
    demo.launch()
  8. How Gradio's queueing system works

    main

    Gradio includes a built-in queuing system that processes requests in order using Server-Side Events (SSE). SSE is used instead of standard HTTP POST to prevent timeouts during long-running inference and to allow the server to send real-time updates (like ETAs) to the frontend.

    By default, Gradio uses a single-function-single-worker model. This means if you have multiple functions (e.g., A, B, and C), Gradio assigns one worker per function type to prevent resource exhaustion (like Out-of-Memory errors). For example, if requests for function A arrive, they will wait for a worker currently assigned to function A to become free before being processed.

    import gradio as gr
    
    app = gr.Interface(lambda x:x, "image", "image")
    app.queue()  # Sets up a queue with default parameters
    app.launch()
  9. Understand the Workflow JSON format

    main

    A workflow JSON file consists of three main collections and an edges list:

    • references: Input nodes (e.g., uploaded files, editable text, literal values).
    • operators: Processing steps (e.g., Spaces, models, datasets, or Python functions).
    • subjects: Output nodes (the results being created).

    Operator Kinds

    kindDescription
    "space"A Gradio Space on the Hub via gradio_client. Requires space_id and endpoint.
    "model"A Hugging Face model via InferenceClient. Requires model_id and a supported endpoint (e.g., text_to_image).
    "dataset"A Hub dataset. Requires dataset_id, dataset_config, and dataset_split.
    "fn"A Python function whose fn value matches a key in bind=.

    Supported Port Types

    image, audio, video, text, number, boolean, gallery, file, json, model3d, any (fallback).

    {
      "schema_version": "2",
      "name": "My Pipeline",
      "references": [
        {
          "id": "ref_prompt", "label": "Prompt", "role": "reference",
          "asset_type": "text",
          "inputs":  [{"id": "in", "label": "Text", "type": "text"}],
          "outputs": [{"id": "out", "label": "Text", "type": "text"}]
        }
      ],
      "operators": [
        {
          "id": "op_flux", "label": "FLUX.1", "role": "operator",
          "kind": "model",
          "model_id": "black-forest-labs/FLUX.1-schnell",
          "endpoint": "text_to_image",
          "pipeline_tag": "text-to-image",
          "inputs":  [{"id": "prompt", "label": "Prompt", "type": "text", "required": true}],
          "outputs": [{"id": "out_0", "label": "Image", "type": "image", "output_index": 0}]
        }
      ],
      "subjects": [
        {
          "id": "sub_img", "label": "Output Image", "role": "subject",
          "asset_type": "image",
          "inputs":  [{"id": "in", "label": "Image", "type": "image"}],
          "outputs": [{"id": "out", "label": "Image", "type": "image"}]
        }
      ],
      "edges": [
        {
          "id": "e1",
          "from_node_id": "ref_prompt", "from_port_id": "out",
          "to_node_id":   "op_flux",    "to_port_id":   "prompt",
          "type": "text"
        },
        {
          "id": "e2",
          "from_node_id": "op_flux", "from_port_id": "out_0",
          "to_node_id":   "sub_img", "to_port_id":   "in",
          "type": "image"
        }
      ]
    }
  10. Configure file access security in Gradio

    main

    When sharing a Gradio application (via Spaces, a local server, or a temporary share link), users can access certain files on your host machine. Gradio implements security boundaries to prevent unauthorized access to your filesystem.

    Accessible Files

    • Files in the script directory: Any file or subdirectory located in the same directory (or subdirectories) where your Gradio script is running is accessible. This allows you to easily reference local assets like images or videos for app examples.
    • Temporary files: Files created by Gradio during prediction (e.g., a video file returned by a function). You can customize the location of these files by setting the GRADIO_TEMP_DIR environment variable to an absolute path.
    • Allowed paths: Any directory or specific file path explicitly included in the allowed_paths parameter of the launch() method.

    Restricted Files (Blocked by default)

    • Dotfiles: Any file or directory starting with a . (e.g., .env, .git) is strictly inaccessible.
    • Blocked paths: Any directory or file path explicitly listed in the blocked_paths parameter of the launch() method. This parameter takes precedence over allowed_paths and default permissions.
    • Other host paths: Any path on the host machine not covered by the rules above is inaccessible.

    Note: Ensure you are running the latest version of gradio to ensure these security protections are active.

  11. Use Upload and ModifyUpload components for file handling

    main

    To allow users to upload files or replace existing ones, use the @gradio/upload package components:

    • Upload: Used to provide the initial upload area. It accepts props like filetype and file_count.
    • ModifyUpload: Used to show a 'clear' or 'replace' interface once a file is already loaded.

    Example logic in Svelte:

    {#if _value}
        <ModifyUpload i18n={gradio.i18n} absolute />
    {:else}
        <Upload
            filetype={"application/pdf"}
            file_count="single"
            {root}
        >
            Upload your PDF
        </Upload>
    {/if}