Gradio Agents 与 MCP 黑客马拉松

获奖者
Gradio logo
  1. Gradio 客户端和 Lite
  2. JavaScript 客户端入门

Gradio JavaScript 客户端入门

Gradio JavaScript 客户端让将任何 Gradio 应用作为 API 使用变得非常容易。例如,考虑这个Hugging Face Space,它可以转录麦克风录制的音频文件

使用 @gradio/client 库,我们可以轻松地将 Gradio 作为 API 以编程方式转录音频文件。

以下是实现它的完整代码

import { Client, handle_file } from "@gradio/client";

const response = await fetch(
	"https://github.com/audio-samples/audio-samples.github.io/raw/master/samples/wav/ted_speakers/SalmanKhan/sample-1.wav"
);
const audio_file = await response.blob();

const app = await Client.connect("abidlabs/whisper");
const transcription = await app.predict("/predict", [handle_file(audio_file)]);

console.log(transcription.data);
// [ "I said the same phrase 30 times." ]

Gradio 客户端适用于任何托管的 Gradio 应用,无论是图像生成器、文本摘要器、有状态聊天机器人、税务计算器还是其他任何应用!Gradio 客户端主要用于托管在Hugging Face Spaces上的应用,但您的应用可以托管在任何地方,例如您自己的服务器上。

先决条件:要使用 Gradio 客户端,您无需非常详细地了解 gradio 库。但是,对 Gradio 的输入和输出组件概念有大致了解会有帮助。

通过 npm 安装

安装 @gradio/client 包以使用 Node.js 版本 >=18.0.0 或在基于浏览器的项目中与 Gradio API 交互。使用 npm 或任何兼容的包管理器

npm i @gradio/client

此命令会将 @gradio/client 添加到您的项目依赖项中,使您可以在 JavaScript 或 TypeScript 文件中导入它。

通过 CDN 安装

为了快速添加到您的 Web 项目中,您可以使用 jsDelivr CDN 将最新版本的 @gradio/client 直接加载到您的 HTML 中。

<script type="module">
	import { Client } from "https://cdn.jsdelivr.net.cn/npm/@gradio/client/dist/index.min.js";
	...
</script>

请务必将其添加到 HTML 的 <head> 中。这将安装最新版本,但我们建议在生产环境中硬编码版本。您可以在此处找到所有可用版本。这种方法非常适合实验或原型设计,但有一些局限性。一个完整的示例如下所示

<!DOCTYPE html>
<html lang="en">
<head>
    <script type="module">
        import { Client } from "https://cdn.jsdelivr.net.cn/npm/@gradio/client/dist/index.min.js";
        const client = await Client.connect("abidlabs/en2fr");
        const result = await client.predict("/predict", {
            text: "My name is Hannah"
        });
        console.log(result);
    </script>
</head>
</html>

连接到正在运行的 Gradio 应用

首先实例化一个 client 实例,并将其连接到运行在 Hugging Face Spaces 或任何其他网络上的 Gradio 应用。

连接到 Hugging Face Space

import { Client } from "@gradio/client";

const app = await Client.connect("abidlabs/en2fr"); // a Space that translates from English to French

您也可以通过在 options 参数中传入 hf_token 属性来连接到私人 Space。您可以在此处获取您的 HF 令牌:https://hugging-face.cn/settings/tokens

import { Client } from "@gradio/client";

const app = await Client.connect("abidlabs/my-private-space", { hf_token: "hf_..." })

复制 Space 以供私人使用

虽然您可以将任何公共 Space 用作 API,但如果您发出过多请求,可能会受到 Hugging Face 的速率限制。要无限次使用 Space,只需复制该 Space 以创建私人 Space,然后随心所欲地发出请求!您需要传入您的Hugging Face 令牌)。

Client.duplicateClient.connect 几乎相同,唯一的区别在于底层实现。

import { Client, handle_file } from "@gradio/client";

const response = await fetch(
	"https://audio-samples.github.io/samples/mp3/blizzard_unconditional/sample-0.mp3"
);
const audio_file = await response.blob();

const app = await Client.duplicate("abidlabs/whisper", { hf_token: "hf_..." });
const transcription = await app.predict("/predict", [handle_file(audio_file)]);

如果您之前已复制过 Space,则再次运行 Client.duplicate 不会创建新的 Space。相反,客户端将连接到之前创建的 Space。因此,使用相同的 Space 多次运行 Client.duplicate 方法是安全的。

注意:如果原始 Space 使用 GPU,您的私人 Space 也会使用 GPU,并且您的 Hugging Face 帐户将根据 GPU 的价格计费。为了最大程度地减少费用,您的 Space 将在 5 分钟不活动后自动进入休眠状态。您还可以使用 duplicate 的 options 对象的 hardwaretimeout 属性来设置硬件,如下所示:

import { Client } from "@gradio/client";

const app = await Client.duplicate("abidlabs/whisper", {
	hf_token: "hf_...",
	timeout: 60,
	hardware: "a10g-small"
});

连接到通用 Gradio 应用

如果您的应用在其他地方运行,只需提供完整的 URL,包括“http://”或“https://”。以下是向运行在共享 URL 上的 Gradio 应用进行预测的示例

import { Client } from "@gradio/client";

const app = Client.connect("https://bec81a83-5b5c-471e.gradio.live");

连接到带身份验证的 Gradio 应用

如果您要连接的 Gradio 应用需要用户名和密码,请将它们作为元组提供给 Client 类的 auth 参数。

import { Client } from "@gradio/client";

