J'effectue une tâche simple consistant à télécharger un fichier à l'aide de la bibliothèque de requêtes Python. J'ai cherché Stack Overflow et personne ne semblait avoir le même problème, à savoir que le fichier n'était pas reçu par le serveur:
import requests
url='http://nesssi.cacr.caltech.edu/cgi-bin/getmulticonedb_release2.cgi/post'
files={'files': open('file.txt','rb')}
values={'upload_file' : 'file.txt' , 'DB':'photcat' , 'OUT':'csv' , 'SHORT':'short'}
r=requests.post(url,files=files,data=values)
Je remplis la valeur du mot clé 'upload_file' avec mon nom de fichier, car si je le laisse vide, il est indiqué
Error - You must select a file to upload!
Et maintenant je reçois
File file.txt of size bytes is uploaded successfully!
Query service results: There were 0 lines.
Ce qui n'apparaît que si le fichier est vide. Je suis donc coincé sur la façon d'envoyer mon fichier avec succès. Je sais que le fichier fonctionne parce que si je vais sur ce site et remplis manuellement le formulaire, il retourne une belle liste d'objets correspondants, ce que je recherche après. J'apprécierais vraiment tous les conseils.
Quelques autres sujets liés (mais ne répondant pas à mon problème):
Si upload_file
est censé être le fichier, utilisez:
files = {'upload_file': open('file.txt','rb')}
values = {'DB': 'photcat', 'OUT': 'csv', 'SHORT': 'short'}
r = requests.post(url, files=files, data=values)
et requests
enverra un corps en plusieurs parties POST avec le champ upload_file
défini sur le contenu du fichier file.txt
.
Le nom de fichier sera inclus dans l'en-tête mime pour le champ spécifique:
>>> import requests
>>> open('file.txt', 'wb') # create an empty demo file
<_io.BufferedWriter name='file.txt'>
>>> files = {'upload_file': open('file.txt', 'rb')}
>>> print(requests.Request('POST', 'http://example.com', files=files).prepare().body.decode('ascii'))
--c226ce13d09842658ffbd31e0563c6bd
Content-Disposition: form-data; name="upload_file"; filename="file.txt"
--c226ce13d09842658ffbd31e0563c6bd--
Notez le paramètre filename="file.txt"
.
Vous pouvez utiliser un tuple pour la valeur de mappage files
, avec entre 2 et 4 éléments, si vous avez besoin de plus de contrôle. Le premier élément est le nom du fichier, suivi du contenu, d'une valeur facultative d'en-tête content-type et d'un mappage facultatif d'en-têtes supplémentaires:
files = {'upload_file': ('foobar.txt', open('file.txt','rb'), 'text/x-spam')}
Ceci définit un autre nom de fichier et type de contenu, en laissant de côté les en-têtes facultatifs.
Si vous souhaitez que l'ensemble du corps POST soit extrait d'un fichier (aucun autre champ ne soit spécifié), n'utilisez pas le paramètre files
, postez-le directement sous le nom data
. Vous voudrez peut-être aussi définir un en-tête Content-Type
, car aucun ne sera défini autrement.
(2018) La nouvelle bibliothèque de requêtes python a simplifié ce processus. Nous pouvons utiliser la variable 'fichiers' pour indiquer que nous souhaitons télécharger un fichier codé en plusieurs parties.
url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}
r = requests.post(url, files=files)
r.text
Si vous souhaitez télécharger un seul fichier avec la bibliothèque Python requests
, demandez alors lib prend en charge les transferts en contin , ce qui vous permet de envoyer des fichiers volumineux ou des flux sans les lire en mémoire .
with open('massive-body', 'rb') as f:
requests.post('http://some.url/streamed', data=f)
Stockez ensuite le fichier sur le côté server.py
de manière à enregistrer le flux dans le fichier sans le charger dans la mémoire. Voici un exemple d'utilisation de pload de fichiers Flask .
@app.route("/upload", methods=['POST'])
def upload_file():
from werkzeug.datastructures import FileStorage
FileStorage(request.stream).save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return 'OK', 200
Ou utilisez werkzeug Form Data Parsing comme indiqué dans un correctif pour le problème de " les fichiers volumineux surchargeant de mémoire) " afin d'éviter utilisation inefficace de la mémoire lors du téléchargement de fichiers volumineux (fichier st 22 GiB en ~ 60 secondes. L’utilisation de la mémoire est constante à environ 13 Mio.).
@app.route("/upload", methods=['POST'])
def upload_file():
def custom_stream_factory(total_content_length, filename, content_type, content_length=None):
import tempfile
tmpfile = tempfile.NamedTemporaryFile('wb+', prefix='flaskapp', suffix='.nc')
app.logger.info("start receiving file ... filename => " + str(tmpfile.name))
return tmpfile
import werkzeug, flask
stream, form, files = werkzeug.formparser.parse_form_data(flask.request.environ, stream_factory=custom_stream_factory)
for fil in files.values():
app.logger.info(" ".join(["saved form name", fil.name, "submitted as", fil.filename, "to temporary file", fil.stream.name]))
# Do whatever with stored file at `fil.stream.name`
return 'OK', 200