こんにちは、
次のコードを使用して、PythonリクエストとZenodo API(サンドボックス)を介して100MBを超えるテストファイルをアップロードしようとすると
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 Request Entity Too Large"を返しますが、zenodo APIドキュメントには記載されていません)。
100 MB未満のファイルでテストされた同じコードが機能し、 201
を返します。
ファイルサイズの制限に達しましたか? (もしそうなら、これをドキュメントに追加するとよいでしょう)。 または、これは「requests」パッケージが原因である可能性があります。データをマルチパートで配置する必要がありますか?
100MBを超えるファイルをアップロードするには、新しいファイルアップロードAPI(まだ公開されていません)を使用する必要があります。 これは、現在の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)ファイルをバケットにアップロードします
$ 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>”
誰かがこれに遭遇した場合に備えて、新しいAPIを使用してファイルのアップロード部分を実行するPythonをいくつか紹介します。 これは、単一のファイルをアップロードするための上記のCURL呼び出しと同等です。 文書化されたAPIで失敗した160MBのファイルでテストしました。 これもリクエスト(文書化されたAPIが使用する)を使用し、単に新しい送信を行ってファイルをアップロードします。 使用される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
を使用して、チャンク化されたファイルをバケットにストリーミングすることは可能だと思いますか?
環境:
事前にメモリまたはディスクにzipファイルを作成せずにzipストリームしたい大きなファイルのセットがあります。 ジェネレータオブジェクトをリクエストメソッドのオクテットストリームに渡したいのですが。
APIを使用してファイルをアップロードしようとしたときに、これに遭遇しました。 私の場合、986 Kbファイルの約半分しかアップロードされなかったためストリーミングAPIが失敗し、PDFが破損しました。 http://killtheradio.net/tricks-hacks/curl-cli-not-sending-full-file-data-when-using-data-binary/に基づいて、 -d @<path to file>
を-T <path to file>
置き換えましたcurlコマンドラインの
最も参考になるコメント
誰かがこれに遭遇した場合に備えて、新しいAPIを使用してファイルのアップロード部分を実行するPythonをいくつか紹介します。 これは、単一のファイルをアップロードするための上記のCURL呼び出しと同等です。 文書化されたAPIで失敗した160MBのファイルでテストしました。 これもリクエスト(文書化されたAPIが使用する)を使用し、単に新しい送信を行ってファイルをアップロードします。 使用されるURLはサンドボックスのものであることに注意してください。