我正在尝试使用带有Python的请求的REST API上传视频文件和一些JSON。
以下是请求的示例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' }"
这是我的代码。
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)
当我运行它时,API服务器返回MissingOrInvalidFileName错误。如果我省略了我的数据参数,则文件正确上传。提出此请求的正确方法是什么?
答案 0 :(得分:2)
你的文件参数在curl请求中被称为filename
,而metadata
部分应该是一个字符串(编码为JSON);它是一个字段,并且有一个嵌套 metadata
对象。 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)
答案 1 :(得分:1)
@Martijn Pieters将输入所有数据作为元组的解决方案几乎可行。唯一的问题是以这种方式设置数据会破坏请求自动设置内容类型标头的能力(它认为我的数据是内容类型的应用程序/ json)。
最后,我使用了request-toolbelt的MultipartEncoder,它允许我使用元组对我的多部分主体进行排序,并将内容类型保存在其实例中。这是最终的工作代码。
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})
终于有效了。