241217-Gradio-FastAPI-集成开发部署_android

A. 安装工具包

pip install fastapi gradio uvicorn

B. 方法1: 直接运行unicorn

# Import necessary libraries
from fastapi import FastAPI, Form
from fastapi.responses import HTMLResponse
import gradio as gr

# Initialize the FastAPI app
app = FastAPI()

# Define the GET endpoint with an HTML form
@app.get("/", response_class=HTMLResponse)
async def read_root():
    return """
    <form action="/submit" method="post">
        <input type="text" name="input_text" placeholder="Enter text">
        <button type="submit">Submit</button>
    </form>
    """

# Define the POST endpoint to handle form submissions
@app.post("/submit")
async def handle_form(input_text: str = Form(...)):
    return {"message": f"You entered: {input_text}"}

# Define the Gradio interface function
def gradio_interface(input_text):
    return f"You entered: {input_text}"

# Create the Gradio Interface
gradio_app = gr.Interface(
    fn=gradio_interface,
    inputs="text",
    outputs="text",
    title="Gradio with FastAPI",
    description="Enter text to see the response."
)

# Mount the Gradio app onto the FastAPI app
app = gr.mount_gradio_app(app, gradio_app, path="/gradio")

# To run the application, use the following command:
# uvicorn your_script_name:app --reload
  • uvicorn main:app --reload

C. 方法2: 直接运行python

  • main.py
# 导入必要的库
from fastapi import FastAPI, Form
from fastapi.responses import HTMLResponse
import gradio as gr
import uvicorn

# 初始化 FastAPI 应用
app = FastAPI()

# 定义 GET 端点,返回包含表单的 HTML
@app.get("/", response_class=HTMLResponse)
async def read_root():
    return """
    <form action="/submit" method="post">
        <input type="text" name="input_text" placeholder="输入文本">
        <button type="submit">提交</button>
    </form>
    """

# 定义 POST 端点,处理表单提交
@app.post("/submit")
async def handle_form(input_text: str = Form(...)):
    return {"message": f"您输入了: {input_text}"}

# 定义 Gradio 接口函数
def gradio_interface(input_text):
    return f"您输入了: {input_text}"

# 创建 Gradio 接口
gradio_app = gr.Interface(
    fn=gradio_interface,
    inputs="text",
    outputs="text",
    title="Gradio 与 FastAPI 集成",
    description="输入文本以查看响应。"
)

# 将 Gradio 应用挂载到 FastAPI 应用上
app = gr.mount_gradio_app(app, gradio_app, path="/gradio")

# 如果脚本是直接执行的,则启动 Uvicorn 服务器
if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
  • python main.py

D. 报错处理

  • 源代码
# 导入必要的库
from fastapi import FastAPI, Form
from fastapi.responses import HTMLResponse
import gradio as gr
import uvicorn

# 初始化 FastAPI 应用
app = FastAPI()

# 定义 GET 端点,返回包含表单的 HTML
@app.get("/", response_class=HTMLResponse)
async def read_root():
    return """
    <form action="/submit" method="post">
        <input type="text" name="input_text" placeholder="输入文本">
        <button type="submit">提交</button>
    </form>
    """

# 定义 POST 端点,处理表单提交
@app.post("/submit")
async def handle_form(input_text: str = Form(...)):
    return {"message": f"您输入了: {input_text}"}

# 定义 Gradio 接口函数
def gradio_interface(input_text):
    return f"您输入了: {input_text}"

# 创建 Gradio 接口
gradio_app = gr.Interface(
    fn=gradio_interface,
    inputs="text",
    outputs="text",
    title="Gradio 与 FastAPI 集成",
    description="输入文本以查看响应。"
)

# 将 Gradio 应用挂载到 FastAPI 应用上
app = gr.mount_gradio_app(app, gradio_app, path="/gradio")

# 如果脚本是直接执行的,则启动 Uvicorn 服务器
if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000, reload=True)
  • 报错信息
(test_gradio) [lgk@localhost TestGradio]$ python main.py 
WARNING:  You must pass the application as an import string to enable 'reload' or 'workers'.

您在运行代码时遇到了以下警告:

WARNING:  You must pass the application as an import string to enable 'reload' or 'workers'.

这是因为在使用 uvicorn.run() 时,启用了 reloadworkers 参数,但直接传递了应用实例 app。在这种情况下,Uvicorn 要求以字符串形式传递应用程序,以便能够正确地重新加载或使用多进程。

解决方法

  1. 确定文件名:假设您的文件名为 main.py,其中定义了 FastAPI 应用实例 app
  2. 修改 uvicorn.run() 调用:在 if __name__ == "__main__": 块中,将 uvicorn.run() 的第一个参数修改为字符串 "main:app",其中 "main" 是模块名(即文件名去掉 .py),"app" 是 FastAPI 实例的名称。

以下是修改后的完整代码:

  • gradio-interface风格代码
# 导入必要的库
from fastapi import FastAPI, Form
from fastapi.responses import HTMLResponse
import gradio as gr
import uvicorn

# 初始化 FastAPI 应用
app = FastAPI()