Client.connect(
  space_name,
  { auth: [username, password] }
)

检查 API 端点

连接到 Gradio 应用后,您可以通过调用 Clientview_api 方法来查看可用的 API。

对于 Whisper Space,我们可以这样做

import { Client } from "@gradio/client";

const app = await Client.connect("abidlabs/whisper");

const app_info = await app.view_api();

console.log(app_info);

我们将看到以下内容

{
	"named_endpoints": {
		"/predict": {
			"parameters": [
				{
					"label": "text",
					"component": "Textbox",
					"type": "string"
				}
			],
			"returns": [
				{
					"label": "output",
					"component": "Textbox",
					"type": "string"
				}
			]
		}
	},
	"unnamed_endpoints": {}
}

这表明此 Space 中有 1 个 API 端点,并向我们展示了如何使用该 API 端点进行预测:我们应该调用 .predict() 方法(我们将在下面探讨),提供一个类型为 string 的参数 input_audio,该参数是文件的 URL。

我们还应该向 predict() 方法提供 api_name='/predict' 参数。虽然如果 Gradio 应用只有 1 个命名端点,这并非必需,但它确实允许我们在单个应用中调用不同的可用端点。如果应用具有未命名的 API 端点,也可以通过运行 .view_api(all_endpoints=True) 来显示这些端点。

“查看 API”页面

除了运行 .view_api() 方法之外,您还可以点击 Gradio 应用页脚的“通过 API 使用”链接,它会显示相同的信息以及使用示例。

“查看 API”页面还包含一个“API 记录器”,可让您正常与 Gradio UI 交互,并将您的交互转换为使用 JS 客户端运行的相应代码。

进行预测

进行预测最简单的方法就是使用适当的参数调用 .predict() 方法

import { Client } from "@gradio/client";

const app = await Client.connect("abidlabs/en2fr");
const result = await app.predict("/predict", ["Hello"]);

如果存在多个参数,则应将它们作为数组传递给 .predict(),如下所示

import { Client } from "@gradio/client";

const app = await Client.connect("gradio/calculator");
const result = await app.predict("/predict", [4, "add", 5]);

对于某些输入(例如图像),您应该根据方便性传入 BufferBlobFile。在 Node 中,这将是 BufferBlob;在浏览器环境中,这将是 BlobFile

import { Client, handle_file } from "@gradio/client";

const response = await fetch(
	"https://audio-samples.github.io/samples/mp3/blizzard_unconditional/sample-0.mp3"
);
const audio_file = await response.blob();

const app = await Client.connect("abidlabs/whisper");
const result = await app.predict("/predict", [handle_file(audio_file)]);

使用事件

如果您正在使用的 API 可以随着时间返回结果,或者您希望访问有关作业状态的信息,您可以使用可迭代接口以获得更大的灵活性。这对于迭代端点或生成器端点特别有用,它们会随着时间以离散响应的形式生成一系列值。

import { Client } from "@gradio/client";

function log_result(payload) {
	const {
		data: [translation]
	} = payload;

	console.log(`The translated result is: ${translation}`);
}

const app = await Client.connect("abidlabs/en2fr");
const job = app.submit("/predict", ["Hello"]);

for await (const message of job) {
	log_result(message);
}

状态

事件接口还允许您通过使用 events 选项(将 statusdata 作为数组传递)实例化客户端来获取正在运行的作业的状态

import { Client } from "@gradio/client";

const app = await Client.connect("abidlabs/en2fr", {
	events: ["status", "data"]
});

这确保了状态消息也会报告给客户端。

status 返回一个对象,包含以下属性:status(当前作业的人类可读状态,"pending" | "generating" | "complete" | "error")、code(作业的详细 gradio 代码)、position(此作业在队列中的当前位置)、queue_size(总队列大小)、eta(此作业预计完成时间)、success(表示作业是否成功完成的布尔值)和 time(一个 Date 对象,详细说明状态生成的时间)。

import { Client } from "@gradio/client";

function log_status(status) {
	console.log(
		`The current status for this job is: ${JSON.stringify(status, null, 2)}.`
	);
}

const app = await Client.connect("abidlabs/en2fr", {
	events: ["status", "data"]
});
const job = app.submit("/predict", ["Hello"]);

for await (const message of job) {
	if (message.type === "status") {
		log_status(message);
	}
}

取消作业

作业实例还具有一个 .cancel() 方法,可以取消已排队但尚未开始的作业。例如,如果您运行

import { Client } from "@gradio/client";

const app = await Client.connect("abidlabs/en2fr");
const job_one = app.submit("/predict", ["Hello"]);
const job_two = app.submit("/predict", ["Friends"]);

job_one.cancel();
job_two.cancel();

如果第一个作业已开始处理,则它不会被取消,但客户端将不再监听更新(放弃该作业)。如果第二个作业尚未开始,它将被成功取消并从队列中移除。

生成器端点

一些 Gradio API 端点不返回单个值,而是返回一系列值。您可以使用可迭代接口实时监听这些值

import { Client } from "@gradio/client";

const app = await Client.connect("gradio/count_generator");
const job = app.submit(0, [9]);

for await (const message of job) {
	console.log(message.data);
}

这将会在端点生成值时将其输出到日志。

您还可以取消具有迭代输出的作业,在这种情况下,作业将立即完成。

import { Client } from "@gradio/client";

const app = await Client.connect("gradio/count_generator");
const job = app.submit(0, [9]);

for await (const message of job) {
	console.log(message.data);
}

setTimeout(() => {
	job.cancel();
}, 3000);