Recherche…


Syntaxe

  • request.files ['name'] # fichier unique requis
  • request.files.get ('name') # Aucun s'il n'est pas posté
  • request.files.getlist ('name') # liste de zéro ou plusieurs fichiers publiés
  • CombinedMultiDict ((request.files, request.form)) # combine les données de formulaire et de fichier

Téléchargement de fichiers

Formulaire HTML

  • Utilisez une entrée de type de file et le navigateur fournira un champ permettant à l'utilisateur de sélectionner un fichier à télécharger.
  • Seuls les formulaires avec la méthode post peuvent envoyer des données de fichier.
  • Assurez-vous de définir l' enctype=multipart/form-data . Sinon, le nom du fichier sera envoyé mais pas les données du fichier.
  • Utilisez l'attribut multiple sur l'entrée pour permettre de sélectionner plusieurs fichiers pour le champ unique.
<form method=post enctype=multipart/form-data>
    <!-- single file for the "profile" field -->
    <input type=file name=profile>
    <!-- multiple files for the "charts" field -->
    <input type=file multiple name=charts>
    <input type=submit>
</form>

Demandes Python

Requests est une bibliothèque Python puissante pour faire des requêtes HTTP. Vous pouvez l'utiliser (ou d'autres outils) pour publier des fichiers sans navigateur.

  • Ouvrez les fichiers à lire en mode binaire.
  • Il existe plusieurs structures de données que les files prennent. Cela montre une liste de tuples (name, data) , qui autorise plusieurs fichiers comme le formulaire ci-dessus.
import requests

with open('profile.txt', 'rb') as f1, open('chart1.csv', 'rb') as f2, open('chart2.csv', 'rb') as f3:
    files = [
        ('profile', f1),
        ('charts', f2),
        ('charts', f3)
    ]
    requests.post('http://localhost:5000/upload', files=files)

Ceci n'est pas censé être une liste exhaustive. Pour des exemples d'utilisation de votre outil préféré ou de scénarios plus complexes, consultez la documentation de cet outil.

Enregistrer les téléchargements sur le serveur

Les fichiers téléchargés sont disponibles dans request.files , un MultiDict champ de mappage MultiDict pour les objets de fichier. Utilisez getlist - au lieu de [] ou get - si plusieurs fichiers ont été téléchargés avec le même nom de champ.

request.files['profile']  # single file (even if multiple were sent)
request.files.getlist('charts')  # list of files (even if one was sent)

Les objets dans request.files ont une méthode de save qui enregistre le fichier localement. Créez un répertoire commun pour enregistrer les fichiers.

L'attribut filename est le nom avec lequel le fichier a été téléchargé. Cela peut être défini de manière arbitraire par le client, alors transmettez-le via la méthode secure_filename pour générer un nom valide et sûr sous secure_filename enregistrer. Cela ne garantit pas que le nom est unique , de sorte que les fichiers existants seront écrasés à moins que vous ne fassiez un travail supplémentaire pour le détecter.

import os
from flask import render_template, request, redirect, url_for
from werkzeug import secure_filename

# Create a directory in a known location to save files to.
uploads_dir = os.path.join(app.instance_path, 'uploads')
os.makedirs(uploads_dir, exists_ok=True)

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        # save the single "profile" file
        profile = request.files['profile']
        profile.save(os.path.join(uploads_dir, secure_filename(profile.filename)))

        # save each "charts" file
        for file in request.files.getlist('charts'):
            file.save(os.path.join(uploads_dir, secure_filename(file.name)))

        return redirect(url_for('upload'))

    return render_template('upload.html')

Transmission de données à WTForms et Flask-WTF

WTForms fournit un FileField pour restituer une entrée de type de fichier. Il ne fait rien de spécial avec les données téléchargées. Toutefois, comme Flask divise les données de formulaire ( request.form ) et les données de fichier ( request.files ), vous devez vous assurer de transmettre les données correctes lors de la création du formulaire. Vous pouvez utiliser un CombinedMultiDict pour combiner les deux en une structure unique que WTForms comprend.

