Zenodo: Fehler beim Hochladen einer größeren Datei über die API in die Sandbox

Erstellt am 26. Sept. 2016  ·  6Kommentare  ·  Quelle: zenodo/zenodo

Hallo,

wenn ich versuche, eine Testdatei > 100 MB über Python-Anfragen und Zenodo-API (Sandbox) mit dem folgenden Code hochzuladen

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)

es gibt den http-Fehlercode 413 ("413 Request Entity Too Large" zurück, der übrigens nicht in der zenodo API Documentation dokumentiert ist).

Derselbe Code, der mit Dateien < 100 MB getestet wurde, funktioniert und gibt 201 .

Habe ich das Dateigrößenlimit erreicht? (Wenn ja, wäre es gut, dies der Dokumentation hinzuzufügen). Oder liegt das vielleicht am "Requests"-Paket - muss ich die Daten mehrteilig setzen?

Enhancement

Hilfreichster Kommentar

Nur für den Fall, dass jemand darauf stößt, hier ist etwas Python, um den Datei-Upload-Teil mit der neuen API durchzuführen. Dies entspricht dem oben beschriebenen CURL-Aufruf zum Hochladen einer einzelnen Datei. Ich habe es mit einer 160 MB-Datei getestet, die mit der dokumentierten API fehlgeschlagen ist. Dies verwendet auch Anfragen (die die dokumentierte API verwendet) und macht einfach eine neue Einreichung und lädt eine Datei hoch. Beachten Sie, dass die verwendete URL die Sandbox-URL ist.

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

Alle 6 Kommentare

Sie müssen unsere neue Datei-Upload-API (die wir noch nicht veröffentlicht haben) verwenden, um Dateien hochzuladen, die größer als 100 MB sind. Dies liegt daran, dass die aktuelle API application/mulitpart-formdata zum Hochladen der Datei verwendet, was nicht sehr effizient ist. In der neuen API streamen Sie den binären Inhalt der Datei in einer PUT-Anfrage, die viel schneller ist und an beiden Enden keine Codierung/Decodierung erfordert. Ein Beispiel schicke ich dir heute etwas später.

Vielen Dank, dass Sie sich das angeschaut haben! Ich bin gespannt auf das Beispiel der neuen API.
Vielleicht möchten Sie das Python-Paket "requests-toolbelt" in Betracht ziehen, das auch das Streamen von mehrteiligen Formulardatenobjekten ermöglicht. Aber ich denke, jede Lösung ohne Codierungsanforderungen wird geschätzt.

Entschuldigung für die lange Verzögerung bei der Beantwortung dieser Frage:

1) Finden Sie Ihre Bucket-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) Laden Sie eine Datei in den Bucket hoch

$ 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>

Beachten Sie, dass der Bucket versioniert ist. Um eine Datei wieder vollständig zu entfernen, müssen Sie den Versionslink verwenden. Finden Sie es in der Auflistung des Buckets:

$ 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>", 
      ...
    }, 
   ...

Löschen der Datei:

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

Nur für den Fall, dass jemand darauf stößt, hier ist etwas Python, um den Datei-Upload-Teil mit der neuen API durchzuführen. Dies entspricht dem oben beschriebenen CURL-Aufruf zum Hochladen einer einzelnen Datei. Ich habe es mit einer 160 MB-Datei getestet, die mit der dokumentierten API fehlgeschlagen ist. Dies verwendet auch Anfragen (die die dokumentierte API verwendet) und macht einfach eine neue Einreichung und lädt eine Datei hoch. Beachten Sie, dass die verwendete URL die Sandbox-URL ist.

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
Glauben Sie, dass es möglich ist, mit requests.put eine aufgeteilte Datei in den Bucket zu streamen?
Kontext:
Ich habe eine Reihe großer Dateien, die ich zipstreamen möchte, ohne vorher eine Zip-Datei im Speicher oder auf der Festplatte zu erstellen. Ich möchte ein Generator-Objekt an den Oktett-Stream der Request-Methode übergeben.

Stolperte darüber, als ich versuchte, Dateien über die API hochzuladen. Für mich ist die Streaming-API fehlgeschlagen, da nur etwa die Hälfte einer 986-KB-Datei hochgeladen wurde, was zu einer beschädigten PDF-Datei führte. Basierend auf http://killtheradio.net/tricks-hacks/curl-cli-not-sending-full-file-data-when-using-data-binary/ habe ich dann -d @<path to file> durch -T <path to file> in der curl-Befehlszeile und die gesamte Datei hochgeladen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen