[英]send multipart upload with json
I'm trying to upload a video file along with some JSON using a REST API with requests in Python. 我正在尝试使用REST API和Python中的请求上传视频文件以及一些JSON。
Here is the example cURL for the request. 这是请求的示例cURL。
curl -XPOST -i "https://io.cimediacloud.com/upload" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-F filename=@Movie.mov
-F metadata="{ 'metadata' : { 'Resolution' : '1080p', 'Language' : 'English' },
'workspaceId' : 'a585b641a60843498543597d16ba0108', 'folderId' :
'a585b641a60843498543597d16ba0108' }"
And here is my code. 这是我的代码。
url = 'https://io.cimediacloud.com/upload'
files = {'file': ('video.mp4', open('files/video.mp4', 'rb')),
}
data = {'metadata': {'Resolution' : '1080p', 'Language' : 'English'},
'workspaceId': your_workspace_id,
'folderId': folder_id,}
r = session.post(url, files=files, data=data)
When I run this, the API server returns a MissingOrInvalidFileName error. 当我运行此命令时,API服务器返回MissingOrInvalidFileName错误。 If I leave out my data parameter, the file uploads correctly. 如果我遗漏了data参数,则文件将正确上传。 What is the correct way to make this request? 发出此请求的正确方法是什么?
Your file parameter is called filename
in the curl request, and the metadata
part should be a string (encoded to JSON); 您的文件参数在curl请求中称为filename
, metadata
部分应为字符串(编码为JSON); it is one field and has a nested metadata
object. 它是一个字段,并且具有嵌套的 metadata
对象。 wordspaceId
and folderId
are keys in the outermost metadata
object, not separate parameters: wordspaceId
和folderId
位于最外面的键metadata
对象,而不是单独的参数:
import json
files = {'filename': ('video.mp4', open('files/video.mp4', 'rb')),
metadata = {
'metadata': {'Resolution': '1080p', 'Language': 'English'},
'workspaceId': your_workspace_id,
'folderId': folder_id
}
data = {'metadata': json.dumps(metadata)}
r = session.post(url, files=files, data=data)
Finally solved! 终于解决了! Turns out requests encodes its multipart with data then files while the API required files then data. 最终,请求使用数据然后是文件对它的多部分进行编码,而API则需要先对数据进行编码。
@Martijn Pieters's solution of inputting all of the data as tuples almost works. @Martijn Pieters将所有数据输入为元组的解决方案几乎可以正常工作。 The only problem is setting the data this way breaks requests' ability to set the content-type header automatically (it thinks my data is content-type application/json). 唯一的问题是以这种方式设置数据会破坏请求自动设置content-type标头的能力(它认为我的数据是content-type application / json)。
In the end, I used request-toolbelt 's MultipartEncoder which allows me to order my multipart body using tuples and saves the content-type in its instance. 最后,我使用了request-toolbelt的MultipartEncoder,它使我可以使用元组对多部分主体进行排序,并将content-type保存在其实例中。 Here is the final working code. 这是最终的工作代码。
m = MultipartEncoder([('filename', ('video.mp4', open('files/video.mp4', 'rb'))),
('metadata', json.dumps(metadata))])
r = session.post(url, data=m, headers={'Content-Type': m.content_type})
Finally works. 终于可以了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.