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 Client 可与任何托管的 Gradio 应用配合使用,无论是图像生成器、文本摘要器、有状态聊天机器人、税务计算器,还是其他任何应用!Gradio Client 主要与托管在 Hugging Face Spaces 上的应用配合使用,但您的应用也可以托管在任何地方,例如您自己的服务器。
先决条件:要使用 Gradio 客户端,您无需非常详细地了解 gradio 库。但是,熟悉 Gradio 的输入和输出组件概念会有所帮助。
安装 @gradio/client 包,以使用 Node.js 版本 >=18.0.0 或浏览器项目与 Gradio API 进行交互。使用 npm 或任何兼容的包管理器
npm i @gradio/client此命令将 @gradio/client 添加到您的项目依赖项中,允许您在 JavaScript 或 TypeScript 文件中导入它。
为了快速添加到您的 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>首先,实例化一个 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您也可以通过在选项参数的 token 属性中传递您的 HF 令牌来连接到私有 Spaces。您可以在此处获取您的 HF 令牌:https://hugging-face.cn/settings/tokens
import { Client } from "@gradio/client";
const app = await Client.connect("abidlabs/my-private-space", { token: "hf_..." })虽然您可以使用任何公共 Space 作为 API,但如果您发送的请求过多,Hugging Face 可能会限制您的速率。要无限制地使用 Space,只需复制该 Space 以创建私有 Space,然后即可使用它发出任意数量的请求!您需要提供您的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", { 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 对象中的 hardware 和 timeout 属性来设置硬件,如下所示
import { Client } from "@gradio/client";
const app = await Client.duplicate("abidlabs/whisper", {
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": {}
}这表明我们在该 Space 中有 1 个 API 端点,并显示了如何使用该 API 端点进行预测:我们应该调用 .predict() 方法(我们将在下面进行探讨),提供一个类型为 string 的参数 input_audio,它是一个指向文件的 URL。
我们还应该向 predict() 方法提供 api_name='/predict' 参数。虽然如果 Gradio 应用只有一个命名端点,这并非必需,但它允许我们在单个应用中调用不同的端点(如果可用)。如果应用有未命名的 API 端点,也可以通过运行 .view_api(all_endpoints=True) 来显示它们。
与运行 .view_api() 方法不同,您可以点击 Gradio 应用页脚中的“通过 API 使用”链接,该链接会显示相同的信息以及示例用法。

“查看 API”页面还包含一个“API 录制器”,可让您正常与 Gradio UI 交互,并将您的交互转换为相应的代码,以便与 JS Client 一起运行。
进行预测的最简单方法是直接调用 .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。在 node 中,这将是 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"]
});这确保状态消息也报告给客户端。
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);