# 定义 GET 端点,返回包含表单的 HTML
@app.get("/", response_class=HTMLResponse)
async def read_root():
    return """
    <form action="/submit" method="post">
        <input type="text" name="input_text" placeholder="输入文本">
        <button type="submit">提交</button>
    </form>
    """

# 定义 POST 端点,处理表单提交
@app.post("/submit")
async def handle_form(input_text: str = Form(...)):
    return {"message": f"您输入了: {input_text}"}

# 定义 Gradio 接口函数
def gradio_interface(input_text):
    return f"您输入了: {input_text}"

# 创建 Gradio 接口
gradio_app = gr.Interface(
    fn=gradio_interface,
    inputs="text",
    outputs="text",
    title="Gradio 与 FastAPI 集成",
    description="输入文本以查看响应。"
)

# 将 Gradio 应用挂载到 FastAPI 应用上
app = gr.mount_gradio_app(app, gradio_app, path="/gradio")

# 如果脚本是直接执行的,则启动 Uvicorn 服务器
if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
  • gradio-blocks风格代码
# 导入必要的库
from fastapi import FastAPI, Form
from fastapi.responses import HTMLResponse
import gradio as gr
import uvicorn

# 初始化 FastAPI 应用
app = FastAPI()

# 定义 GET 端点,返回包含表单的 HTML
@app.get("/", response_class=HTMLResponse)
async def read_root():
    return """
    <form action="/submit" method="post">
        <input type="text" name="input_text" placeholder="输入文本">
        <button type="submit">提交</button>
    </form>
    """

# 定义 POST 端点,处理表单提交
@app.post("/submit")
async def handle_form(input_text: str = Form(...)):
    return {"message": f"您输入了: {input_text}"}

# 定义 Gradio 接口函数
def gradio_interface(input_text):
    return f"您输入了: {input_text}"

# 创建 Gradio 接口
# gradio_app = gr.Interface(
#     fn=gradio_interface,
#     inputs="text",
#     outputs="text",
#     title="Gradio 与 FastAPI 集成",
#     description="输入文本以查看响应。"
# )

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

with gr.Blocks() as gradio_app:
    #设置输入组件
    name = gr.Textbox(label="Name")
    # 设置输出组件
    output = gr.Textbox(label="Output Box")
    #设置按钮
    greet_btn = gr.Button("Greet")
    #设置按钮点击事件
    greet_btn.click(fn=greet, inputs=name, outputs=output)

# 将 Gradio 应用挂载到 FastAPI 应用上
app = gr.mount_gradio_app(app, gradio_app, path="/gradio")

# 如果脚本是直接执行的,则启动 Uvicorn 服务器
if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

注意事项

  • 确保文件名匹配uvicorn.run("main:app", ...) 中的 "main" 应与您的 Python 文件名(去掉 .py)一致。如果您的文件名是 my_app.py,则应使用 uvicorn.run("my_app:app", ...)
  • 关于 reload 参数reload=True 适用于开发环境,允许代码更改后自动重新加载服务器。在生产环境中,应将其设置为 False 或省略,以提高性能和稳定性。

通过上述修改,您可以直接运行 Python 脚本,启动包含 FastAPI 和 Gradio 的应用程序,并启用自动重载功能。
s

E. 命令解释

在您的 FastAPI 应用中,app = gr.mount_gradio_app(app, gradio_app, path="/gradio") 这一行代码的作用是将 Gradio 接口集成到现有的 FastAPI 应用中,使得 Gradio 界面可以通过指定的路径进行访问。

参数解析

  • app:这是您已创建的 FastAPI 应用实例。
  • gradio_app:这是您定义的 Gradio 接口或 Blocks 实例,用于提供交互式功能。
  • path="/gradio":指定 Gradio 接口在 FastAPI 应用中的访问路径。在此设置下,用户可以通过 http://your-domain.com/gradio 访问 Gradio 界面。

功能说明

通过调用 gr.mount_gradio_app() 函数,您可以将 Gradio 应用挂载到 FastAPI 应用的指定路径上。这意味着,任何对 http://your-domain.com/gradio 的请求都会被路由到 Gradio 接口,而 FastAPI 应用的其他路由不会受到影响。这种集成方式特别适用于在一个 Web 应用中同时提供 FastAPI 的 API 功能和 Gradio 的交互式界面。

示例代码

from fastapi import FastAPI
import gradio as gr

# 初始化 FastAPI 应用
app = FastAPI()

# 定义一个简单的 Gradio 接口函数
def greet(name):
    return f"你好,{name}!"

# 创建 Gradio 接口
gradio_app = gr.Interface(fn=greet, inputs="text", outputs="text")

# 将 Gradio 应用挂载到 FastAPI 应用的指定路径
app = gr.mount_gradio_app(app, gradio_app, path="/gradio")

# 运行应用
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

在上述代码中,FastAPI 应用的根路径 / 可以用于定义其他 API 端点,而 /gradio 路径则用于提供 Gradio 的交互式界面。这种集成方式使得您可以在同一个应用中同时提供 API 服务和用户友好的界面。

参考资料

通过这种方式,您可以有效地将 Gradio 的强大交互功能与 FastAPI 的高性能 API 服务相结合,构建功能丰富的 Web 应用。