在本指南中,我们将更深入地探讨与他人共享Gradio应用程序的各个方面。我们将涵盖:
Gradio 演示可以通过在 launch() 方法中设置 share=True 轻松公开分享。像这样:
import gradio as gr
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(fn=greet, inputs="textbox", outputs="textbox")
demo.launch(share=True) # Share your demo with just 1 extra parameter 🚀这将生成一个公开的、可分享的链接,您可以发送给任何人!当您发送此链接时,另一端的用户可以在他们的浏览器中试用该模型。由于处理发生在您的设备上(只要您的设备保持开启),您不必担心任何依赖项的打包。
分享链接通常看起来像这样:https://07ff8706ab.gradio.live。虽然链接是通过Gradio分享服务器提供的,但这些服务器只是您本地服务器的代理,不会存储通过您的应用程序发送的任何数据。分享链接在72小时后过期。(也可以在您自己的云服务器上设置自己的分享服务器来克服此限制。)
提示: 请记住,分享链接是公开可访问的,这意味着任何人都可以使用你的模型进行预测!因此,请确保不要通过你编写的函数暴露任何敏感信息,或允许在你的设备上发生任何关键更改。或者你可以按照下面讨论的[为你的Gradio应用添加认证](#authentication)。
请注意,默认情况下,share=False,这意味着您的服务器仅在本地运行。(这是默认设置,除了在Google Colab笔记本中,会自动创建共享链接)。作为使用共享链接的替代方案,您可以使用SSH端口转发与特定用户共享您的本地服务器。
如果您希望在互联网上拥有一个永久链接到您的Gradio演示,请使用Hugging Face Spaces。Hugging Face Spaces提供了永久免费托管您的机器学习模型的基础设施!
在您创建了一个免费的Hugging Face账户之后,您有两种方法可以将您的Gradio应用程序部署到Hugging Face Spaces:
从终端:在您的应用程序目录中运行 gradio deploy。CLI 将收集一些基本元数据,然后启动您的应用程序。要更新您的空间,您可以重新运行此命令或启用 Github Actions 选项以在 git push 时自动更新空间。
从您的浏览器:拖放一个包含您的Gradio模型和所有相关文件的文件夹这里。有关更多信息,请参阅此指南如何在Hugging Face Spaces上托管,或观看嵌入的视频:
一旦你在Hugging Face Spaces(或你自己的服务器)上托管了你的应用程序,你可能希望将演示嵌入到不同的网站上,比如你的博客或作品集。嵌入一个交互式演示可以让人们尝试你构建的机器学习模型,而无需下载或安装任何东西——直接在他们的浏览器中!最棒的是,你甚至可以在静态网站上嵌入交互式演示,比如GitHub页面。
有两种方法可以嵌入你的Gradio演示。你可以在Hugging Face Space页面的“嵌入此Space”下拉选项中找到这两种选项的快速链接:

Web组件通常比IFrames提供更好的用户体验。Web组件是懒加载的,这意味着它们不会减慢您网站的加载时间,并且它们会根据Gradio应用程序的大小自动调整高度。
使用Web Components嵌入:
<script
type="module"
src="https://gradio.s3-us-west-2.amazonaws.com/{GRADIO_VERSION}/gradio.js"
></script><gradio-app src="https://$your_space_host.hf.space"></gradio-app>你想要放置应用程序的元素。将src=属性设置为你空间的嵌入URL,你可以在“嵌入此空间”按钮中找到它。例如:
<gradio-app
src="https://abidlabs-pytorch-image-classifier.hf.space"
></gradio-app>你可以看到网页组件的示例 在Grio的登陆页面.
您还可以通过传递给标签的属性来自定义您的Web组件的外观和行为:
src: 正如我们所看到的,src 属性链接到您想要嵌入的托管 Gradio 演示的 URLspace: 如果你的Gradio演示托管在Hugging Face Space上,这是一个可选的简写。接受username/space_name而不是完整的URL。例如:gradio/Echocardiogram-Segmentation。如果提供了此属性,则不需要提供src。control_page_title: 一个布尔值,指定页面的HTML标题是否应设置为Gradio应用的标题(默认为"false")initial_height: 网页组件在加载 Gradio 应用时的初始高度,(默认为 "300px")。请注意,最终高度是根据 Gradio 应用的大小设置的。container: 是否显示边框框架和有关Space托管位置的信息(默认为"true")info: 是否仅显示有关嵌入式应用程序下方托管空间位置的信息(默认情况下为 "true")autoscroll: 预测完成后是否自动滚动到输出(默认为 "false")eager: 是否在页面加载时立即加载Gradio应用(默认为"false")theme_mode: 是否使用dark、light或默认的system主题模式(默认为"system")render: 嵌入空间完成渲染后触发的事件。这里有一个示例,展示了如何使用这些属性创建一个不进行懒加载且初始高度为0px的Gradio应用。
<gradio-app
space="gradio/Echocardiogram-Segmentation"
eager="true"
initial_height="0px"
></gradio-app>这是另一个如何使用render事件的示例。使用事件监听器来捕获render事件,并在渲染完成后调用handleLoadComplete()函数。
<script>
function handleLoadComplete() {
console.log("Embedded space has finished rendering");
}
const gradioApp = document.querySelector("gradio-app");
gradioApp.addEventListener("render", handleLoadComplete);
</script>注意:虽然Gradio的CSS永远不会影响嵌入页面,但嵌入页面可能会影响嵌入的Gradio应用程序的样式。确保父页面中的任何CSS不会过于通用,以至于也可能应用于嵌入的Gradio应用程序并导致样式破坏。像header { ... }和footer { ... }这样的元素选择器最有可能引起问题。
要使用IFrames嵌入(例如,如果您无法将javascript添加到您的网站),请添加此元素:
<iframe src="https://$your_space_host.hf.space"></iframe>再次,你可以找到你的Space的嵌入URL中的src=属性,你可以在“嵌入此Space”按钮中找到它。
注意:如果您使用IFrames,您可能希望添加一个固定的height属性并设置style="border:0;"以移除边框。此外,如果您的应用程序需要访问网络摄像头或麦克风等权限,您还需要使用allow属性来提供这些权限。
你可以将几乎任何Gradio应用用作API!在Gradio应用的页脚,比如这个,你会看到一个“通过API使用”的链接。

这是一个页面,列出了可以通过我们支持的客户端查询Gradio应用程序的端点:Python客户端或JavaScript客户端。对于每个端点,Gradio会自动生成参数及其类型,以及示例输入,如下所示。

当您启动Gradio Interface时,端点会自动创建。如果您使用Gradio Blocks,您也可以设置一个Gradio API页面,但我们建议您明确命名每个事件监听器,例如
btn.click(add, [num1, num2], output, api_name="addition")这将添加并记录端点 /api/addition/ 到自动生成的API页面。否则,您的API端点将显示为“未命名”端点。
当用户向您的应用程序做出预测时,您可能需要底层的网络请求,以便获取请求头(例如用于高级身份验证)、记录客户端的IP地址、获取查询参数或其他原因。Gradio以类似于FastAPI的方式支持这一点:只需添加一个类型提示为gr.Request的函数参数,Gradio将把网络请求作为该参数传递。以下是一个示例:
import gradio as gr
def echo(text, request: gr.Request):
if request:
print("Request headers dictionary:", request.headers)
print("IP address:", request.client.host)
print("Query parameters:", dict(request.query_params))
return text
io = gr.Interface(echo, "textbox", "textbox").launch()注意:如果你的函数是直接调用而不是通过UI调用(例如,当示例被缓存,或者当Gradio应用程序通过API调用时),那么request将会是None。你应该明确处理这种情况,以确保你的应用程序不会抛出任何错误。这就是为什么我们有明确的检查if request。
在某些情况下,您可能已经有一个现有的FastAPI应用程序,并且您想为Gradio演示添加一个路径。
您可以使用gradio.mount_gradio_app()轻松实现这一点。
这是一个完整的示例:
from fastapi import FastAPI
import gradio as gr
CUSTOM_PATH = "/gradio"
app = FastAPI()
@app.get("/")
def read_main():
return {"message": "This is your main app"}
io = gr.Interface(lambda x: "Hello, " + x + "!", "textbox", "textbox")
app = gr.mount_gradio_app(app, io, path=CUSTOM_PATH)
# Run this from the terminal as you would normally start a FastAPI app: `uvicorn run:app`
# and navigate to http://localhost:8000/gradio in your browser.
请注意,这种方法还允许您在自定义路径上运行您的Gradio应用程序(在上面的示例中为http://localhost:8000/gradio)。
您可能希望在应用程序前放置一个认证页面,以限制谁可以打开您的应用程序。通过在launch()方法中使用auth=关键字参数,您可以提供一个包含用户名和密码的元组,或者一个可接受用户名/密码元组的列表;这里有一个为名为“admin”的单个用户提供基于密码认证的示例:
demo.launch(auth=("admin", "pass1234"))对于更复杂的身份验证处理,你甚至可以传递一个函数,该函数以用户名和密码作为参数,并返回True以允许访问,否则返回False。
这是一个接受任何用户名和密码相同的登录的函数示例:
def same_auth(username, password):
return username == password
demo.launch(auth=same_auth)如果您有多个用户,您可能希望根据登录的用户自定义显示的内容。您可以通过直接访问网络请求来检索登录的用户,如上所述,然后读取请求的.username属性。这里有一个示例:
import gradio as gr
def update_message(request: gr.Request):
return f"Welcome, {request.username}"
with gr.Blocks() as demo:
m = gr.Markdown()
demo.load(update_message, None, m)
demo.launch(auth=[("Abubakar", "Abubakar"), ("Ali", "Ali")])注意:为了使身份验证正常工作,必须在浏览器中启用第三方Cookie。Safari或Chrome隐身模式默认情况下并非如此。
如果用户访问您的Gradio应用程序的/logout页面,他们将自动注销并删除会话cookie。这使您也可以向您的Gradio应用程序添加注销功能。让我们更新前面的示例以包含一个注销按钮:
import gradio as gr
def update_message(request: gr.Request):
return f"Welcome, {request.username}"
with gr.Blocks() as demo:
m = gr.Markdown()
logout_button = gr.Button("Logout", link="/logout")
demo.load(update_message, None, m)
demo.launch(auth=[("Pete", "Pete"), ("Dawood", "Dawood")])注意:Gradio的内置认证提供了一个简单且基础的访问控制层,但对于需要严格访问控制的应用(例如多因素认证、速率限制或自动锁定策略),它并不提供强大的安全功能。
Gradio 原生支持通过 Hugging Face 进行 OAuth 登录。换句话说,您可以轻松地在您的演示中添加一个"使用 Hugging Face 登录"按钮,该按钮允许您获取用户的 HF 用户名以及他们 HF 个人资料中的其他信息。查看这个 Space以获取实时演示。
要启用OAuth,您必须在README.md文件中将hf_oauth: true设置为Space元数据。这将在Hugging Face上将您的Space注册为OAuth应用程序。接下来,您可以使用gr.LoginButton在您的Gradio应用程序中添加登录按钮。一旦用户使用他们的HF账户登录,您可以通过在任何Gradio函数中添加类型为gr.OAuthProfile的参数来检索他们的个人资料。用户个人资料将自动作为参数值注入。如果您想代表用户执行操作(例如列出用户的私有仓库、创建仓库等),您可以通过添加类型为gr.OAuthToken的参数来检索用户令牌。您必须在Space元数据中定义您将使用的范围(有关更多详细信息,请参阅文档)。
这是一个简短的示例:
from __future__ import annotations
import gradio as gr
from huggingface_hub import whoami
def hello(profile: gr.OAuthProfile | None) -> str:
if profile is None:
return "I don't know you."
return f"Hello {profile.name}"
def list_organizations(oauth_token: gr.OAuthToken | None) -> str:
if oauth_token is None:
return "Please deploy this on Spaces and log in to list organizations."
org_names = [org["name"] for org in whoami(oauth_token.token)["orgs"]]
return f"You belong to {', '.join(org_names)}."
with gr.Blocks() as demo:
gr.LoginButton()
m1 = gr.Markdown()
m2 = gr.Markdown()
demo.load(hello, inputs=None, outputs=m1)
demo.load(list_organizations, inputs=None, outputs=m2)
demo.launch()
当用户点击登录按钮时,他们将被重定向到一个新页面以授权您的空间。
用户可以随时在他们的设置中撤销对其个人资料的访问权限。
如上所示,OAuth 功能仅在您的应用程序在 Space 中运行时可用。然而,您通常需要在部署之前在本地测试您的应用程序。要在本地测试 OAuth 功能,您的机器必须登录到 Hugging Face。请运行 huggingface-cli login 或使用您的访问令牌之一设置 HF_TOKEN 作为环境变量。您可以在设置页面生成一个新令牌 (https://huggingface.co/settings/tokens)。然后,点击 gr.LoginButton 将登录您的本地 Hugging Face 配置文件,允许您在将应用程序部署到 Space 之前使用您的 Hugging Face 帐户调试应用程序。
安全提示: 需要注意的是,添加一个gr.LoginButton并不会像添加用户名-密码认证那样限制用户使用你的应用。这意味着,即使没有通过Hugging Face登录的用户仍然可以访问并运行你的Gradio应用中的事件——不同之处在于,在相应的函数中,gr.OAuthProfile或gr.OAuthToken将会是None。
也可以在您的Gradio应用程序中使用外部OAuth提供者(例如Google OAuth)进行身份验证。为此,首先将您的Gradio应用程序挂载到FastAPI应用程序中(如上所述)。然后,您必须编写一个身份验证函数,该函数从OAuth提供者获取用户的用户名并返回它。此函数应传递给gr.mount_gradio_app中的auth_dependency参数。
类似于FastAPI依赖函数,由auth_dependency指定的函数将在你的FastAPI应用中的任何Gradio相关路由之前运行。该函数应接受一个参数:FastAPI的Request,并返回一个字符串(代表用户的用户名)或None。如果返回一个字符串,用户将能够访问你的FastAPI应用中的Gradio相关路由。
首先,让我们展示一个简单的例子来说明 auth_dependency 参数:
from fastapi import FastAPI, Request
import gradio as gr
app = FastAPI()
def get_user(request: Request):
return request.headers.get("user")
demo = gr.Interface(lambda s: f"Hello {s}!", "textbox", "textbox")
app = gr.mount_gradio_app(app, demo, path="/demo", auth_dependency=get_user)
if __name__ == '__main__':
uvicorn.run(app)在这个例子中,只有包含“user”头的请求才能访问Gradio应用程序。当然,这并没有增加多少安全性,因为任何用户都可以在他们的请求中添加这个头。
这里有一个更完整的示例,展示了如何将Google OAuth添加到Gradio应用程序中(假设您已经在Google开发者控制台上创建了OAuth凭据):
import os
from authlib.integrations.starlette_client import OAuth, OAuthError
from fastapi import FastAPI, Depends, Request
from starlette.config import Config
from starlette.responses import RedirectResponse
from starlette.middleware.sessions import SessionMiddleware
import uvicorn
import gradio as gr
app = FastAPI()
# Replace these with your own OAuth settings
GOOGLE_CLIENT_ID = "..."
GOOGLE_CLIENT_SECRET = "..."
SECRET_KEY = "..."
config_data = {'GOOGLE_CLIENT_ID': GOOGLE_CLIENT_ID, 'GOOGLE_CLIENT_SECRET': GOOGLE_CLIENT_SECRET}
starlette_config = Config(environ=config_data)
oauth = OAuth(starlette_config)
oauth.register(
name='google',
server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
client_kwargs={'scope': 'openid email profile'},
)
SECRET_KEY = os.environ.get('SECRET_KEY') or "a_very_secret_key"
app.add_middleware(SessionMiddleware, secret_key=SECRET_KEY)
# Dependency to get the current user
def get_user(request: Request):
user = request.session.get('user')
if user:
return user['name']
return None
@app.get('/')
def public(user: dict = Depends(get_user)):
if user:
return RedirectResponse(url='/gradio')
else:
return RedirectResponse(url='/login-demo')
@app.route('/logout')
async def logout(request: Request):
request.session.pop('user', None)
return RedirectResponse(url='/')
@app.route('/login')
async def login(request: Request):
redirect_uri = request.url_for('auth')
# If your app is running on https, you should ensure that the
# `redirect_uri` is https, e.g. uncomment the following lines:
#
# from urllib.parse import urlparse, urlunparse
# redirect_uri = urlunparse(urlparse(str(redirect_uri))._replace(scheme='https'))
return await oauth.google.authorize_redirect(request, redirect_uri)
@app.route('/auth')
async def auth(request: Request):
try:
access_token = await oauth.google.authorize_access_token(request)
except OAuthError:
return RedirectResponse(url='/')
request.session['user'] = dict(access_token)["userinfo"]
return RedirectResponse(url='/')
with gr.Blocks() as login_demo:
gr.Button("Login", link="/login")
app = gr.mount_gradio_app(app, login_demo, path="/login-demo")
def greet(request: gr.Request):
return f"Welcome to Gradio, {request.username}"
with gr.Blocks() as main_demo:
m = gr.Markdown("Welcome to Gradio!")
gr.Button("Logout", link="/logout")
main_demo.load(greet, None, m)
app = gr.mount_gradio_app(app, main_demo, path="/gradio", auth_dependency=get_user)
if __name__ == '__main__':
uvicorn.run(app)在这个例子中实际上有两个独立的Gradio应用程序!一个简单地显示登录按钮(任何用户都可以访问此演示),而另一个主要演示仅对已登录的用户可访问。你可以在这个Space上尝试这个例子。
默认情况下,Gradio 会收集某些分析数据,以帮助我们更好地了解 gradio 库的使用情况。这包括以下信息:
auth 或 show_error 不会从您的Gradio应用程序的用户那里收集任何信息。如果您想完全禁用分析功能,可以通过在gr.Blocks、gr.Interface或gr.ChatInterface中将analytics_enabled参数设置为False来实现。或者,您可以将GRADIO_ANALYTICS_ENABLED环境变量设置为"False",以将此设置应用于您系统上创建的所有Gradio应用程序。
注意: 这反映了自 gradio>=4.32.0 以来的分析政策。