Gradio 代理与 MCP 黑客马拉松

获奖者
Gradio logo
  1. 自定义组件
  2. PDF 组件示例

案例研究:一个显示 PDF 的组件

让我们通过一个示例来构建一个用于显示 PDF 文件的自定义 Gradio 组件。该组件将方便展示文档问答模型,这些模型通常以 PDF 作为输入。这是我们完成后的组件外观预览

demo

步骤 0:先决条件

请确保您已安装 Gradio 5.0 或更高版本以及 Node 20+。截至发布时,最新版本为 4.1.1。此外,请在开始之前阅读自定义组件的五分钟教程关键概念指南。

步骤 1:创建自定义组件

导航到您选择的目录并运行以下命令

gradio cc create PDF

提示:您应该更改组件的名称。一些屏幕截图假设组件名为 `PDF`,但概念是相同的!

这将在您当前的工作目录中创建一个名为 `pdf` 的子目录。`pdf` 中有三个主要子目录:`frontend`、`backend` 和 `demo`。如果您在代码编辑器中打开 `pdf`,它将看起来像这样

directory structure

提示: 对于此演示,我们没有基于现有 Gradio 组件进行模板化。但您可以使用 `gradio cc show` 查看可用模板列表,然后将模板名称传递给 `--template` 选项,例如 `gradio cc create`--template`

步骤 2:前端 - 修改 JavaScript 依赖

我们将使用 pdfjs JavaScript 库在前端显示 PDF。让我们首先将其添加到前端项目的依赖项中,同时添加我们需要的其他几个项目。

在 `frontend` 目录中,运行 `npm install @gradio/client @gradio/upload @gradio/icons @gradio/button` 和 `npm install --save-dev pdfjs-dist@3.11.174`。另外,通过运行 `npm uninstall @zerodevx/svelte-json-view` 来卸载 `@zerodevx/svelte-json-view` 依赖。

完整的 `package.json` 应该像这样

{
  "name": "gradio_pdf",
  "version": "0.2.0",
  "description": "Gradio component for displaying PDFs",
  "type": "module",
  "author": "",
  "license": "ISC",
  "private": false,
  "main_changeset": true,
  "exports": {
    ".": "./Index.svelte",
    "./example": "./Example.svelte",
    "./package.json": "./package.json"
  },
  "devDependencies": {
    "pdfjs-dist": "3.11.174"
  },
  "dependencies": {
    "@gradio/atoms": "0.2.0",
    "@gradio/statustracker": "0.3.0",
    "@gradio/utils": "0.2.0",
    "@gradio/client": "0.7.1",
    "@gradio/upload": "0.3.2",
    "@gradio/icons": "0.2.0",
    "@gradio/button": "0.2.3",
    "pdfjs-dist": "3.11.174"
  }
}

提示: 运行 `npm install` 将安装可用软件包的最新版本。您可以使用 `npm install package@` 安装特定版本。`. 您可以在[此处](https://gradio.org.cn/docs/js)找到 Gradio JavaScript 软件包的所有文档。建议您使用与我相同的版本,因为 API 可能会发生变化。

导航到 `Index.svelte` 并删除对 `JSONView` 的引用

import { JsonView } from "@zerodevx/svelte-json-view";
<JsonView json={value} />

步骤 3:前端 - 启动开发服务器

运行 `dev` 命令以启动开发服务器。这将在一个环境中打开 `demo/app.py` 中的演示,其中对 `frontend` 和 `backend` 目录的更改将即时反映在已启动的应用中。

启动开发服务器后,您应该会在控制台看到一个链接,显示 `Frontend Server (Go here): ... `。

您应该会看到以下内容

它现在看起来还不怎么样,但我们已经准备好开始编码了!

步骤 4:前端 - 基本骨架

我们将首先编写前端骨架,然后添加 PDF 渲染逻辑。在文件顶部的 `` 标签下方,删除所有当前代码并添加以下内容

<Block {visible} {elem_id} {elem_classes} {container} {scale} {min_width}>
    {#if loading_status}
        <StatusTracker
            autoscroll={gradio.autoscroll}
            i18n={gradio.i18n}
            {...loading_status}
        />
    {/if}
    <BlockLabel
        show_label={label !== null}
        Icon={File}
        float={value === null}
        label={label || "File"}
    />
    {#if _value}
        <ModifyUpload i18n={gradio.i18n} absolute />
    {:else}
        <Upload
            filetype={"application/pdf"}
            file_count="single"
            {root}
        >
            Upload your PDF
        </Upload>
    {/if}
</Block>

保存当前更改后,当您导航到应用程序时,您应该会看到以下内容

步骤 5:前端 - 更友好的上传文本

“上传您的 PDF”文本看起来有点小且简陋。让我们自定义它!

创建一个名为 `PdfUploadText.svelte` 的新文件并复制以下代码。它正在创建一个新的 div,用于显示我们带有自定义样式的“上传文本”。

提示: 请注意,我们在这里利用了 Gradio 核心现有的 CSS 变量:`var(--size-60)` 和 `var(--body-text-color-subdued)`。这使得我们的组件在亮色模式和暗色模式下以及 Gradio 内置主题下都能很好地工作。

<script lang="ts">
	import { Upload as UploadIcon } from "@gradio/icons";
	export let hovered = false;

</script>

<div class="wrap">
	<span class="icon-wrap" class:hovered><UploadIcon /> </span>
    Drop PDF
    <span class="or">- or -</span>
    Click to Upload
</div>

<style>
	.wrap {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		min-height: var(--size-60);
		color: var(--block-label-text-color);
		line-height: var(--line-md);
		height: 100%;
		padding-top: var(--size-3);
	}

	.or {
		color: var(--body-text-color-subdued);
		display: flex;
	}

	.icon-wrap {
		width: 30px;
		margin-bottom: var(--spacing-lg);
	}

	@media (--screen-md) {
		.wrap {
			font-size: var(--text-lg);
		}
	}

	.hovered {
		color: var(--color-accent);
	}
</style>

现在在您的 `