1. 附加功能
  2. 分享你的应用

分享你的应用

在本指南中,我们将深入探讨与他人分享 Gradio 应用的各种方面。我们将涵盖:

  1. 使用 share 参数分享演示
  2. 在 HF Spaces 上托管
  3. 分享深度链接
  4. 嵌入托管的 Spaces
  5. 使用 API 页面
  6. 访问网络请求
  7. 在 FastAPI 中挂载
  8. 身份验证
  9. MCP 服务器
  10. 速率限制
  11. 分析
  12. 渐进式 Web 应用 (PWA)

分享演示

通过在 launch() 方法中设置 share=True,Gradio 应用可以轻松地公开分享。例如:

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 🚀

这将生成一个公开的、可分享的链接,你可以发送给任何人!当你发送这个链接时,另一端的用户可以在他们的浏览器中试用该模型。因为处理是在你的设备上进行的(只要你的设备保持开机),所以你不必担心打包任何依赖项。

sharing

分享链接通常看起来像这样:https://07ff8706ab.gradio.live。尽管链接是通过 Gradio 分享服务器提供的,但这些服务器只是你本地服务器的代理,并且不存储通过你的应用发送的任何数据。分享链接通常在一周后过期。(也可以在自己的云服务器上设置自己的分享服务器来克服此限制。)

请记住,分享链接是公开可访问的,这意味着任何人都可以使用你的模型进行预测!因此,请确保你编写的函数不暴露任何敏感信息,也不允许在你的设备上发生任何关键性更改。或者,你可以 为你的 Gradio 应用添加身份验证,如下文所述。

请注意,默认情况下 share=False,这意味着你的服务器仅在本地运行。(这是默认设置,但在 Google Colab 笔记本中除外,在这些笔记本中会自动创建分享链接)。作为使用分享链接的替代方案,你可以使用 SSH 端口转发与特定用户共享你的本地服务器。

在 HF Spaces 上托管

如果你想拥有一个永久的 Gradio 演示链接在互联网上,可以使用 Hugging Face Spaces。 Hugging Face Spaces 提供免费永久托管机器学习模型的基础设施!

创建免费 Hugging Face 账户后,你有两种方法可以将 Gradio 应用部署到 Hugging Face Spaces:

  1. 通过终端:在你的应用目录中运行 gradio deploy。CLI 将收集一些基本元数据,上传当前目录下的所有文件(遵守根目录下可能存在的 .gitignore 文件),然后将你的应用部署到 Spaces。要更新你的 Space,可以重新运行此命令,或在 CLI 中启用 Github Actions 选项,以便在 git push 时自动更新 Spaces。

  2. 通过浏览器:将包含 Gradio 模型和所有相关文件的文件夹 拖放到此处。有关如何将 Gradio 应用托管到 Hugging Face Spaces 的更多信息,请参阅 此指南,或观看嵌入式视频。

你可以将一个按钮添加到你的 Gradio 应用中,该按钮可以创建一个唯一的 URL,你可以用它来与他人分享你的应用和所有组件的**当前状态**。这对于分享应用中独特而有趣的生成内容,或保存应用在特定时间点的快照非常有用。

要向你的应用添加深度链接按钮,请将 gr.DeepLinkButton 组件放置在你的应用中的任何位置。为了让 URL 可供他人访问,你的应用必须可以通过公共 URL 访问。因此,请务必像托管 Hugging Face Spaces 那样托管你的应用,或在启动应用时使用 share=True 参数。

让我们看一个这个例子如何工作的例子。这是一个简单的 Gradio 聊天应用,它使用了 gr.DeepLinkButton 组件。在发送几条消息后,点击深度链接按钮并将其粘贴到新的浏览器标签页中,即可看到应用在该时间点的状态。

import gradio as gr
import random

def random_response(message, history):
    return random.choice(["Hi!", "Hello!", "Greetings!"])

with gr.Blocks() as demo:
    gr.ChatInterface(
        random_response,
        title="Greeting Bot",
        description="Ask anything and receive a nice greeting!",
        api_name="chat",
    )
    gr.DeepLinkButton()

if __name__ == "__main__":
    demo.launch(share=True)

嵌入托管的 Spaces

一旦你在 Hugging Face Spaces(或你自己的服务器)上托管了你的应用,你可能想将演示嵌入到另一个网站,例如你的博客或作品集。嵌入一个交互式演示可以让人们在他们的浏览器中直接试用你构建的机器学习模型,而无需下载或安装任何东西!最好的部分是,你甚至可以在静态网站(如 GitHub pages)中嵌入交互式演示。

有两种方法可以嵌入你的 Gradio 演示。你可以在 Hugging Face Space 页面的“嵌入此 Space”下拉选项中找到这两种选项的快速链接。

