使用FastAPI整合Gradio和Jinja2

306 阅读3分钟

大家好,我是每天分享AI应用的萤火君!

前端时间我使用FastAPI整合了Gradio和Django,让它们跑在一个进程中,使用同一个端口,分享文章在这里:

使用FastAPI整合Gradio和Django

不过在后来的使用过程中,我发现Django还是太重了,很多东西我也用不上,改起来还有点麻烦(比如启用静态文件),而我的需求只是需要一个能开发Web页面的框架,尽可能轻量级一些。

经过一番探索,找到了Jinja2这个模版引擎,用起来特别简单。这篇文章就给大家介绍下使用FastAPI整合Gradio和Jinja2的方法。

Jinja2

Jinja2 是一个 Python 的现代且设计者友好的模板引擎,它广泛应用于各种 Web 框架,尤其是 Flask 和 Starlette。Jinja2 的主要目的是将动态内容插入到 HTML、XML 或其他文本格式的模板中,从而生成最终的输出文件。

因为FastAPI使用 Starlette 来处理 ASGI 请求,而Starlette内部集成了Jinja2,所以我们使用了FastAPI框架,就可以直接使用Jinja2了。

安装 FastAPI 的命令:

pip install fastapi

如果你的项目中没有安装 Starlette 或者想要安装最新版本,可以使用这个命令:

pip install starlette

Gradio项目

为了演示,这里准备一个Gradio的程序。

如果还没有安装 Gradio,先执行这个命令:

pip install gradio

编写一个Gradio文件,假设文件路径为:gradio/app.py,内容如下:

import gradio as gr

def greet(name):
    return f"Hello {name}!"

# 定义 Gradio 接口
demo = gr.Interface(fn=greet, inputs="text", outputs="text")

整合Gradio和Jinja2

首先创建一个静态模版文件,假设路径是:templates/index.html,内容如下:

<!DOCTYPE html>
<html>
<head>
    <title>Gradio in Jinja2</title>
</head>
<body>
    <h1>Hello, {{ name }} </h1>
</body>
</html>

其中 {{ name }} 是输出名为name的模版变量,这个变量需要在根据模版生成HTML时传入,下边会有介绍。

然后创建主程序文件,假设路径是:main.py,内容如下:

# app/main.py
from fastapi import FastAPI
from starlette.templating import Jinja2Templates
from starlette.requests import Request
from gradio.app import demo

app = FastAPI()

# 设置静态文件的目录
app.mount("/static", StaticFiles(directory="static"), name="static")

# 挂载 Gradio 到 FastAPI
app = gr.mount_gradio_app(app, demo, path="/gradio")

# 设置 Jinja2 的模板目录
templates = Jinja2Templates(directory="templates")

@app.get("/")
async def read_root(request: Request):
    context = {
        'request':request,
        'name':'萤火君',
    }
    return templates.TemplateResponse("index.html", context)

大概介绍下这个文件,它主要干了三件事:

1、设置静态文件的目录为 static,这样我们就可以在浏览器通过路径 /static/xxx.yyy 访问到静态文件。

2、将Gradio程序挂载到FastAPI,这样我们就可以在浏览器通过路径 /gradio 访问到原来的Gradio页面。

3、注册一个FastAPI路由:/ ,访问它时,程序会使用Jinja2模版引擎创建一个HTML页面,并返回到浏览器。

使用模版引擎的方法:

首先通过创建 Jinja2Templates 的实例设置了模版文件的根目录:

templates = Jinja2Templates(directory="templates")

然后在处理模版页面时传递了模版文件名称和一个字典,其中字典内容为:

  • request 是模版引擎必需的,它是当前HTTP请求的上下文;
  • name 是业务自定义的参数,可以在HTML模版中输出它的值。

我们可以在这个字典中增加更多自定义变量,用来渲染HTML页面的内容。

最后使用 uvicorn 启动程序:

uvicorn main:app

这样我们就可以在原有Gradio项目中快速开发新的样式更加美好的原生HTML页面了。

总结

本文分享了一种整合 即有Gradio程序 和 Jinja2 模版引擎 的方法,在这种方法下,Gradio 和 Jinja2 可以使用同一个进程,使用相同的端口号对外服务,同时Gradio程序使用子目录 /gradio 进行访问,Jinja2开发的页面使用根目录 / 进行访问。

因本人对 Gradio 和 Jinja2 的了解有限,文中介绍的方法可能存在瑕疵,请谨慎测试、使用。

关注萤火架构,加速技术提升!