Gradio Agents & MCP 黑客马拉松

获奖者
Gradio logo
  1. 自定义组件
  2. 核心组件概念

Gradio 组件:核心概念

在本节中,我们将讨论 Gradio 组件的一些重要概念。在开发您自己的组件时,理解这些概念非常重要。否则,您的组件可能会与其他 Gradio 组件表现出非常不同的行为!

提示: 如果您熟悉 Gradio 库的内部工作原理,例如每个组件的 `preprocess` 和 `postprocess` 方法,则可以跳过本节。

交互式与静态

Gradio 中的每个组件都有一个 static 变体,并且大多数组件也有一个 interactive 版本。static 版本用于组件显示值但用户**无法**通过交互来更改该值的情况。interactive 版本用于用户能够通过与 Gradio UI 交互来更改值的情况。

我们来看一些示例

import gradio as gr

with gr.Blocks() as demo:
   gr.Textbox(value="Hello", interactive=True)
   gr.Textbox(value="Hello", interactive=False)

demo.launch()

这将显示两个文本框。唯一的区别是:您将能够编辑顶部 Gradio 组件的值,而无法编辑底部变体的值(即,文本框将被禁用)。

一个更有趣的示例可能是 Image 组件

import gradio as gr

with gr.Blocks() as demo:
   gr.Image(interactive=True)
   gr.Image(interactive=False)

demo.launch()

该组件的交互式版本要复杂得多——您可以上传图片或从网络摄像头拍照——而静态版本只能用于显示图片。

并非每个组件都有独特的交互式版本。例如,gr.AnnotatedImage 只作为静态版本出现,因为无法交互式地更改标注或图像的值。

你需要记住什么

  • 如果组件用作任何事件的**输入**,Gradio 将使用该组件的交互式版本(如果可用);否则,将使用静态版本。

  • 当您设计自定义组件时,您**必须**在 Python 类的构造函数中接受布尔型 `interactive` 关键字。在前端,您**可以**接受 `interactive` 属性,这是一个 `bool` 类型的值,表示组件应该是静态的还是交互式的。如果您在前端不使用此属性,则组件在交互式或静态模式下将显示相同。

值以及如何进行预处理/后处理

组件最重要的属性是其 value。每个组件都有一个 value。这个值通常由用户在前端设置(如果组件是交互式的),或者显示给用户(如果是静态的)。当用户触发事件时,或者在预测结束时由用户函数返回时,也是这个值被发送到后端函数。

因此,这个值会频繁传递,但有时值在前端和后端之间需要改变格式。请看这个示例

import numpy as np
import gradio as gr

def sepia(input_img):
    sepia_filter = np.array([
        [0.393, 0.769, 0.189], 
        [0.349, 0.686, 0.168], 
        [0.272, 0.534, 0.131]
    ])
    sepia_img = input_img.dot(sepia_filter.T)
    sepia_img /= sepia_img.max()
    return sepia_img

demo = gr.Interface(sepia, gr.Image(width=200, height=200), "image")
demo.launch()

这将创建一个 Gradio 应用程序,其输入和输出都是 Image 组件。在前端,Image 组件实际上会将文件**上传**到服务器并发送**文件路径**,但在此文件路径发送到用户函数之前,它会被转换为 numpy 数组。反之,当用户函数返回一个 numpy 数组时,该 numpy 数组会被转换为文件,以便发送到前端并由 Image 组件显示。

提示: 默认情况下,Image 组件会将 NumPy 数组发送到 Python 函数,因为这是机器学习工程师的常见选择,不过 Image 组件也支持使用 type 参数的其他格式。在此处阅读 Image 文档以了解更多信息。

每个组件执行两种转换

  1. preprocess:将 value 从前端发送的格式转换为 Python 函数期望的格式。这通常涉及将 Web 友好的 **JSON** 结构转换为**Python 原生**数据结构,例如 numpy 数组或 PIL 图像。AudioImage 组件是 preprocess 方法的良好示例。

  2. postprocess:将 Python 函数返回的值转换为前端期望的格式。这通常涉及将**Python 原生**数据结构(例如 PIL 图像)转换为 **JSON** 结构。

你需要记住什么

  • 每个组件都必须实现 preprocesspostprocess 方法。在极少数不需要进行转换的情况下,只需原样返回该值即可。TextboxNumber 就是这方面的例子。

  • 作为组件作者,**您**控制前端显示的数据格式以及使用您组件的用户将接收到的数据格式。请考虑一种 **Python** 开发人员会觉得直观的人体工程学数据结构,并使用 preprocesspostprocess 控制从**Web 友好型 JSON** 数据结构(反之亦然)的转换。

组件的“示例版本”

Gradio 应用程序支持提供示例输入——这对于帮助用户开始使用您的 Gradio 应用程序非常有用。在 gr.Interface 中,您可以使用 examples 关键字提供示例;在 Blocks 中,您可以使用特殊的 gr.Examples 组件提供示例。

在此屏幕截图底部,我们展示了一张微型猎豹示例图片,点击后,它将在输入图像组件中填充相同的图片。

img

要启用示例视图,您必须在 frontend 目录的顶部包含以下两个文件:

  • Example.svelte:这对应于您组件的“示例版本”
  • Index.svelte:这对应于“常规版本”

在后端,您通常不需要做任何事情。用户提供的示例 value 使用前面描述的相同 .postprocess() 方法进行处理。如果您想以不同方式处理数据(例如,如果 .postprocess() 方法计算成本很高),那么您可以为您的自定义组件编写自己的 .process_example() 方法,它将被替代使用。

Example.svelte 文件和 process_example() 方法将在专门的前端后端指南中更深入地介绍。

你需要记住什么

  • 如果您希望您的组件用作输入,定义一个“示例”视图非常重要。
  • 如果您不定义,Gradio 将使用默认视图,但它不会像它本来可以的那样具有信息性!

总结

既然您已经了解了 Gradio 组件最重要的部分,就可以开始设计和构建您自己的组件了!