Embed this Space dropdown option

使用 Web Components 嵌入

Web Components 通常比 IFrames 为用户提供更好的体验。Web Components 惰性加载,这意味着它们不会减慢你网站的加载速度,并且它们会根据 Gradio 应用的大小自动调整高度。

使用 Web Components 嵌入

  1. 通过将下面的脚本添加到你的网站中,将 Gradio JS 库导入到你的网站中(将 URL 中的 {GRADIO_VERSION} 替换为你正在使用的 Gradio 的库版本)。
<script
	type="module"
	src="https://#/{GRADIO_VERSION}/gradio.js"
></script>
  1. 添加
<gradio-app src="https://$your_space_host.hf.space"></gradio-app>

<gradio-app> 元素,你想放置应用的地方。设置 src= 属性为你 Space 的嵌入 URL,你可以在“嵌入此 Space”按钮中找到它。例如:

<gradio-app
	src="https://abidlabs-pytorch-image-classifier.hf.space"
></gradio-app>

你可以在 Gradio 登陆页面 上看到 Web Components 的外观示例。

你还可以通过传递给 <gradio-app> 标签的属性来定制 Web Component 的外观和行为。

  • src:正如我们所见,src 属性链接到你想要嵌入的托管 Gradio 演示的 URL。
  • space:如果你的 Gradio 演示托管在 Hugging Face Space 上,则这是一个可选的简写方式。接受 username/space_name 而不是完整的 URL。例如:gradio/Echocardiogram-Segmentation。如果提供了此属性,则不需要提供 src 属性。
  • control_page_title:一个布尔值,指定页面 HTML 标题是否应设置为 Gradio 应用的标题(默认为 "false")。
  • initial_height:Web Component 在加载 Gradio 应用时的高度(默认为 "300px")。请注意,最终高度是根据 Gradio 应用的大小确定的。
  • container:是否显示边框框架以及有关 Space 托管位置的信息(默认为 "true")。
  • info:是否仅显示有关 Space 托管位置的信息,在嵌入式应用下方(默认为 "true")。
  • autoscroll:预测完成后是否自动滚动到输出(默认为 "false")。
  • eager:页面加载时是否立即加载 Gradio 应用(默认为 "false")。
  • theme_mode:使用 darklight 或默认的 system 主题模式(默认为 "system")。
  • render:一个事件,在嵌入式 Space 渲染完成后触发。

这是一个使用这些属性创建不延迟加载且初始高度为 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 { ... } 这样的元素选择器最有可能引起问题。

使用 IFrame 嵌入

如果不能将javascript添加到你的网站(例如),使用 IFrame 来嵌入(如果你不能将javascript添加到你的网站),请添加此元素

<iframe src="https://$your_space_host.hf.space"></iframe>

同样,你可以在“嵌入此 Space”按钮中找到 src= 属性为你 Space 的嵌入 URL。

注意:如果你使用 IFrame,你可能需要添加一个固定的 height 属性并设置 style="border:0;" 来移除边框。此外,如果你的应用需要访问摄像头或麦克风等权限,你还需要使用 allow 属性来提供这些权限。

API 页面

你可以将几乎任何 Gradio 应用用作 API!在 这个演示的页脚,你会看到一个“通过 API 使用”链接。

Use via API

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

当您启动 Gradio 应用程序时,端点会自动创建。如果你正在使用 Gradio Blocks,你也可以为每个事件监听器命名,例如:

btn.click(add, [num1, num2], output, api_name="addition")

这将向自动生成的 API 页面添加并记录 /addition/ 端点。在此处 了解有关 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 应用中挂载

在某些情况下,你可能有一个现有的 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 https://:8000/gradio in your browser.

