【问题标题】:Python POST multipart/form-data request different behavior from PostmanPython POST multipart/form-data 请求 Postman 的不同行为
【发布时间】:2021-01-05 14:14:18
【问题描述】:

我正在尝试使用此 API 端点上传文件:

https://h.app.wdesk.com/s/cerebral-docs/?python#uploadfileusingpost

有了这个python函数:

def upload_file(token, filepath, table_id):
    url = "https://h.app.wdesk.com/s/wdata/prep/api/v1/file"
    headers = {
        'Accept': 'application/json',
        'Authorization': f'Bearer {token}'
    }

    files = {
        "tableId": (None, table_id),
        "file": open(filepath, "rb")
    }
    resp = requests.post(url, headers=headers, files=files)
    print(resp.request.headers)
    return resp.json()

Content-TypeContent-Length 标头由请求库内部根据其文档计算和添加。在post 函数中分配给files kwarg 时,库知道它应该是multipart/form-data 请求。

请求头的打印输出如下,显示了库添加的Content-TypeContent-Length。我省略了身份验证令牌。

{'User-Agent': 'python-requests/2.24.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive',
'Authorization': 'Bearer <omitted>', 'Content-Length': '8201', 'Content-Type': 'multipart/form-data; boundary=bb582b9071574462d44c4b43ec4d7bf3'}

来自 API 的 json 响应是:

{'body': ['contentType must not be null'], 'code': 400}

奇怪的是,当通过 Postman 发出相同的请求时,会给出不同的响应——这也是我对 Python 的期望。

{ "code": 409, "body": "duplicate file name" }

这些是 Postman 请求标头:

POST /s/wdata/prep/api/v1/file HTTP/1.1
Authorization: Bearer <omitted>
Accept: */*
Cache-Control: no-cache
Postman-Token: 34ed08d4-4467-4168-a4e4-c83b16ce9afb
Host: h.app.wdesk.com
Content-Type: multipart/form-data; boundary=--------------------------179907322036790253179546
Content-Length: 8279

Postman 请求还会在发送请求时计算 Content-TypeContent-Length 标头,并且不是用户指定的。

我很困惑为什么我会从 API 服务中获得两种不同的行为来处理同一个请求。 一定有什么我错过了,无法弄清楚它是什么。

【问题讨论】:

    标签: python python-3.x python-requests postman multipartform-data


    【解决方案1】:

    与 NodeJS 和 Postman 相比,找出我的请求有什么问题。

    API 错误消息中提到的contentType 是文件参数的内容类型,而不是http 请求标头Content-Type

    当我像这样更新我的文件参数时,上传开始完美无缺:

    files = {
            "tableId": (None, table_id),
            "file": (Path(filepath).name, open(filepath, "rb"), "text/csv", None)
        }
    

    我了解到 Python 的请求库不会自动将文件的 mime 类型添加到请求正文中。我们需要明确说明。

    希望这对其他人也有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多