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

使用Python requests复刻cURL multipart POST时遇415/400错误求助

问题分析与解决:requests复刻cURL multipart请求出错

问题背景

尝试用Python requests复刻指定cURL请求,已知不应手动设置"content-type": 'multipart/form-data'请求头,需由requests模块自动处理,但遇到两类错误:

  • 不手动添加该请求头时,返回HTTP 415错误:Unsupported media type
  • 手动添加该请求头时,返回HTTP 400错误:Missing initial multi part boundary

原cURL命令

curl -X POST \
  'https://example.com/v1/endpoint' \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -H 'Authorization: Bearer <BEARER_TOKEN_HERE>' \
  -F 'name=test5' \
  -F 'type=notebook' \
  -F 'content=@some-file.json;type=application/json'

自行编写的Python代码

headers = {
  "accept": "application/json",
  "Authorization": "Bearer <BEARER_TOKEN_REDACTED>"
}

with open(path, mode="r") as f:

    data = f.read()

    stuff = {
        "name": "test1",
        "type": "notebook",
        "content": f"{data};type=application/json"
    }

    upload_resp = requests.post(
        url="https://example.com/endpoint",
        data=stuff,
        headers=headers
    )

    return upload_resp

问题根源与修正方案

你存在三个关键错误:

  1. 请求参数使用错误:requests发送multipart/form-data类型请求时,文件类字段必须通过files参数传递,而非data参数——data仅适用于普通表单编码(application/x-www-form-urlencoded)的请求。
  2. 文件字段构造错误:cURL中@some-file.json;type=application/json的含义是上传指定文件并设置该字段的Content-Type,你直接拼接文件内容字符串的方式完全不符合multipart字段的格式要求。
  3. 请求路径不一致:你的代码中请求URL为https://example.com/endpoint,但原cURL的路径是https://example.com/v1/endpoint,路径不匹配也可能导致接口识别失败。

修正后的代码示例

方案一:普通字段与文件字段分离传递

普通表单字段放在data参数,文件字段放在files参数:

import requests

headers = {
    "accept": "application/json",
    "Authorization": "Bearer <BEARER_TOKEN_REDACTED>"
}

# 普通表单字段
form_fields = {
    "name": "test1",
    "type": "notebook"
}

# 文件字段采用元组格式:(文件名, 文件对象, 内容类型)
with open(path, mode="rb") as f:
    upload_files = {
        "content": ("some-file.json", f, "application/json")
    }

    upload_resp = requests.post(
        url="https://example.com/v1/endpoint",
        data=form_fields,
        files=upload_files,
        headers=headers
    )

# 可根据需求处理响应
print(upload_resp.status_code)
print(upload_resp.json())

方案二:所有字段统一放在files参数

若接口要求所有字段都在multipart表单中,可将普通字段也放入files,格式为(None, 字段值):

import requests

headers = {
    "accept": "application/json",
    "Authorization": "Bearer <BEARER_TOKEN_REDACTED>"
}

with open(path, mode="rb") as f:
    multipart_fields = {
        "name": (None, "test1"),
        "type": (None, "notebook"),
        "content": ("some-file.json", f, "application/json")
    }

    upload_resp = requests.post(
        url="https://example.com/v1/endpoint",
        files=multipart_fields,
        headers=headers
    )

# 可根据需求处理响应
print(upload_resp.status_code)
print(upload_resp.json())

额外注意事项

  • 打开文件必须使用rb(二进制只读)模式,避免文本编码导致文件内容损坏,确保和cURL上传的文件内容一致。
  • 绝对不要手动添加Content-Type: multipart/form-data请求头——requests会自动生成包含正确boundary的该头,手动添加会覆盖自动生成的boundary,导致接口无法解析请求,触发400错误。

内容的提问来源于stack exchange,提问作者A. Gardner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 11:03:40