Gradio Python 客户端入门

标签:客户端,API,空间

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

The Gradio Python client makes it very easy to use any Gradio app as an API. As an example, consider this Hugging Face Space that transcribes audio files that are recorded from the microphone.

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

Using the gradio_client library, we can easily use the Gradio as an API to transcribe audio files programmatically.

这是执行此操作的完整代码:

Here's the entire code to do it:

from gradio_client import Client

client = Client("abidlabs/whisper") 
client.predict("audio_sample.wav")  

>> "This is a test of the whisper speech recognition model."

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

The Gradio client works with any hosted Gradio app, whether it be an image generator, a text summarizer, a stateful chatbot, a tax calculator, or anything else! The Gradio Client is mostly used with apps hosted on Hugging Face Spaces, but your app can be hosted anywhere, such as your own server.

前提条件:使用 Gradio 客户端不需要gradio 库有很详细的了解。 但是,大体熟悉 Gradio 的输入和输出组件概念会很有帮助。

Prerequisites: To use the Gradio client, you do not need to know the gradio library in great detail. However, it is helpful to have general familiarity with Gradio's concepts of input and output components.

安装

如果你已经拥有最新版本的 gradio ,那么 gradio_client 将作为依赖项包含在内。

If you already have a recent version of gradio, then the gradio_client is included as a dependency.

否则,轻量级的 gradio_client 包可以从 pip(或 pip3)安装,并经过测试可与 Python 3.9 或更高版本一起使用:

Otherwise, the lightweight gradio_client package can be installed from pip (or pip3) and is tested to work with Python versions 3.9 or higher:

$ pip install gradio_client

连接到正在运行的 Gradio 应用程序

首先连接实例化一个 Client 对象,并将其连接到在 Hugging Face Spaces 上或通常在网络上的任何地方运行的 Gradio 应用程序。

Start by connecting instantiating a Client object and connecting it to a Gradio app that is running on Hugging Face Spaces or generally anywhere on the web.

连接到拥抱面空间

from gradio_client import Client

client = Client("abidlabs/en2fr")  # a Space that translates from English to French

你还可以通过使用 hf_token 参数传入你的 HF 令牌来连接到私有空间。 你可以在这里获取你的 HF 代币: https ://huggingface.co/settings/tokens

You can also connect to private Spaces by passing in your HF token with the hf_token parameter. You can get your HF token here: https://huggingface.co/settings/tokens

from gradio_client import Client

client = Client("abidlabs/my-private-space", hf_token="...") 

复制空间供私人使用

虽然你可以将任何公共空间用作 API,但如果你发出太多请求,你可能会受到 Hugging Face 的速率限制。 要无限使用空间,只需复制空间以创建一个私人空间,然后使用它来提出任意数量的请求!

While you can use any public Space as an API, you may get rate limited by Hugging Face if you make too many requests. For unlimited usage of a Space, simply duplicate the Space to create a private Space, and then use it to make as many requests as you'd like!

gradio_client 包含一个类方法: Client.duplicate() 以简化此过程(你需要传入你的Hugging Face 令牌或使用 Hugging Face CLI 登录):

