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的输入和输出组件概念有一定的熟悉会有所帮助。
安装 @gradio/client 包以使用 Node.js 版本 >=18.0.0 或在基于浏览器的项目中与 Gradio API 进行交互。使用 npm 或任何兼容的包管理器:
npm i @gradio/client此命令将@gradio/client添加到您的项目依赖项中,允许您在JavaScript或TypeScript文件中导入它。
为了快速添加到您的网页项目中,您可以使用 jsDelivr CDN 将最新版本的 @gradio/client 直接加载到您的 HTML 中:
<script type="module">
import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
...
</script>请确保将此添加到HTML的
部分。这将安装最新版本,但我们建议在生产环境中硬编码版本号。您可以在此找到所有可用版本here。这种方法非常适合实验或原型设计目的,尽管有一些限制。一个完整的示例如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module">
import { Client } from "https://cdn.jsdelivr.net/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>首先通过实例化一个client实例并将其连接到在Hugging Face Spaces上或通常在任何地方运行的Gradio应用程序。
import { Client } from "@gradio/client";
const app = await Client.connect("abidlabs/en2fr"); // a Space that translates from English to French您还可以通过在选项参数的hf_token属性中传递您的HF令牌来连接到私有空间。您可以在此处获取您的HF令牌:https://huggingface.co/settings/tokens
import { Client } from "@gradio/client";
const app = await Client.connect("abidlabs/my-private-space", { hf_token: "hf_..." })虽然您可以使用任何公共空间作为API,但如果请求过多,可能会被Hugging Face限速。要无限制地使用空间,只需复制该空间以创建私有空间,然后使用它进行任意数量的请求!您需要传入您的Hugging Face令牌。
Client.duplicate 与 Client.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 选项对象中的 hardware 和 timeout 属性来设置硬件,如下所示:
import { Client } from "@gradio/client";
const app = await Client.duplicate("abidlabs/whisper", {
hf_token: "hf_...",
timeout: 60,
hardware: "a10g-small"
});如果你的应用程序在其他地方运行,只需提供完整的URL,包括“http://”或“https://”。以下是一个向运行在共享URL上的Gradio应用程序进行预测的示例:
import { Client } from "@gradio/client";
const app = Client.connect("https://bec81a83-5b5c-471e.gradio.live");如果您连接的Gradio应用程序需要用户名和密码,则将它们作为元组提供给Client类的auth参数:
import { Client } from "@gradio/client";
Client.connect(
space_name,
{ auth: [username, password] }
)一旦你连接到一个Gradio应用,你可以通过调用Client的view_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": {}
}这表明我们在这个空间中有1个API端点,并展示了如何使用该API端点进行预测:我们应该调用.predict()方法(我们将在下面探讨),提供一个类型为string的参数input_audio,这是一个文件的URL。
我们还应该向predict()方法提供api_name='/predict'参数。虽然如果Gradio应用程序只有一个命名的端点,这不是必需的,但它确实允许我们在单个应用程序中调用不同的端点(如果它们可用)。如果应用程序有未命名的API端点,也可以通过运行.view_api(all_endpoints=True)来显示这些端点。
作为运行.view_api()方法的替代方案,您可以点击Gradio应用页脚中的“通过API使用”链接,该链接向我们展示了相同的信息以及示例用法。

View 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]);对于某些输入,如图像,您应根据最方便的情况传入Buffer、Blob或File。在节点环境中,这将是Buffer或Blob;在浏览器环境中,这将是Blob或File。
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选项实例化客户端来获取正在运行的作业的状态,传递status和data作为数组:
import { Client } from "@gradio/client";
const app = await Client.connect("abidlabs/en2fr", {
events: ["status", "data"]
});这确保了状态消息也会报告给客户端。
statuses 作为具有以下属性的对象返回: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);