You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI如何获取POST接口后台任务返回值并传入Jinja2 HTML模板

FastAPI猫狗分类应用问题解决方案

1. 后台任务无法获取返回值问题

核心原因:FastAPI的BackgroundTasks设计目的是在响应完全返回给客户端之后再执行异步任务,不会将任务的返回值传递给当前请求的响应流程,因此你无法直接通过background_tasks.add_task的返回值拿到预测结果,这和你的需求「拿到预测结果返回给用户」本质冲突。
你注释里写的「无论图片数据处理耗时多久,都可以先返回响应」如果是真实需求,你需要额外引入状态存储(比如Redis)存储任务ID与预测结果的映射,先给用户返回任务ID,前端通过定时轮询接口拉取最终结果,属于异步交互方案。
但猫狗分类预测属于毫秒级耗时任务,完全不需要用后台任务,直接调用预测函数即可,这也是最符合你当前需求的解决方案。

2. POST请求下Jinja2模板渲染实现

你之前的代码有两个错误导致模板无法渲染:

  • 将模板目录Templates挂载为了静态资源目录,FastAPI会优先返回静态html文件,不会解析模板变量
  • POST接口没有调用Jinja2的模板渲染方法,也没有传入必填的Request对象

修改后的完整代码

后端代码

from starlette.responses import RedirectResponse
from fastapi.templating import Jinja2Templates
from fastapi import FastAPI, File, UploadFile, Request
from tensorflow.keras import preprocessing
from fastapi.staticfiles import StaticFiles
from keras.models import load_model
from PIL import Image
import numpy as np
import uvicorn

app = FastAPI()
# 静态资源单独挂载到static目录,不要和模板目录混用
app.mount("/static", StaticFiles(directory="static"), name="static")
# 模板目录单独配置
templates = Jinja2Templates(directory="templates")

model_dir = 'F:\\Saved-Models\\Dog-Cat-Models\\json_function_test_dog_cat_optuna.h5'
model = load_model(model_dir)


def predict_image(image):
    pp_dogcat_image = Image.open(image.file).resize((150, 150), Image.NEAREST).convert("RGB")
    pp_dogcat_image_arr = preprocessing.image.img_to_array(pp_dogcat_image)
    input_arr = np.array([pp_dogcat_image_arr])
    prediction = np.argmax(model.predict(input_arr), axis=-1)

    if str(prediction) == '[1]':
        answer = "It's a Dog"
    else:
        answer = "It's a Cat"

    return answer


@app.get('/')
async def index():
    # 首页重定向到渲染后的模板页,不是静态文件
    return RedirectResponse(url="/prediction_page")

# 同时支持GET和POST请求,GET返回空表单,POST返回带结果的页面
@app.get('/prediction_page')
async def show_form(request: Request):
    return templates.TemplateResponse("prediction.html", {"request": request, "answer": ""})

@app.post('/prediction_page')
async def prediction_form(request: Request, dogcat_img: UploadFile = File(...)):
    # 直接调用预测函数拿到结果
    answer = predict_image(dogcat_img)
    # 返回渲染后的模板,传入预测结果
    return templates.TemplateResponse("prediction.html", {"request": request, "answer": answer})


if __name__ == '__main__':
    uvicorn.run(app, host='localhost', port=8000)

目录结构调整

  • 新建templates文件夹,将你的html文件存入该目录,命名为prediction.html
  • 新建static文件夹,存放css、js、图片等静态资源

前端代码(templates/prediction.html)

<!DOCTYPE html>
<html>
<head>
    <title>猫狗分类预测</title>
</head>
<body>
<div class="prediction_box"><p>Select an image of a dog or a cat and the AI will print out a prediction of what he
    thinks
    it is.....</p><br>

    <!--enctype="multipart/form-data" 允许UploadFile类型数据传输-->
    <form action="/prediction_page" enctype="multipart/form-data" method="post">
        <label for="image-upload" class="custom-file-upload">Select Image:</label>
        <input type="file" id="image-upload" name="dogcat_img"><br>
        <input class="custom-submit-button" type="submit">
    </form>

    <p>{{answer}}</p>
</div>
</body>
</html>

运行说明

启动服务后访问http://localhost:8000即可进入预测页面,上传图片提交后会直接在当前页面显示预测结果。

内容的提问来源于stack exchange,提问作者Luleo_Primoc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 12:57:03