The gradio_client includes a class method: Client.duplicate() to make this process simple (you'll need to pass in your Hugging Face token or be logged in using the Hugging Face CLI):

import os
from gradio_client import Client

HF_TOKEN = os.environ.get("HF_TOKEN")

client = Client.duplicate("abidlabs/whisper", hf_token=HF_TOKEN) 
client.predict("audio_sample.wav")  

>> "This is a test of the whisper speech recognition model."

如果你之前复制过一个空间,重新运行 duplicate()不会创建一个新空间。 相反,客户端将附加到先前创建的空间。 所以多次重新运行 Client.duplicate() 方法是安全的。

If you have previously duplicated a Space, re-running duplicate() will not create a new Space. Instead, the Client will attach to the previously-created Space. So it is safe to re-run the Client.duplicate() method multiple times.

注意:如果原始 Space 使用 GPU,你的私人空间也会使用 GPU,并且你的 Hugging Face 帐户将根据 GPU 的价格进行计费。 为最大程度地减少费用,你的空间将在闲置 1 小时后自动进入休眠状态。 你还可以使用 duplicate()hardware 参数设置硬件。

Note: if the original Space uses GPUs, your private Space will as well, and your Hugging Face account will get billed based on the price of the GPU. To minimize charges, your Space will automatically go to sleep after 1 hour of inactivity. You can also set the hardware using the hardware parameter of duplicate().

连接通用的 Gradio 应用程序

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

If your app is running somewhere else, just provide the full URL instead, including the "http://" or "https://". Here's an example of making predictions to a Gradio app that is running on a share URL:

from gradio_client import Client

client = Client("https://bec81a83-5b5c-471e.gradio.live")

检查 API 端点

连接到 Gradio 应用程序后,你可以通过调用 Client.view_api() 方法查看可用的 API。 对于耳语空间,我们看到以下内容:

Once you have connected to a Gradio app, you can view the APIs that are available to you by calling the Client.view_api() method. For the Whisper Space, we see the following:

Client.predict() Usage Info
---------------------------
Named API endpoints: 1

 - predict(input_audio, api_name="/predict") -> value_0
    Parameters:
     - [Audio] input_audio: str (filepath or URL)
    Returns:
     - [Textbox] value_0: str (value)

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

This shows us that we have 1 API endpoint in this space, and shows us how to use the API endpoint to make a prediction: we should call the .predict() method (which we will explore below), providing a parameter input_audio of type str, which is a filepath or URL.

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

We should also provide the api_name='/predict' argument to the predict() method. Although this isn't necessary if a Gradio app has only 1 named endpoint, it does allow us to call different endpoints in a single app if they are available. If an app has unnamed API endpoints, these can also be displayed by running .view_api(all_endpoints=True).

做出预测

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

The simplest way to make a prediction is simply to call the .predict() function with the appropriate arguments:

from gradio_client import Client

client = Client("abidlabs/en2fr", api_name='/predict')
client.predict("Hello")

>> Bonjour

如果有多个参数,则应将它们作为单独的参数传递给 .predict() ,如下所示:

If there are multiple parameters, then you should pass them as separate arguments to .predict(), like this:

from gradio_client import Client

client = Client("gradio/calculator")
client.predict(4, "add", 5)

>> 9.0

对于某些输入,例如图像,你应该将文件路径或 URL 传递给文件。 同样,对于相应的输出类型,你将获得返回的文件路径或 URL。

For certain inputs, such as images, you should pass in the filepath or URL to the file. Likewise, for the corresponding output types, you will get a filepath or URL returned.

from gradio_client import Client

client = Client("abidlabs/whisper")
client.predict("https://audio-samples.github.io/samples/mp3/blizzard_unconditional/sample-0.mp3")

>> "My thought I have nobody by a beauty and will as you poured. Mr. Rochester is serve in that so don't find simpus, and devoted abode, to at might in a r—"

异步运行作业

Oe 应该注意 .predict() 是一个阻塞操作,因为它在返回预测之前等待操作完成。

Oe should note that .predict() is a blocking operation as it waits for the operation to complete before returning the prediction.

在许多情况下,你最好让作业在后台运行,直到你需要预测结果为止。 为此,你可以使用 .submit() 方法创建一个 Job 实例,然后在作业上调用 .result() 来获取结果。 例如:

In many cases, you may be better off letting the job run in the background until you need the results of the prediction. You can do this by creating a Job instance using the .submit() method, and then later calling .result() on the job to get the result. For example:

from gradio_client import Client

client = Client(space="abidlabs/en2fr")
job = client.submit("Hello", api_name="/predict")  # This is not blocking

# Do something else

job.result()  # This is blocking

>> Bonjour

添加回调

或者,可以添加一个或多个回调以在作业完成运行后执行操作,如下所示:

Alternatively, one can add one or more callbacks to perform actions after the job has completed running, like this:

from gradio_client import Client

def print_result(x):
    print("The translated result is: {x}")

client = Client(space="abidlabs/en2fr")

job = client.submit("Hello", api_name="/predict", result_callbacks=[print_result])

# Do something else

>> The translated result is: Bonjour

地位

Job 对象还允许你通过调用 .status() 方法来获取正在运行的作业的状态。 这将返回一个具有以下属性的 StatusUpdate 对象: code (状态代码,代表状态的一组已定义字符串之一。请参阅 utils.Status 类)、 rank (此作业在队列中的当前位置)、 queue_size (总队列大小)、 eta (此作业完成的估计时间)、 success (表示作业是否成功完成的布尔值)和 time (生成状态的时间)。

The Job object also allows you to get the status of the running job by calling the .status() method. This returns a StatusUpdate object with the following attributes: code (the status code, one of a set of defined strings representing the status. See the utils.Status class), rank (the current position of this job in the queue), queue_size (the total queue size), eta (estimated time this job will complete), success (a boolean representing whether the job completed successfully), and time (the time that the status was generated).

from gradio_client import Client

client = Client(src="gradio/calculator")
job = client.submit(5, "add", 4, api_name="/predict")
job.status()

>> 

注意Job 类还有一个 .done() 实例方法,它返回一个布尔值,指示作业是否已完成。

Note: The Job class also has a .done() instance method which returns a boolean indicating whether the job has completed.

取消作业

Job 类还有一个 .cancel() 实例方法,用于取消已排队但尚未启动的作业。 例如,如果你运行:

The Job class also has a .cancel() instance method that cancels jobs that have been queued but not started. For example, if you run:

client = Client("abidlabs/whisper") 
job1 = client.submit("audio_sample1.wav")  
job2 = client.submit("audio_sample2.wav")  
job1.cancel()  # will return False, assuming the job has started
job2.cancel()  # will return True, indicating that the job has been canceled

如果第一个作业已开始处理,则不会取消。 如果第二个作业还没有开始,它会被成功取消并从队列中移除。

If the first job has started processing, then it will not be canceled. If the second job has not yet started, it will be successfully canceled and removed from the queue.

生成器端点

一些 Gradio API 端点不返回单个值,而是返回一系列值。 你可以通过运行 job.outputs() 获取随时从此类生成器端点返回的一系列值:

Some Gradio API endpoints do not return a single value, rather they return a series of values. You can get the series of values that have been returned at any time from such a generator endpoint by running job.outputs():

from gradio_client import Client

client = Client(src="gradio/count_generator")
job = client.submit(3, api_name="/count")
while not job.done():
    time.sleep(0.1)
job.outputs()

>> ['0', '1', '2']

请注意,在生成器端点上运行 job.result() 只会为你提供端点返回的第一个值。

Note that running job.result() on a generator endpoint only gives you the first value returned by the endpoint.

Job 对象也是可迭代的,这意味着你可以使用它来显示从端点返回的生成器函数的结果。 下面是使用 Job 作为生成器的等效示例:

The Job object is also iterable, which means you can use it to display the results of a generator function as they are returned from the endpoint. Here's the equivalent example using the Job as a generator:

from gradio_client import Client

client = Client(src="gradio/count_generator")
job = client.submit(3, api_name="/count")

for o in job:
    print(o)

>> 0
>> 1
>> 2

你还可以取消具有迭代输出的作业,在这种情况下,作业将在当前迭代完成运行后立即完成。

You can also cancel jobs that that have iterative outputs, in which case the job will finish as soon as the current iteration finishes running.

from gradio_client import Client
import time

client = Client("abidlabs/test-yield")
job = client.submit("abcdef")
time.sleep(3)
job.cancel()  # job cancels after 2 iterations