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

FastAPI可接收Python客户端请求但Postman请求失败求助

FastAPI接口Postman请求失败问题排查与解决思路

问题背景

我实现了一个支持接收表单文本与多图片文件的FastAPI接口,Python客户端请求正常,但用Postman发送请求时失败,日志显示:

INFO: 127.0.0.1:58121 - "POST /generate_chart/ HTTP/1.1" 307 Temporary Redirect
Did not find boundary character 137 at index 2
INFO: 127.0.0.1:58122 - "POST /generate_chart HTTP/1.1" 400 Bad Request

接口代码

from fastapi import FastAPI, Form, File, UploadFile
from typing import List,Dict
import os
import campaign_begin
import shutil


app = FastAPI()

@app.post("/generate_chart")
async def generate_chart(
        company_retailer: str = Form(...),
        ad_lvl_count: int = Form(...),
        ad_level_name_list: list = Form(...),
        analytics_cat_type: str = Form(...),
        discount_flag: bool = Form(...),
        discount_adlevel: str = Form(...),
        discount_checkout_type: str = Form(...),
        optimization_checkout_type: str = Form(...),
        optimization_adlevel: str = Form(...),
        market_type_name_checkout: str = Form(...),
        a_b_test_flag: bool = Form(...),
        ab_adlevel: str = Form(...),
        tableau_name_checkout: str = Form(...),
        clip_count: int = Form(...),
        w_id: str = Form(...),
        ad_level_images: List[UploadFile] = File(...),
        clip_images: List[UploadFile] = File(...)

):

    for index, ad_image in enumerate(ad_level_images):
        with open(f"pic{index + 1}.jpg", "wb") as buffer:
            shutil.copyfileobj(ad_image.file, buffer)

    for index, clip_image in enumerate(clip_images):
        with open(f"clip{index + 1}.jpg", "wb") as buffer:
            shutil.copyfileobj(clip_image.file, buffer)

    # Call campaign_begin.generate_chart() function
    campaign_begin.generate_chart(
        company_retailer=company_retailer,
        ad_lvl_count=ad_lvl_count,
        ad_level_name_list=ad_level_name_list,
        analytics_cat_type=analytics_cat_type,
        discount_flag=discount_flag,
        discount_adlevel=discount_adlevel,
        discount_checkout_type=discount_checkout_type,
        optimization_checkout_type=optimization_checkout_type,
        optimization_adlevel=optimization_adlevel,
        market_type_name_checkout=market_type_name_checkout,
        a_b_test_flag=a_b_test_flag,
        ab_adlevel=ab_adlevel,
        tableau_name_checkout=tableau_name_checkout,
        clip_count=clip_count,
        w_id=w_id
    )


    return {"status": "success"}

正常工作的Python客户端代码

import requests

url = "http://localhost:8000/generate_chart/"

data = {
    "company_retailer": "Dummy_Company",
    "ad_lvl_count": 2,
    "ad_level_name_list": ["dummy_adlevel_1", "dummy_adlevel_2"],
    "analytics_cat_type": "Trolley + All",
    "discount_flag": True,
    "discount_adlevel": "dummy_adlevel_1",
    "discount_checkout_type": "Trolley + All",
    "optimization_checkout_type": "only-trolley",
    "optimization_adlevel": "dummy_adlevel_1",
    "market_type_name_checkout": "only-trolley",
    "a_b_test_flag": True,
    "ab_adlevel": "dummy_adlevel_1",
    "tableau_name_checkout": "only-trolley",
    "clip_count": 2,
    "w_id": '6485klo-5477'
}

files = [
    ("ad_level_images", ("pic1.jpg", open("pic1.jpg", "rb"), "image/jpeg")),
    ("ad_level_images", ("pic2.jpg", open("pic2.jpg", "rb"), "image/jpeg")),
    ("clip_images", ("clip1.jpg", open("clip1.jpg", "rb"), "image/jpeg")),
    ("clip_images", ("clip2.jpg", open("clip2.jpg", "rb"), "image/jpeg")),
]


response = requests.post(url, data=data, files=files)

print(response.json())

错误原因分析

  1. 307重定向问题:FastAPI默认会对带尾部斜杠的URL(/generate_chart/)重定向到不带斜杠的路径,Postman处理重定向时未正确复用原请求的multipart表单数据,导致边界字符丢失。
  2. 边界字符错误:日志中的Did not find boundary character说明Postman发送的请求中,multipart/form-data的边界标识不正确,大概率是手动设置了Content-Type头,破坏了自动生成的边界值。
  3. 列表参数传递问题:ad_level_name_list是列表类型,Postman传递表单列表的方式与requests库不同,若格式错误会导致解析失败。

解决方案步骤

1. 修正请求URL

直接使用不带尾部斜杠的URL:http://localhost:8000/generate_chart,避免触发307重定向。

2. 正确配置Postman表单参数

  • 选择POST请求,切换到Body标签,选择form-data类型。
  • 文本参数设置:
    • 普通字符串/数字/布尔值:直接填写Key和对应Value,比如discount_flag填小写的true,ad_lvl_count填2。
    • 列表参数(ad_level_name_list):添加多个相同Key的条目,分别填入列表的每个元素,比如两次添加Key为ad_level_name_list,Value依次为dummy_adlevel_1和dummy_adlevel_2,FastAPI会自动解析为列表。
  • 文件参数设置:
    • 对于ad_level_images:添加多个Key为ad_level_images的条目,类型选择File,再选择对应图片文件,Postman会自动设置正确的文件Content-Type。
    • 同理,clip_images也添加多个相同Key的文件条目。

3. 禁止手动设置Content-Type头

Postman选择form-data后会自动生成包含正确边界字符的Content-Type: multipart/form-data; boundary=xxx头,手动设置会覆盖该值,导致解析错误。

4. 可选:禁用FastAPI重定向

如果需要支持带斜杠的URL,可以创建FastAPI实例时关闭重定向:

app = FastAPI(redirect_slashes=False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:55:07