gradio_client 使用指南:用 3 行 Python 把任何 Gradio 应用变成 API
gradio_client 是 Gradio 官方推出的轻量级 Python 客户端库,它让你可以像调用本地函数一样调用任何运行中的 Gradio 应用(无论是 Hugging Face Space 上托管的、还是通过 share URL 临时分享的应用),把训练好的机器学习模型、有状态的聊天机器人、图像生成器等统一封装成远程 API。读完本文,你将掌握如何用 Client 对象连接 Gradio 应用、用 .view_api() 查看可用的 API 端点、用 .predict() / .submit() 完成同步与异步调用,以及通过 Client.duplicate() 复制一份属于自己的 Space 来绕开速率限制。
一、gradio_client 是什么
本仓库的 client/python/ 目录承载着 gradio_client 的完整源码。它是一个独立的、轻量的 Python 包,与完整的 gradio 框架解耦,专门负责"消费" Gradio 应用暴露的 API。
一个最直观的例子:假设有一个 Hugging Face Space 上的语音转文字应用(Whisper 模型),用 gradio_client 只需要三行代码即可完成一次音频转写:
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_client 都能以统一的方式与之交互。
从实现上看,包的公共 API 定义在 client/python/gradio_client/init.py,对外导出了 Client、file、handle_file、FileData 与 __version__ 五个核心成员。其中 Client 类是使用入口,负责连接远程应用、解析其配置并调度请求。
二、安装与依赖
gradio_client 的版本与 Python 要求可以在 client/python/pyproject.toml 中确认:requires-python = ">=3.10",即支持 Python 3.10 及以上版本,项目许可证为 Apache-2.0。
安装方式有两种:
- 如果你已经安装了较新版本的
gradio,gradio_client已经作为依赖被一并安装,无需额外操作; - 否则,通过 pip 单独安装这个轻量包:
$ pip install gradio_client
从 pyproject.toml 可以看到,包的核心依赖包括 httpx(HTTP 客户端)、huggingface_hub(Space 查找、复制、运行时状态查询)、fsspec 与 packaging 等,这些依赖支撑了客户端连接远程应用、处理文件传输与协议协商的全部能力。
三、基本用法
3.1 连接到一个 Space 或任意 Gradio 应用
创建 Client 对象时传入目标应用的地址即可完成连接,地址有两种形式:
连接 Hugging Face Space——直接使用 "用户名/空间名" 格式:
from gradio_client import Client
client = Client("abidlabs/en2fr") # 一个英译法的 Space
连接私有 Space——传入你的 Hugging Face Token(可在 https://huggingface.co/settings/tokens 获取):
from gradio_client import Client
client = Client("abidlabs/my-private-space", hf_token="...")
连接其他位置运行的 Gradio 应用——只要提供完整的 URL(包含 http:// 或 https://)即可,例如通过 share URL 临时分享的应用:
from gradio_client import Client
client = Client("https://bec81a83-5b5c-471e.gradio.live")
从 Client.init 的源码可以看到,除了上述用法,构造函数还支持更多底层参数:
| 参数 | 类型 | 默认值 | 作用 |
|---|---|---|---|
src |
str |
必填 | Space 名称(如 "abidlabs/whisper")或完整 URL(如 "http://mydomain.com/app") |
token |
str | None |
None |
访问私有 Space 用的 HF Token,默认使用本地已保存的 Token |
max_workers |
int |
40 |
同时向远程应用发起请求的最大线程数 |
verbose |
bool |
True |
是否在控制台打印信息 |
auth |
tuple[str, str] | None |
None |
以用户名/密码元组登录启用了认证的应用 |
headers |
dict[str, str] | None |
None |
每次请求附加的额外请求头,同名键会覆盖默认头 |
download_files |
str | Path | False |
GRADIO_TEMP_DIR |
输出文件下载到本地的目录;为 False 时不下载,返回 FileData 对象 |
ssl_verify |
bool |
True |
设为 False 可跳过证书校验,用于连接使用自签名证书的应用 |
httpx_kwargs |
dict | None |
None |
透传给 httpx.Client/httpx.stream/httpx.get/httpx.post 的额外参数,可设置超时、代理、HTTP 认证等 |
analytics_enabled |
bool |
True |
是否允许基础遥测 |
oauth_token |
str | None |
None |
代表你在应用内执行操作的 OAuth Token,仅发送给声明需要它的端点 |
连接建立后,客户端会做几件关键的事(见 client.py):若传入的是 Space 名称,会先解析出对应的 Space 地址并查询其运行时状态;如果 Space 仍在构建(BUILDING),会每隔 2 秒轮询等待;随后拉取应用的 config,根据配置中的 protocol 字段("ws"、"sse"、"sse_v1"、"sse_v2"、"sse_v2.1" 等)决定使用 WebSocket 还是 SSE 协议与队列通信,最后获取 API 元信息并建立端点映射。
3.2 复制一个 Space 供自己使用
任何公开 Space 都可以当作 API 使用,但如果请求过于频繁,可能会被 Hugging Face 限流。想要无限量使用,最直接的办法是把该 Space 复制一份到自己的账号下(默认创建为私有 Space),然后随意调用。
gradio_client 提供了类方法 Client.duplicate() 来简化这一过程:
from gradio_client import Client
client = Client.duplicate("abidlabs/whisper")
client.predict("audio_sample.wav")
>> "This is a test of the whisper speech recognition model."
duplicate() 是幂等的:如果你之前已经复制过该 Space,再次调用不会创建新 Space,而是直接挂载到之前创建的那份上,因此可以放心重复调用。
费用提醒:如果原 Space 使用 GPU,你的私有副本也会使用 GPU,并按 GPU 价格向你的 Hugging Face 账号计费。为了尽量降低费用,副本会在闲置 1 小时后自动休眠(sleep_timeout 参数可调,源码中默认 5 分钟);你也可以通过 hardware 参数显式指定硬件。
从 duplicate() 的实现可以看到完整流程:先通过 huggingface_hub.get_space_runtime 检查原 Space 是否存在;若目标副本已存在则复用并给出提示;否则调用 huggingface_hub.duplicate_space 创建副本,必要时写入 secrets 环境变量;随后按需通过 request_space_hardware 升级硬件、通过 utils.set_space_timeout 设置自动休眠时间,最后返回连接该副本的 Client 实例。其完整参数如下:
| 参数 | 类型 | 默认值 | 作用 |
|---|---|---|---|
from_id |
str |
必填 | 要复制的 Space,格式 "{用户名}/{空间名}" |
to_id |
str | None |
None |
新 Space 名称;不填则命名为 "{你的HF用户名}/{空间名}" |
token |
str | None |
None |
复制私有 Space 用的 HF Token |
private |
bool |
True |
新 Space 是否私有 |
hardware |
str | SpaceHardware | None |
原 Space 的硬件 | 硬件档位,可选 "cpu-basic"、"cpu-upgrade"、"t4-small"、"t4-medium"、"a10g-small"、"a10g-large"、"a100-large" 等 |
secrets |
dict[str, str] | None |
None |
传递给新 Space 的密钥字典,仅在首次创建副本时生效 |
sleep_timeout |
int |
5 |
副本无请求多少分钟后自动休眠(单位为分钟,源码中会换算为秒) |
max_workers |
int |
40 |
最大并发线程数 |
verbose |
bool |
True |
是否打印过程信息 |
3.3 查看应用的 API 端点
连接成功后,调用 .view_api() 即可查看该应用暴露了哪些 API 及各自用法。以 Whisper Space 为例,输出如下:
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)
这告诉我们:该 Space 有 1 个命名 API 端点,调用方式是调用 .predict(),传入类型为 str(文件路径或 URL)的参数 input_audio。同时应显式传入 api_name='/predict'——虽然当应用只有一个命名端点时并非必须,但当单个应用有多个端点时,它用于区分要调用哪个端点。
view_api() 的完整签名(见 client.py):
all_endpoints:为True时同时打印命名与未命名端点;默认(None)时只打印命名端点,若应用没有命名端点则自动展示未命名端点;print_info:是否打印到控制台;return_format:为"str"时返回将被打印的字符串;为"dict"时返回可编程解析的字典(该模式下无论all_endpoints取值如何,都会返回全部端点),字典包含named_endpoints与unnamed_endpoints两个键,每个端点下含parameters(含label、python_type、type_description、component、example_input等字段)与returns列表。
另外,若应用存在未命名端点,默认打印时会提示"要查看请运行 Client.view_api(all_endpoints=True)"。
3.4 发起预测调用
最直接的调用方式就是 .predict(),它会阻塞等待远程结果返回:
from gradio_client import Client
client = Client("abidlabs/en2fr")
client.predict("Hello")
>> Bonjour
当端点有多个参数时,按顺序依次传入即可:
from gradio_client import Client
client = Client("gradio/calculator")
client.predict(4, "add", 5)
>> 9.0
对于图片、音频等文件类输入,应传入本地文件路径或 URL;对应地,文件类输出也会以本地文件路径或 URL 的形式返回:
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. ..."
从 predict() 的实现可以看到,predict() 本质上是对 submit().result() 的封装。它支持的参数包括:
api_name:要调用的端点名,以斜杠开头(如"/predict");应用只有一个命名端点时可不传;fn_index:端点的索引(如0),作为api_name的替代;两者同时提供且冲突时以api_name为准;headers:本次请求额外附加的请求头,同名键会覆盖构造函数中设置的请求头;- 其余位置参数/关键字参数对应端点的输入(推荐使用关键字参数,源码中的
utils.construct_args会根据ParameterInfo做参数名匹配、默认值填充与缺失参数校验)。
四、进阶用法
4.1 用 submit() 做异步调用与状态跟踪
当预测耗时较长,或你需要监控任务状态、在结果就绪时执行回调时,应使用 .submit()。它返回一个在后台线程中执行的 Job 对象,不会阻塞主线程:
from gradio_client import Client
client = Client(src="gradio/calculator")
job = client.submit(5, "add", 4, api_name="/predict")
job.status()
>> <Status.STARTING: 'STARTING'>
job.result() # 阻塞直到拿到结果
>> 9.0
Job 类(定义于 client.py)是对 Python concurrent.futures.Future 的包装,除了 result() 之外还提供:
status():查询任务的当前状态(如STARTING、RUNNING、FINISHED等);- 可迭代性:
Job实现了__iter__/__next__/__aiter__,可以直接在for循环中消费生成器端点的阶段性输出; cancel():取消尚未完成的任务。
submit() 额外支持 result_callbacks 参数,可传入一个或一组回调函数,在结果就绪时按顺序调用(多个返回值会作为多个位置参数展开传入回调),非常适合把预测结果直接接入后续处理链路。predict() 与 submit() 在参数形式上保持一致,可以无缝互换。
4.2 文件上传与 handle_file()
向端点传入本地文件时,推荐使用 handle_file() 来构造文件数据:
from gradio_client import handle_file, Client
client = Client("abidlabs/whisper")
client.predict(handle_file("audio_sample.wav"))
handle_file() 的实现会构造一个带 gradio.FileData 元信息的字典:若传入的是 URL,会附带 orig_name 与 url 字段;若传入的是本地存在的路径,则附带本地文件名;两者都不是时抛出 ValueError。在较新版本中,file() 已标记为废弃(deprecated),应统一使用 handle_file()。
默认情况下,文件类输出会被下载到临时目录(由环境变量 GRADIO_TEMP_DIR 控制,未设置时为系统临时目录下的 gradio 子目录),并返回本地路径;若将 Client 的 download_files 参数设为 False,则不会下载文件,而是返回 FileData 数据类对象(定义于 data_classes.py,包含 name、data、size、orig_name、mime_type、is_stream 等字段),其中 data 字段保存 base64 编码的内容。
4.3 多端点应用的调用
当一个 Gradio 应用包含多个 API 端点时,用 api_name 区分即可;没有命名的端点则可以用 fn_index 指定其索引。.view_api(all_endpoints=True) 会列出所有命名与未命名端点及其索引,方便你确认正确的调用方式。值得说明的是,view_api(return_format="dict") 返回的字典中永远包含全部端点(不受 all_endpoints 影响),适合在程序中自动发现端点结构。
五、背后机制与测试佐证
gradio_client 与远程应用的通信建立在 Gradio 的队列协议之上。从 client.py 可以看到,客户端会根据应用 config 中的 protocol 字段选择通信方式,并据此构造 api/predict/、queue/join、upload、reset、cancel 等一系列内部端点 URL(这些常量定义在 utils.py)。请求在后台线程池中执行,通过 Job 包装,实现"提交即返回、结果异步取"的模型。
仓库中的测试为这些行为提供了可验证的依据:
- test_client.py 覆盖了端到端调用(如
test_space_with_files_v4_sse_v2、test_file_io)、文件下载(如test_download_private_file、test_download_stream_file_uses_url_directly)、duplicate()的 secret 注入(test_add_secrets)以及超大文件限制(test_raise_error_max_file_size)等场景; - test_utils.py 与 test_documentation.py 则分别验证了工具函数与文档生成逻辑。
六、总结
gradio_client 把"消费一个 Gradio 应用"压缩成了三步:连接(Client)→ 查看(view_api)→ 调用(predict/submit)。它既支持 Hugging Face Space(含私有 Space 与自动复制副本),也支持任何以 URL 形式暴露的 Gradio 应用;既支持同步阻塞调用,也支持带状态跟踪与回调的异步任务;文件类数据在客户端与远程应用之间以路径/URL 自动转换。对于任何需要把现成的机器学习应用接入自己代码流程的开发者来说,它是比手写 HTTP 请求更省心、更健壮的选择。
更完整的用法(如流式输出、事件监听、OAuth 端点等)可以参考官方关于 Python 客户端的专项指南,也可直接阅读本仓库 client/python/ 下的源码、CHANGELOG.md 与 client/python/test/ 中的测试用例进行深入探索。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00