form = ProfileForm(CombinedMultiDict((request.files, request.form)))

Si vous utilisez Flask-WTF , une extension pour intégrer Flask et WTForms, le transfert des données correctes sera géré automatiquement pour vous.

En raison d'un bogue dans WTForms, un seul fichier sera présent pour chaque champ, même si plusieurs ont été téléchargés. Voir ce numéro pour plus de détails. Il sera corrigé dans 3.0.

TÉLÉCHARGER LE FICHIER PARSE CSV EN TANT QUE LISTE DE DICTIONNAIRES EN FLACON SANS ÉCONOMIE

Les développeurs doivent souvent concevoir des sites Web permettant aux utilisateurs de télécharger un fichier CSV. En règle générale, il n’ya aucune raison de sauvegarder le fichier CSV actuel car les données seront traitées et / ou stockées dans une base de données une fois téléchargées. Cependant, la plupart des méthodes d'analyse syntaxique des données CSV, si ce n'est la plupart, nécessitent que les données soient lues sous forme de fichier. Cela peut poser un problème si vous utilisez FLASK pour le développement Web.

Supposons que notre CSV a une ligne d'en-tête et ressemble à ceci:

h1,h2,h3
'yellow','orange','blue'
'green','white','black'
'orange','pink','purple'

Maintenant, supposons que le formulaire HTML pour télécharger un fichier est comme suit:

<form action="upload.html" method="post" enctype="multipart/form-data">
    <input type="file" name="fileupload" id="fileToUpload">
    <input type="submit" value="Upload File" name="submit">
</form>

Puisque personne ne veut réinventer la roue, vous décidez d' importer csv dans votre script FLASK . Il n'y a aucune garantie que les utilisateurs téléchargent le fichier csv avec les colonnes dans le bon ordre. Si le fichier csv a une ligne d'en-tête, alors, à l'aide de la méthode csv.DictReader , vous pouvez lire le fichier CSV sous la forme d'une liste de dictionnaires, en saisissant les entrées de la ligne d'en-tête. Cependant, csv.DictReader a besoin d'un fichier et n'accepte pas directement les chaînes. Vous pensez peut-être que vous devez utiliser les méthodes FLASK pour enregistrer d'abord le fichier téléchargé, obtenir le nouveau nom et l'emplacement du fichier, l'ouvrir à l'aide de csv.DictReader , puis supprimer le fichier. Semble un peu comme un déchet.

Heureusement, nous pouvons obtenir le contenu du fichier sous forme de chaîne, puis diviser la chaîne par des lignes terminées. La méthode csv csv.DictReader acceptera ceci comme substitut à un fichier. Le code suivant montre comment cela peut être accompli sans enregistrer temporairement le fichier.

@application.route('upload.html',methods = ['POST'])
def upload_route_summary():
    if request.method == 'POST':

        # Create variable for uploaded file
        f = request.files['fileupload']  

        #store the file contents as a string
        fstring = f.read()
        
        #create list of dictionaries keyed by header row
        csv_dicts = [{k: v for k, v in row.items()} for row in csv.DictReader(fstring.splitlines(), skipinitialspace=True)]

        #do something list of dictionaries
    return "success"

La variable csv_dicts est maintenant la liste de dictionnaires suivante:

   csv_dicts = 
    [
        {'h1':'yellow','h2':'orange','h3':'blue'},
        {'h1':'green','h2':'white','h3':'black'},
        {'h1':'orange','h2':'pink','h3':'purple'}
    ]

Si vous êtes nouveau sur PYTHON, vous pouvez accéder aux données suivantes:

csv_dicts[1]['h2'] = 'white'
csv_dicts[0]['h3'] = 'blue'

D'autres solutions impliquent l'importation du module io et utilisent la méthode io.Stream . Je pense que c'est une approche plus simple. Je crois que le code est un peu plus facile à suivre que d'utiliser la méthode io . Cette approche est spécifique à l'exemple d'analyse d'un fichier CSV téléchargé.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow