Python POST multipart/formdata请求与Postman不同的行为

2024-09-30 22:19:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用此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函数中分配给fileskwarg时,库知道它应该是一个multipart/form-data请求

请求头的打印输出如下所示,显示库添加的Content-TypeContent-Length。我省略了auth标记

{'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" }

以下是邮递员请求标题:

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

邮递员请求在发送请求时还计算Content-TypeContent-Length头,并且不是用户指定的

我很困惑,为什么对于同一个请求,API服务会有两种不同的行为。 一定是我遗漏了什么,弄不清是什么


Tags: comapijsonapptypefilescontentresp
1条回答
网友
1楼 · 发布于 2024-09-30 22:19:35

与NodeJS和Postman相比,我发现我的请求有什么问题

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

当我更新我的文件参数时,上传开始完美工作,如下所示:

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

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

希望这对其他人也有帮助

相关问题 更多 >