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

如何使用Python HTTPX库发送等价于有效CURL请求的multipart/form-data POST请求至OpenGear REST API

如何使用Python HTTPX库发送等价于有效CURL请求的multipart/form-data POST请求至OpenGear REST API

我明白你遇到的问题了——你有一个能正常工作的curl命令,但用HTTPX尝试了几种POST方式都没成功,从Nginx日志来看,请求格式明显不对。咱们来一步步解决这个问题:

问题根源分析

你的curl命令用-F参数发送的是multipart/form-data格式的表单数据,curl会自动处理这个格式的核心细节:比如生成用于分隔字段的边界标识符(boundary)、自动设置带boundary的Content-Type头。但你的HTTPX代码犯了两个关键错误:

  • 手动设置Content-Type头:当你硬指定multipart/form-data时,HTTPX无法自动添加必要的boundary参数,服务器缺少这个标识就无法正确解析multipart数据。
  • 用错参数传递数据:你用data参数传递字段,但默认情况下HTTPX会把data编码成application/x-www-form-urlencoded格式,哪怕你改了Content-Type头,也不会生成符合要求的multipart结构。

正确的HTTPX实现代码

正确的做法是让HTTPX自动处理multipart格式的所有细节,不需要手动设置Content-Type头,而是用files参数来传递curl里用-F定义的字段(哪怕这些字段不是实际文件,HTTPX也会把它们当作multipart表单的普通字段处理):

# 假设你已经初始化好带会话的api_client对象
form_fields = {
    # 元组格式:(文件名, 字段值),非文件字段文件名设为None即可
    "firmware_url": (None, "https://example.com/path/to/file/file.name"),
    "firmware_options": (None, "-R")
}

# 发送请求,无需手动设置Content-Type
response = api_client.post(
    f"https://{SERVER}/api/v2/system/firmware_upgrade",
    files=form_fields
)

# 验证请求结果
print(f"响应状态码: {response.status_code}")
print(f"响应内容: {response.text}")

额外说明

如果你的api_client会话没有预先包含Authorization Token,记得在请求中添加对应的头:

headers = {"Authorization": f"Token {TOKEN}"}
response = api_client.post(
    f"https://{SERVER}/api/v2/system/firmware_upgrade",
    files=form_fields,
    headers=headers
)

为什么之前的尝试失败?

从你提供的Nginx日志就能看出问题:

  • 使用raw data dict时,HTTPX把数据编码成了urlencoded格式,但你手动设置了multipart的Content-Type,服务器拿到格式不匹配的数据,直接返回400错误,甚至出现了把请求体误当作单独URL请求的异常情况。
  • JSON dumps的方式完全不符合服务器期望的multipart表单格式,自然无法被正确解析。

备注:内容来源于stack exchange,提问作者krizzo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 15:14:29