1. 附加功能
  2. 文件访问

安全与文件访问

与他人共享您的 Gradio 应用程序(通过托管在 Spaces、您自己的服务器上,或通过临时共享链接)会暴露您机器上的某些文件到互联网。被暴露的文件可以通过一个特殊的 URL 进行访问。

http://<your-gradio-app-url>/gradio_api/file=<local-file-path>

本指南解释了哪些文件会被暴露,以及确保您机器上的文件安全的一些最佳实践。

Gradio 允许用户访问的文件

  • 1. 静态文件。您可以使用 gr.set_static_paths 函数指定静态文件或目录。静态文件不会被复制到 Gradio 缓存(见下文),而是直接从您的计算机提供服务。这有助于节省磁盘空间并减少应用程序启动时间,但请注意可能的安全隐患,因为所有 Gradio 应用程序的用户都可以访问任何静态文件。

  • 2. launch() 函数中 allowed_paths 参数中的文件。此参数允许您传入一个额外的目录或精确文件路径列表,您希望允许用户访问这些文件。(默认情况下,此参数为空列表)。

  • 3. Gradio 缓存中的文件。在您启动 Gradio 应用程序后,Gradio 会将某些文件复制到一个临时缓存中,并使这些文件可供用户访问。下面我们将详细解释这一点。

Gradio 缓存

首先,了解 Gradio 为什么需要缓存是很重要的。Gradio 在将文件返回给前端之前,会将其复制到缓存目录。这可以防止在应用程序的一个用户仍需要文件时,文件被另一个用户覆盖。例如,如果您的预测函数返回一个视频文件,那么 Gradio 会在您的预测函数运行后将该视频移动到缓存中,并返回一个前端可以用来显示视频的 URL。缓存中的任何文件都可以通过 URL 供所有正在运行的应用程序用户访问。

您可以通过将 GRADIO_TEMP_DIR 环境变量设置为绝对路径(例如 /home/usr/scripts/project/temp/)来自定义缓存位置。

Gradio 移动到缓存的文件

Gradio 将三类文件移动到缓存中:

  1. 开发者在运行时之前指定的文件,例如缓存的示例、组件的默认值,或传递给参数的文件(如 gr.Chatbotavatar_images)。

  2. 您的 Gradio 应用程序中的预测函数返回的文件路径,如果它们也满足以下条件之一:

  • 它在 Blocks.launch 方法的 allowed_paths 参数中。
  • 它在 Python 解释器的当前工作目录中。
  • 它在通过 tempfile.gettempdir() 获取的临时目录中。

注意:当前工作目录中名称以句点(.)开头的文件,即使它们是从预测函数返回的,也不会被移动到缓存中,因为它们通常包含敏感信息。

如果以上条件均未满足,返回该文件的预测函数将抛出异常,而不是将文件移动到缓存。Gradio 执行此检查是为了防止您的机器上的任意文件被访问。

  1. 用户上传到您的 Gradio 应用程序的文件(例如通过 FileImage 输入组件上传)。

    如果在任何时候 Gradio 阻止了您希望它处理的文件,请将其路径添加到 allowed_paths 参数中。

Gradio 不允许他人访问的文件

在运行时,Gradio 应用程序将不允许用户访问以下文件:

  • 您通过 launch() 函数中的 blocked_paths 参数明确阻止的文件。您可以将额外的目录或精确文件路径列表传递给 launch() 中的 blocked_paths 参数。此参数优先于 Gradio 默认暴露的文件,或通过 allowed_paths 参数或 gr.set_static_paths 函数暴露的文件。

  • 主机上的任何其他路径。用户不应能够访问主机上的其他任意路径。

上传文件

共享 Gradio 应用程序也会允许用户上传文件到您的计算机或服务器。您可以设置上传文件的最大文件大小,以防止滥用并保留磁盘空间。您可以通过 .launchmax_file_size 参数来设置。例如,以下两个代码片段将文件上传限制为每个文件 5 兆字节。

import gradio as gr

demo = gr.Interface(lambda x: x, "image", "image")

demo.launch(max_file_size="5mb")
# or
demo.launch(max_file_size=5 * gr.FileSize.MB)

最佳实践

  • 为您的应用程序设置 max_file_size
  • 不要将任意用户输入从连接到基于文件的输出组件(gr.Imagegr.File 等)的函数返回。例如,以下接口将允许任何人将您本地目录中的任意文件移动到缓存中:gr.Interface(lambda s: s, "text", "file")。这是因为用户输入被视为任意文件路径。
  • 使 allowed_paths 尽可能小。如果 allowed_paths 中的路径是一个目录,则该目录中的任何文件都可以被访问。确保 allowed_paths 的条目只包含与您的应用程序相关的文件。
  • 从应用程序文件所在的同一目录运行 Gradio 应用程序。这将缩小 Gradio 允许移动到缓存中的文件范围。例如,最好使用 python app.py 而不是 python Users/sources/project/app.py

示例:访问本地文件

gr.set_static_paths 和 launch 中的 allowed_paths 参数都期望使用绝对路径。下面是一个最小示例,用于在 HTML 块中显示本地 .png 图像文件。

├── assets
│   └── logo.png
└── app.py

对于示例目录结构,在 app.py 中可以按如下方式访问 assets 文件夹中的 logo.png 和任何其他文件:

from pathlib import Path

import gradio as gr

gr.set_static_paths(paths=[Path.cwd().absolute()/"assets"])

with gr.Blocks() as demo:
    gr.HTML("<img src='/gradio_api/file=assets/logo.png'>")

demo.launch()
gradio