请注意,这种方法也允许你在自定义路径上运行 Gradio 应用(在上面的示例中为 https://: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")])

默认情况下,访问 /logout 会将用户从**所有会话**中注销(例如,如果他们从多个浏览器或设备登录,所有都会被注销)。如果你只想从**当前会话**中注销,请添加查询参数 all_session=false(即 /logout?all_session=false)。

注意:Gradio 的内置身份验证提供了一个简单直接的访问控制层,但对于需要严格访问控制(例如多因素身份验证、速率限制或自动锁定策略)的应用,它并不提供强大的安全功能。

OAuth(通过 Hugging Face 登录)

Gradio 原生支持通过 Hugging Face 进行 OAuth 登录。换句话说,你可以轻松地为你的演示添加一个“使用 Hugging Face 登录”按钮,该按钮允许你获取用户的 HF 用户名以及他们 HF 个人资料中的其他信息。请查看 此 Space 以获取实时演示。

要启用 OAuth,必须在你的 README.md 文件中将 hf_oauth: true 设置为 Space 元数据。这将把你的 Space 注册为 Hugging Face 上的 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()

当用户点击登录按钮时,他们会被重定向到一个新页面以授权你的 Space。

用户可以随时在他们的 设置中撤销对其个人资料的访问权限。

如上所示,OAuth 功能仅在你应用在 Space 中运行时可用。然而,在部署之前,你通常需要本地测试你的应用。要本地测试 OAuth 功能,你的机器必须登录到 Hugging Face。请运行 huggingface-cli login 或将 HF_TOKEN 设置为包含你的一个访问令牌的环境变量。你可以在你的设置页面 (https://hugging-face.cn/settings/tokens) 生成一个新令牌。然后,点击 gr.LoginButton 将登录到你的本地 Hugging Face 个人资料,使你可以在部署到 Space 之前使用你的 Hugging Face 帐户调试你的应用。

安全说明:重要的是要注意,添加 gr.LoginButton 并不会限制用户使用你的应用,这与添加 用户名-密码身份验证 的方式不同。这意味着你的应用用户,那些没有通过 Hugging Face 登录的用户,仍然可以访问和运行你的 Gradio 应用中的事件——区别在于,在相应的函数中,gr.OAuthProfilegr.OAuthToken 将为 None

OAuth(使用外部提供商)

你也可以使用外部 OAuth 提供商(例如 Google OAuth)在你的 Gradio 应用中进行身份验证。为此,首先将你的 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 应用。当然,这并没有增加多少安全性,因为任何用户都可以在其请求中添加此标头。

这是一个更完整的例子,展示了如何向 Gradio 应用添加 Google OAuth(假设你已经在 Google Developer Console 中创建了 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://#/.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 上试用此示例。

MCP 服务器

Gradio 应用可以作为 MCP(模型上下文协议)服务器运行,允许 LLM 使用你的应用函数作为工具。只需在 .launch() 方法中设置 mcp_server=True,Gradio 就会自动将你的应用函数转换为 MCP 工具,这些工具可以被 Claude Desktop、Cursor 或 Cline 等 MCP 客户端调用。服务器根据你的函数名称、文档字符串和类型提示公开工具,并可以处理文件上传、身份验证头和进度更新。你还可以使用 gr.api 创建仅限 MCP 的函数,并使用装饰器公开资源和提示。有关使用 Gradio 构建 MCP 服务器的全面指南,请参阅 使用 Gradio 构建 MCP 服务器

速率限制

在公开发布你的应用,并通过 API 或 MCP 服务器提供时,你可能需要设置速率限制以防止用户滥用你的应用。你可以使用 IP 地址(使用 gr.Request 对象,如上文讨论)来识别用户,或者如果他们通过 Hugging Face OAuth 登录,则使用他们的用户名。要查看设置速率限制的完整示例,请参阅 此 Gradio 应用

分析

默认情况下,Gradio 会收集某些分析数据,以帮助我们更好地理解 gradio 库的用法。这包括以下信息:

  • Gradio 应用运行的环境(例如,Colab Notebook、Hugging Face Spaces)
  • Gradio 应用中使用的输入/输出组件
  • Gradio 应用是否利用了某些高级功能,例如 authshow_error
  • IP 地址,仅用于衡量 Gradio 的唯一开发者数量
  • 正在运行的 Gradio 版本

不会从你的 Gradio 应用的*用户*那里收集任何信息。如果你想完全禁用分析,可以通过在 gr.Blocksgr.Interfacegr.ChatInterface 中将 analytics_enabled 参数设置为 False 来实现。或者,你可以将 GRADIO_ANALYTICS_ENABLED 环境变量设置为 "False",以将此应用到你系统上的所有 Gradio 应用。

注意:这反映了截至 gradio>=4.32.0 的分析策略。

渐进式 Web 应用 (PWA)

渐进式 Web 应用 (PWA) 是 Web 应用,它们是普通的网页或网站,但可以向用户显示为可安装的特定平台应用程序。

通过在 launch() 方法中设置 pwa=True 参数,Gradio 应用可以轻松地作为 PWA 提供。这是一个例子:

import gradio as gr

def greet(name):
    return "Hello " + name + "!"

demo = gr.Interface(fn=greet, inputs="textbox", outputs="textbox")

demo.launch(pwa=True)  # Launch your app as a PWA

这将生成一个可以在你的设备上安装的 PWA。它是这样的:

Installing PWA

当你在 launch() 方法中指定 favicon_path 时,该图标将用作应用的图标。这是一个例子:

demo.launch(pwa=True, favicon_path="./hf-logo.svg")  # Use a custom icon for your PWA

Custom PWA Icon

gradio