尧图精选

Gradio Python Client 实战指南:用几行代码把任意 Gradio 应用变成可编程 API

🕒 发布时间:2026/9/9 14:48:42 📁 来源:尧图网络
Gradio Python Client 实战指南用几行代码把任意 Gradio 应用变成可编程 API【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradio本指南是 Gradio 官方文档系列 Gradio Clients and Lite位于 guides/09_gradio-clients-and-lite/01_getting-started-with-the-python-client.md的核心入门篇。你将学会安装独立的gradio_client轻量包用它连接托管在 Hugging Face Spaces、Share 链接或自建服务器上的任何 Gradio 应用完成文件上传、同步/异步预测、任务状态跟踪与取消、生成式端点的流式消费等真实开发场景。读完本文你可以完全不打开浏览器用 Python 把任何 Gradio 应用当作标准 REST/流式 API 调用。Gradio Python Client 是什么Gradio 生态通常被理解为一个“用 Python 构建机器学习演示界面”的前端框架而gradio_client则是同一生态的另一半它把任何正在运行的 Gradio 应用暴露成可编程的 API让你在脚本、批处理任务、Agent 或 Web 服务中远程调用它的功能。用 client/python/gradio_client/init.py 中的定义来看这个独立包向用户暴露的接口非常收敛只有几个核心对象from gradio_client.client import Client from gradio_client.data_classes import FileData from gradio_client.utils import __version__, file, handle_file也就是说绝大多数使用场景只涉及Client、handle_file、FileData三个名字。官方文档用一个经典示例说明其威力——连接一个“将麦克风录音转成文字”的 Whisper Space全部代码只有五行from gradio_client import Client, handle_file client Client(abidlabs/whisper) client.predict( audiohandle_file(audio_sample.wav) ) This is a test of the whisper speech recognition model.这里的handle_file(audio_sample.wav)负责把本地文件上传到远端 Gradio 服务器Client.predict()则把上传结果作为参数送入远端函数。注意这里甚至不需要显式指定api_name因为该 Space 只有一个命名端点客户端会自动推断。需要强调的是客户端不受托管位置限制。Hugging Face Spaces、临时*.gradio.live共享链接、你自己的公网/内网服务器只要是标准 Gradio 应用都能连接。前置知识门槛很低你不必精通gradio库本身只需大致理解 Gradio 的“输入组件 / 输出组件”概念即可因为客户端的参数结构正是由这些组件推导出来的。安装与版本前提gradio_client是一个独立、轻量、与前端解耦的包仅需网络库httpx、huggingface_hub 等就能工作无需安装完整版gradio。官方文档声明其测试支持的 Python 版本为3.10 及以上。pip install --upgrade gradio_client如果你已经安装了较新版本的gradio那么gradio_client会作为依赖自动带上。但需要注意文档与 API 永远以最新版gradio_client为准所以如果环境里的版本较老建议先执行上面的升级命令再继续。连接一个运行中的应用四种接入方式1. 连接 Hugging Face 上的 Space连接运行在 HF Spaces 上的应用src直接传 Space 的命名空间路径即可from gradio_client import Client client Client(abidlabs/en2fr) # 一个英译法的 Spacesrc支持两种取值见 client.py 中 Client.init的文档HF Space 名称如abidlabs/whisper-large-v2客户端会解析为对应 Space 的公开地址完整 URL含http://或https://指向任何自托管 Gradio 应用。2. 带鉴权连接token 与 auth面向 HF 私有 Space 的 token 鉴权私有 Space 需要传 HF Tokenfrom gradio_client import Client client Client(abidlabs/my-private-space, token...)在源码里这个 token 会通过huggingface_hub的build_hf_headers(...)生成请求头见 client.py 第 113-120 行其中既有标准authorization头也会额外复制一份为x-hf-authorization头供 Gradio 应用校验。面向应用自身的用户名/密码鉴权如果应用部署时配置了 Basic Auth即 Gradio 应用的“用户名 密码”登录则把凭据以元组形式传给auth参数from gradio_client import Client Client( space_name, auth[username, password] )注意token与auth是两类不同的鉴权——前者是 HF 平台凭据用于拉取/访问私有 Space后者是应用自身登录凭据会在首次连接时先调用/login端点换取会话 cookie。3. 连接自托管或 Share 链接只要 URL 可达直接传完整地址无需任何中间件或代理from gradio_client import Client client Client(https://bec81a83-5b5c-471e.gradio.live)4. 更多底层可调参数从 client.py 的构造函数签名 可以看到Client.__init__还暴露了若干实用选项用于把客户端调整到符合你的网络与运行环境参数默认值作用max_workers40可同时向远端发起请求的工作线程上限verboseTrue是否在控制台打印客户端信息httpx_kwargsNone透传给底层 httpx 的关键字timeout、proxy 等download_files临时目录受GRADIO_TEMP_DIR影响远端输出文件下载到本地的目录传False则不下载、直接返回带远端路径的FileDatassl_verifyTrue设为False可连接使用自签名证书的 Gradio 应用oauth_tokenNone供应用代码以你的身份调用需要gr.OAuthToken的端点用 duplicate 复制一个 Space绕开限流任何公开 Space 都可以直接当 API 用但高频请求可能触发 HF 平台的频率限制。官方推荐的做法是用Client.duplicate()把 Space 复制一份到自己的命名空间下成为私有 Space随后对它不限量发起请求。import os from gradio_client import Client, handle_file HF_TOKEN os.environ.get(HF_TOKEN) client Client.duplicate(abidlabs/whisper, tokenHF_TOKEN) client.predict(handle_file(audio_sample.wav)) This is a test of the whisper speech recognition model.从 client.py 中 duplicate 的类方法签名 可以确认其完整参数Client.duplicate( from_id: str, # 要复制的原 Space to_id: str | None, # 新 Space 名称默认自动生成 token: str | None, # HF Token private: bool True, # 默认复制为私有 Space hardware: ..., # 可选cpu-basic / cpu-upgrade / t4-small / t4-medium / # a10g-small / a10g-large / a100-large 等 GPU 规格 secrets: dict | None, # 需要注入的环境变量密钥 sleep_timeout: int 5, # 轮询等待 Space 就绪的间隔 max_workers: int 40, verbose: bool True, )几个实用要点重复调用是幂等的。如果已经复制过某个 Space再次执行duplicate()不会新建实例而是复用先前创建好的那一个可以放心在脚本/CI 中反复调用。GPU 成本提示若原 Space 使用 GPU你的私有副本同样会占用 GPU并依据 GPU 规格向你的 HF 账户计费。为控制成本副本会在闲置 1 小时后自动休眠这也是平台默认行为你也可以通过hardware参数显式选择更便宜的硬件规格或用sleep_timeout等参数微调。该功能在库内的实现会先经huggingface_hub创建 Space随后通过轮询等待其进入运行状态因此需要传入有效 token或已通过 HF CLI 登录。查看可用端点Client.view_api()连接建立后第一件事通常是弄清楚“这个应用到底能调什么”。调用Client.view_api()即可打印该应用所有命名的 API 端点及其参数结构。对 Whisper Space 输出大致如下Client.predict() Usage Info --------------------------- Named API endpoints: 1 - predict(audio, api_name/predict) - output Parameters: - [Audio] audio: filepath (required) Returns: - [Textbox] output: str这里揭示了客户端方法论的关键远端 Gradio 组件Audio、Textbox……会被映射成 Python 侧的参数类型。比如[Audio] audio: filepath表示你要传一个本地文件路径或网络文件 URL经handle_file包装[Textbox] output: str表示返回的是字符串。在源码层面这一能力的支撑是 client.py 中的view_api方法与内部的_get_api_info它请求远端的config与info?all_endpointsTrue接口对应 utils.py 中定义的 CONFIG_URL / API_INFO_URL把 Gradio 的组件定义解析成人类可读的参数清单。view_api还支持all_endpoints是否同时展示匿名无api_name端点print_infoFalse/return_formatdict将结构以字典返回便于在程序里进一步处理。什么时候需要传api_name当应用只有一个命名端点时可以不传客户端自动选默认端点但当应用定义了多个命名端点如/predict、/count、/chat就必须通过api_name/xxx指定要调用哪一个。同步预测Client.predict()最简单也最常见的调用方式就是同步.predict()传入与端点参数对应的值等待计算完成并一次性返回结果。from gradio_client import Client client Client(abidlabs/en2fr) client.predict(Hello, api_name/predict) Bonjour多参数应用依次传参即可以gradio/calculator为例它接收“两个数字 一个运算符”from gradio_client import Client client Client(gradio/calculator) client.predict(4, add, 5) 9.0为什么推荐关键字参数官方文档明确建议用关键字参数而不是位置参数。这不仅让调用意图一目了然还能利用 Gradio 组件的默认值机制——端点上凡是“组件有初始值”或“函数参数默认值为 None”的参数在客户端侧都可以省略。from gradio_client import Client client Client(gradio/calculator) client.predict(num14, operationadd, num25)例如某图像生成 Space 的steps参数底层对应一个带默认值的 Slider 组件那么你只需要提供必填的textfrom gradio_client import Client client Client(abidlabs/image_generator) client.predict(textan astronaut riding a camel)想覆盖默认值就把它一并写上client.predict(textan astronaut riding a camel, steps25)在实现上Client.predict会把你的*args/**kwargs交给construct_args()见 utils.py与远端 API 描述中记录的ParameterInfo含parameter_has_default、parameter_default字段定义在 data_classes.py进行对齐缺省参数自动填充这正是“默认值自动生效”的底层原因。传文件与传 URL必须用 handle_file()当某个参数是 Audio、Image、Video、File 等“文件型组件”时必须把本地路径或网络 URL 用handle_file()包起来。它负责把文件上传到 Gradio 服务器的/upload端点并生成一个标准的 FileData 结构确保远端能正确预处理。from gradio_client import Client, handle_file client Client(abidlabs/whisper) client.predict( audiohandle_file(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. ...从 utils.py 中 handle_file 的实现 可以看到它的判定逻辑def handle_file(filepath_or_url: str | Path): s str(filepath_or_url) data {path: s, meta: {_type: gradio.FileData}} if is_http_url_like(s): return {**data, orig_name: s.rsplit(/, maxsplit1)[-1], url: s} elif Path(s).exists(): return {**data, orig_name: Path(s).name} else: raise ValueError( fFile {s} does not exist on local filesystem and is not a valid URL. )即合法输入只可能是「HTTP(S) 形式的 URL」或「本地确实存在的文件路径」二者都会携带orig_name与meta._type gradio.FileData标记两者都不匹配则直接抛ValueError。返回值本质上就是一个结构化的FileData字典——该 TypedDict 的完整字段name、data、size、orig_name、mime_type等定义在 data_classes.py。这也解释了为什么文档提示“输入输出数据事实上以 FileData 形式在网络间传输”。兼容性提醒旧版接口gradio_client.file()仍可用但已标记 deprecated会在未来版本移除新代码一律使用handle_file()utils.py 第 1357-1361 行。异步提交与结果回调.predict()是阻塞调用——它会一直等到远端算完才返回。当一次推理耗时很长大模型、视频处理等更合理的做法是先把任务交出去后台运行等你需要结果时再取回。这时使用.submit()它会立刻返回一个Job对象from gradio_client import Client client Client(spaceabidlabs/en2fr) job client.submit(Hello, api_name/predict) # 非阻塞 # 在这里可以做任何其他事情…… job.result() # 阻塞直到任务完成并返回结果 Bonjour为任务挂上回调如果你希望在任务完成后自动执行某个动作而不是手动轮询可以给submit()传入一个或多个result_callbacks。每个回调接收该次任务的输出作为参数from gradio_client import Client def print_result(x): print(fThe translated result is: {x}) client Client(spaceabidlabs/en2fr) job client.submit(Hello, api_name/predict, result_callbacks[print_result]) # 继续做别的事…… The translated result is: Bonjour在实现上submit()会创建后台 Future 并把回调包装成线程安全的完成钩子见 client.py 的create_fn/fn回调列表也支持传单个可调用对象或多个可调用对象的列表。跟踪任务状态job.status()通过Job.status()可以随时读取任务在服务端队列/执行器中的状态。它返回一个StatusUpdate对象。根据 utils.py 中 StatusUpdate 数据类定义其主要属性为code状态码取自Status枚举见下rank该任务在队列中的当前位置queue_size当前队列总长度eta预计完成时间success任务是否成功time该状态生成的时间戳另外还有progress_data进度条明细与log日志。code可取的具体值定义在 utils.py 的 Status 枚举STARTING、JOINING_QUEUE、QUEUE_FULL、IN_QUEUE、SENDING_DATA、PROCESSING、PROGRESS、ITERATING、FINISHED、CANCELLED。这些状态由后台线程把服务端 SSE 协议消息send_hash、estimation、process_starts、process_completed……逐条映射而来Status.msg_to_status()。from gradio_client import Client client Client(srcgradio/calculator) job client.submit(5, add, 4, api_name/predict) job.status() Status.STARTING: STARTING如果只想判断任务是否已经跑完可以用Job.done()它返回布尔值。取消排队中的任务Job.cancel()用于取消那些还在排队、尚未开始处理的任务client Client(abidlabs/whisper) job1 client.submit(handle_file(audio_sample1.wav)) job2 client.submit(handle_file(audio_sample2.wav)) job1.cancel() # 若已开始处理返回 False无法取消 job2.cancel() # 若仍在队列中返回 True成功取消并移出队列其语义清晰地区分两种情况已经开始被服务端处理的任务不可取消返回False尚未开始、仍在排队中的任务会被取消并从队列移除返回True。取消动作在底层通过向服务端的/cancel端点发送取消请求实现。处理 Generator 端点流式输出某些 Gradio 端点的函数是 Python 生成器会连续产出多个值而不是只返回一个值。Job对象针对这类端点提供了三种使用方式。方式一job.outputs() 取当前累计结果from gradio_client import Client client Client(srcgradio/count_generator) job client.submit(3, api_name/count) while not job.done(): time.sleep(0.1) job.outputs() [0, 1, 2]需要留意对生成器端点执行job.result()只会返回第一个产出值这里是0要拿全量结果必须用job.outputs()。方式二把 Job 当迭代器逐条消费Job对象实现了__iter__/__next__可以像生成器一样边产出边处理from gradio_client import Client client Client(srcgradio/count_generator) job client.submit(3, api_name/count) for o in job: print(o) 0 1 2方式三取消迭代式任务对仍在产出中间结果的任务执行cancel()任务会在当前这一轮迭代完成后优雅结束而不是立刻中断服务端from gradio_client import Client import time client Client(abidlabs/test-yield) job client.submit(abcdef) time.sleep(3) job.cancel() # 任务在若干轮迭代后停止仓库自带的本地演示 demo/count_generator/run.py 就是上述count_generatorSpace 的等价实现可以作为本地复现流式端点的参考。Session State客户端自动帮你“记住状态”Gradio 应用可以用gr.State组件在页面会话内持久化数据例如累积用户提交过的词列表。下面这段gr.Blocks演示维护一个“已见过哪些词”的列表用户每提交一个新词它返回该词的历史出现次数并把新词追加进状态import gradio as gr def count(word, list_of_words): return list_of_words.count(word), list_of_words [word] with gr.Blocks() as demo: words gr.State([]) textbox gr.Textbox() number gr.Number() textbox.submit(count, inputs[textbox, words], outputs[number, words]) demo.launch()有趣的是当你用 Python Client 连接这样的应用时view_api()显示的 API 结构里根本看不到 state 输入/输出只有一对“词 → 次数”- predict(word, api_name/count) - value_31 Parameters: - [Textbox] word: str (required) Returns: - [Number] value_31: float原因在源码中有直接体现utils.py 的SKIP_COMPONENTS集合把state列入了“不向用户暴露”的组件类型。也就是说Python Client 会自动替你管理会话状态连续多次请求时上一次请求返回的 state 会被内部保存并自动作为下一次请求的输入送回去整个过程对调用方透明。如果你想强制让应用“回到初始状态”例如开启一段全新的独立会话调用Client.reset_session()即可对应源码中向RESET_URL reset端点发起重置请求见 utils.py。进阶阅读本系列其余篇幅查询 Gradio 应用的其他方式curl、JavaScript Client 入门、在 FastAPI 应用内嵌 Gradio 客户端若想本地查看客户端实现细节核心代码集中在 client/python/gradio_client/client.pyClient、Job、Communicator 等与 client/python/gradio_client/utils.py网络协议、状态枚举、handle_file 等需要理解“Gradio 应用端如何定义这些端点”可结合 gradio/events.py、gradio/blocks.py 中关于事件与端点的实现以及 guides/04_additional-features 下关于应用共享与鉴权的说明。把 Python Client 与 Gradio 服务端配合起来看服务端把任意 Python 函数含生成器、带状态、带队列标准化为 HTTP SSE 端点客户端则负责上传文件、维护会话、翻译参数、消费流式输出。理解这层抽象后你会发现“把 Gradio 应用变成 API”与“把 API 交给 Agent / LLM 工具调用”之间只有一步之遥。【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →