Zenodo: 无法通过 API 将较大的文件上传到沙箱

创建于 2016-09-26  ·  6评论  ·  资料来源: zenodo/zenodo

你好呀,

当我尝试使用以下代码通过 python 请求和 Zenodo API(沙箱)上传大于 100 MB 的测试文件时

data = {'filename': 'test.zip'}
files = {'file': open(filename, 'rb')}
r = requests.post("https://sandbox.zenodo.org/api/deposit/depositions/%s/files?access_token=TOKEN" % deposition_id, data=data, files=files)

它返回 http 错误代码413 (“413 请求实体太大”,顺便说一句,zenodo API 文档中没有记录)。

对小于 100 MB 的文件进行测试的相同代码有效并返回201

我是否已达到文件大小限制? (如果是这样,最好将其添加到文档中)。 或者这可能是由于“请求”包 - 我是否必须将数据分成多个部分?

Enhancement

最有用的评论

以防万一有人遇到这个问题,这里有一些 Python 可以使用新的 API 来完成文件上传部分。 这相当于上面概述的用于上传单个文件的 CURL 调用。 我已经用 160MB 的文件对其进行了测试,但该文件的 API失败了。 这也使用请求(文档化 API 使用的)并简单地进行新提交并上传文件。 请注意,使用的 URL 是沙盒 URL。

import requests

r = requests.post('https://sandbox.zenodo.org/api/deposit/depositions',
                        params={'access_token': ACCESS_TOKEN}, json={},
                        headers={"Content-Type": "application/json"})

print r.status_code

bucket_url = r.json()['links']['bucket']

filename='bigfile.txt'
r = requests.put('%s/%s' % (bucket_url,filename),
                data=open(filename, 'rb'),
                headers={"Accept":"application/json",
                "Authorization":"Bearer %s" % ACCESS_TOKEN,
                "Content-Type":"application/octet-stream"})

print r.status_code

所有6条评论

您必须使用我们新的文件上传 API(我们尚未发布)来上传大于 100MB 的文件。 这是因为当前的 API 使用application/mulitpart-formdata来上传文件,效率不高。 在新的 API 中,您可以在 PUT 请求中流式传输文件的二进制内容,该请求要快得多,并且两端都不需要任何编码/解码。 今天稍后我会给你一个例子。

感谢您调查此事! 我对新 API 的示例感到很兴奋。
也许你想考虑 python 包“requests-toolbelt”,它也允许流式传输多部分表单数据对象。 但我想任何没有编码要求的解决方案都值得赞赏。

抱歉这么久才回复这个问题:

1) 找到您的存储桶 URL:

$ curl -H "Accept: application/json" -H "Authorization: Bearer <access token>" "https://www.zenodo.org/api/deposit/depositions/<deposit id>"
{
  "links": {
    "bucket": "https://www.zenodo.org/api/files/<bucket id>",
    ...
  },
...

2) 上传文件到bucket

$ curl -X PUT -H "Accept: application/json" -H "Content-Type: application/octet-stream" -H "Authorization: Bearer <access_token>" -d @<path to local file> https://www.zenodo.org/api/files/<bucket id>/<filename>

请注意,存储桶是版本化的,因此为了再次完全删除文件,您必须使用版本链接。 从列出存储桶中找到它:

$ curl -H "Accept: application/json" -H "Authorization: Bearer <access token>" "https://www.zenodo.org/api/files/<bucket id>”
{
  "contents": [
    {
      "links": {
        "version": "https://zenodo.org/api/files/<bucket id>/<filename>?versionId=<versionId>", 
        ...
      }, 
      "key": "<filename>", 
      ...
    }, 
   ...

删除文件:

$ curl -X DELETE -H "Accept: application/json" -H "Authorization: Bearer <access_token>" https://www.zenodo.org/api/files/<bucket id>/<filename>?versionId=<versionId>”

以防万一有人遇到这个问题,这里有一些 Python 可以使用新的 API 来完成文件上传部分。 这相当于上面概述的用于上传单个文件的 CURL 调用。 我已经用 160MB 的文件对其进行了测试,但该文件的 API失败了。 这也使用请求(文档化 API 使用的)并简单地进行新提交并上传文件。 请注意,使用的 URL 是沙盒 URL。

import requests

r = requests.post('https://sandbox.zenodo.org/api/deposit/depositions',
                        params={'access_token': ACCESS_TOKEN}, json={},
                        headers={"Content-Type": "application/json"})

print r.status_code

bucket_url = r.json()['links']['bucket']

filename='bigfile.txt'
r = requests.put('%s/%s' % (bucket_url,filename),
                data=open(filename, 'rb'),
                headers={"Accept":"application/json",
                "Authorization":"Bearer %s" % ACCESS_TOKEN,
                "Content-Type":"application/octet-stream"})

print r.status_code

@lnielsen @jakelever
您认为可以使用requests.put将分块文件流式传输到存储桶中吗?
语境:
我有一组大文件,我想对其进行压缩,而无需事先在内存或磁盘上创建 zipfile。 我想将生成器对象传递给请求方法的八位字节流。

在尝试使用 API 上传文件时偶然发现了这一点。 对我来说,流 API 失败了,因为只有大约 986 Kb 文件的一半被上传,导致 PDF 损坏。 基于http://killtheradio.net/tricks-hacks/curl-cli-not-sending-full-file-data-when-using-data-binary/然后我用-T <path to file>替换了-d @<path to file> -T <path to file>在 curl 命令行和整个文件上传。

此页面是否有帮助?
0 / 5 - 0 等级