One place for hosting & domains

      Comment traiter les données des requêtes entrantes dans Flask


      Introduction

      Les applications web doivent souvent traiter les données des requêtes entrantes fournies par les utilisateurs. Cette charge utile peut prendre la forme de chaînes de requête, de données de formulaires et d’objets JSON. Flask, comme tout autre framework web, vous permet d’accéder aux données d’une requête.

      Au cours de ce tutoriel, vous allez créer une application Flask avec trois itinéraires qui acceptent soit les chaînes de requête, les données de formulaire ou les objets JSON.

      Conditions préalables

      Pour suivre ce tutoriel, vous aurez besoin de :

      Ce tutoriel a été vérifié avec Pipenv v2020.11.15, Python v3.9.0 et Flask v1.1.2.

      Créer le projet

      Afin de pouvoir découvrir les différentes façons d’utiliser des requêtes, vous devrez créer une application Flask. Même si l’application donnée en exemple utilise une structure simplifiée pour les fonctions et les itinéraires de visualisation, vous pouvez appliquer tout ce que vous apprendrez au cours de ce tutoriel à toute méthode qui permet d’organiser vos affichages sous forme, par exemple, d’un affichage par catégories, de plans d’action ou d’une extension comme Flask-Via.

      Vous devrez tout d’abord créer un répertoire de projet. Ouvrez votre terminal et exécutez la commande suivante :

      • mkdir flask_request_example

      Ensuite, naviguez vers le nouveau répertoire :

      Ensuite, installez Flask. Ouvrez votre terminal et exécutez la commande suivante :

      La commande pipenv créera un virtualenv pour ce projet, un Pipfile, installera flask et un Pipfile.lock.

      Pour activer le virtualenv du projet, exécutez la commande suivante :

      Pour accéder aux données entrantes dans Flask, vous devez utiliser l'objet request. L'objet request contient toutes les données entrantes de la requête, qui incluent, entre autres, le typemime, le référent, l'adresse IP, les données brutes, la méthode HTTP et les en-têtes.

      Bien que toutes les informations que contient l'objet request soient utiles, pour les besoins de cet article, vous allez vous concentrer sur les données qui sont normalement fournies directement par l'appelant du terminal.

      Pour accéder à l'objet de requête dans Flask, vous devez l'importer à partir de la bibliothèque Flask :

      from flask import request
      

      Vous aurez alors la possibilité de l'utiliser dans l'une de vos fonctions d'affichage.

      Utilisez votre éditeur de code pour créer un fichier app.py. Importez Flask et l'objet request. Configurez également des itinéraires pour query-example, form-example et json-example:

      app.py

      # import main Flask class and request object
      from flask import Flask, request
      
      # create the Flask app
      app = Flask(__name__)
      
      @app.route('/query-example')
      def query_example():
          return 'Query String Example'
      
      @app.route('/form-example')
      def form_example():
          return 'Form Data Example'
      
      @app.route('/json-example')
      def json_example():
          return 'JSON Object Example'
      
      if __name__ == '__main__':
          # run app in debug mode on port 5000
          app.run(debug=True, port=5000)
      

      Ensuite, ouvrez votre terminal et démarrez l'application avec la commande suivante :

      L'application démarrera sur le port 5000. Vous pourrez alors visualiser chaque itinéraire dans votre navigateur en utilisant les liens suivants :

      http://127.0.0.1:5000/query-example (or localhost:5000/query-example)
      http://127.0.0.1:5000/form-example (or localhost:5000/form-example)
      http://127.0.0.1:5000/json-example (or localhost:5000/json-example)
      

      Le code établit trois itinéraires. En visualisant chaque itinéraire, les messages « Requy String Example », « Form Data example » et « JSON Object example » s'afficheront respectivement.

      Utiliser les arguments de requête

      On utilise souvent les arguments URL que vous ajoutez à une chaîne de requête pour transmettre des données à une application web. Alors qu'en navigant sur le Web, vous rencontrerez probablement une chaîne de requête auparavant.

      Une chaîne de requête ressemble à ce qui suit :

      example.com?arg1=value1&arg2=value2
      

      La chaîne de requête commence après le caractère du point d'interrogation (?) :

      example.com?arg1=value1&arg2=value2
      

      Et intègre des paires de valeurs clés séparées par un caractère de perluète (&) :

      example.com?arg1=value1&arg2=value2
      

      Pour chaque pair, la clé est suivie du caractère égal (=), puis de la valeur.

      arg1 : value1
      arg2 : value2
      

      Les chaînes de requête vous seront utiles pour transmettre les données sur lesquelles l'utilisateur n'a pas besoin d'agir. Vous pouvez générer une chaîne de requête quelque part dans votre application et l'ajouter à une URL afin que, lorsqu'un utilisateur soumet une requête, les données soient automatiquement transmises pour elles. Une chaîne de requête peut également être générée par les formulaires qui ont pour méthode GET.

      Ajoutons une chaîne de requête à l'itinéraire query-example. Dans cet exemple hypothétique, vous allez renseigner le nom d'un langage de programmation qui s'affichera à l'écran. Créez une clé de « langage » et une valeur de « Python » :

      http://127.0.0.1:5000/query-example?language=Python
      

      Si vous exécutez l'application et que vous naviguez vers cette URL, vous verrez qu'elle affiche toujours le message « Request String Example ».

      Vous devrez alors programmer la partie qui gère les arguments de la requête. Ce code lira le contenu de la clé language en utilisant soit request.args.get('language') ou request.args['language'].

      En appelant request.args.get('language'), l'exécution de l'application continuera si la clé language n'existe pas dans l'URL. Le cas échéant, la méthode affichira le résultat None.

      En appelant request.args['language'], l'application renverra une erreur 400 si la clé de la langue n'existe pas dans l'URL.

      Lorsque vous travaillez avec des chaînes de requête, nous vous recommandons d'utiliser request.args.get() pour empêcher l'application d'entrer en échec.

      Lisons la clé language et affichons-la comme la sortie.

      Modifiez l'itinéraire query-example dans app.py en utilisant le code suivant :

      app.py

      @app.route('/query-example')
      def query_example():
          # if key doesn't exist, returns None
          language = request.args.get('language')
      
          return '''<h1>The language value is: {}</h1>'''.format(language)
      

      Ensuite, exécutez l'application et naviguez jusqu'à l'URL :

      http://127.0.0.1:5000/query-example?language=Python
      

      Le navigateur devrait afficher le message suivant :

      Output

      The language value is: Python

      L'argument provenant de l'URL est affecté à la variable language et ensuite renvoyé au navigateur.

      Pour ajouter d'autres paramètres de chaîne de requête, vous pouvez ajouter les perluètes et de nouvelles paires clé-valeur à la fin de l'URL. Créez une clé « framework » et une valeur « Flask » :

      http://127.0.0.1:5000/query-example?language=Python&framework=Flask
      

      Et si vous en voulez plus, continuez à ajouter des perluettes et des paires clé-valeur. Créez une clé « website » et une valeur « DigitalOcean » :

      http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean
      

      Pour accéder à ces valeurs, vous devrez à nouveau utiliser soit request.args.get() ou request.args[]. Utilisons-les toutes les deux pour voir ce qu'il se passe lorsqu'une clé est manquante. Modifiez l'itinéraire query_example pour attribuer la valeur des résultats à des variables, puis affichez-les :

      @app.route('/query-example')
      def query_example():
          # if key doesn't exist, returns None
          language = request.args.get('language')
      
          # if key doesn't exist, returns a 400, bad request error
          framework = request.args['framework']
      
          # if key doesn't exist, returns None
          website = request.args.get('website')
      
          return '''
                    <h1>The language value is: {}</h1>
                    <h1>The framework value is: {}</h1>
                    <h1>The website value is: {}'''.format(language, framework, website)
      

      Ensuite, exécutez l'application et naviguez jusqu'à l'URL :

      http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean
      

      Le navigateur devrait afficher le message suivant :

      Output

      The language value is: Python The framework value is: Flask The website value is: DigitalOcean

      Supprimez la clé language de l'URL :

      http://127.0.0.1:5000/query-example?framework=Flask&website=DigitalOcean
      

      Le navigateur devrait afficher le message suivant accompagné de None si aucune valeur language n'est fournie :

      Output

      The language value is: None The framework value is: Flask The website value is: DigitalOcean

      Supprimez la clé framework de l'URL :

      http://127.0.0.1:5000/query-example?language=Python&website=DigitalOcean
      

      Le navigateur devrait rencontrer une erreur, étant donné qu'il s'attend à trouver une valeur pour framework :

      Output

      werkzeug.exceptions.BadRequestKeyError werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'framework'

      Vous comprenez maintenant de quelle manière sont traitées les chaînes de requête. Passons au prochain type de données entrantes.

      Utiliser les données de formulaire

      Les données des formulaires proviennent d'un formulaire qui a été envoyé en tant que requête POST à un itinéraire. Par conséquent, au lieu de voir les données dans l'URL (sauf si le formulaire est soumis avec une requête GET), les données du formulaire seront transmises à l'application en coulisses. Même si vous ne pouvez pas facilement voir les données du formulaire qui sont transmises, votre application est tout de même en capacité de les lire.

      Pour le démontrer, modifiez l'itinéraire form-example dans app.py pour accepter les requêtes à la fois GET et POST. Le formulaire suivant est renvoyé :

      app.py

      # allow both GET and POST requests
      @app.route('/form-example', methods=['GET', 'POST'])
      def form_example():
          return '''
                    <form method="POST">
                        <div><label>Language: <input type="text" name="language"></label></div>
                        <div><label>Framework: <input type="text" name="framework"></label></div>
                        <input type="submit" value="Submit">
                    </form>'''
      

      Ensuite, exécutez l'application et naviguez jusqu'à l'URL :

      http://127.0.0.1:5000/form-example
      

      Le navigateur devrait afficher un formulaire avec deux champs de saisie (un pour language et un pour framework) et un bouton Submit.

      Le plus important à savoir sur ce formulaire, c'est qu'il effectue une requête POST sur le même itinéraire qui a généré le formulaire. Les clés qui seront lues dans l'application proviennent toutes des attributs name qui se trouvent sur nos entrées de formulaire. Dans ce cas, langage et framework correspondent aux noms des entrées. Vous y aurez donc accès dans l'application.

      Dans la fonction d'affichage, vous devrez alors vérifier si la méthode de requête est GET ou POST. S'il s'agit d'une requête GET, vous pouvez afficher le formulaire. Dans le cas contraire, s’il s'agit d'une requête POST, vous devrez alors traiter les données entrantes.

      Modifiez l'itinéraire form-example dans app.py en utilisant le code suivant :

      app.py

      # allow both GET and POST requests
      @app.route('/form-example', methods=['GET', 'POST'])
      def form_example():
          # handle the POST request
          if request.method == 'POST':
              language = request.form.get('language')
              framework = request.form.get('framework')
              return '''
                        <h1>The language value is: {}</h1>
                        <h1>The framework value is: {}</h1>'''.format(language, framework)
      
          # otherwise handle the GET request
          return '''
                 <form method="POST">
                     <div><label>Language: <input type="text" name="language"></label></div>
                     <div><label>Framework: <input type="text" name="framework"></label></div>
                     <input type="submit" value="Submit">
                 </form>'''
      

      Ensuite, exécutez l'application et naviguez jusqu'à l'URL :

      http://127.0.0.1:5000/form-example
      

      Renseignez le champ language avec la valeur Python et le champ framework avec la valeur Flask. Ensuite, appuyez sur Submit.

      Le navigateur devrait afficher le message suivant :

      Output

      The language value is: Python The framework value is: Flask

      Vous comprenez maintenant de quelle manière sont traitées les chaînes de requête. Passons au prochain type de données entrantes.

      Utiliser des données JSON

      Les données JSON sont généralement construites par un processus qui appelle l'itinéraire.

      Voici à quoi ressemble un exemple d'objet JSON :

      {
        "language": "Python",
        "framework": "Flask",
        "website": "Scotch",
        "version_info": {
          "python": "3.9.0",
          "flask": "1.1.2"
        },
        "examples": ["query", "form", "json"],
        "boolean_test": true
      }
      

      Cette structure peut permettre la transmission de données bien plus complexes par opposition aux chaînes de requête et aux données de formulaires. Dans l'exemple, vous voyez des objets JSON imbriqués et un tableau d'éléments. Flask peut gérer ce format de données.

      Modifiez l'itinéraire form-example dans app.py pour accepter les requêtes POST et ignorer les autres requêtes comme GET :

      app.py

      @app.route('/json-example', methods=['POST'])
      def json_example():
          return 'JSON Object Example'
      

      Contrairement au navigateur web qui sert à interroger les chaînes et les données de formulaire, pour les besoins de cet article, afin d'envoyer un objet JSON, vous utiliserez Postman pour envoyer des requêtes personnalisées aux URL.

      Remarque : si vous avez besoin d'aide pour naviguer sur l'interface Postman pour les requêtes, consultez la documentation officielle.

      Dans Postman, ajoutez l'URL et configurez le type sur POST. Sur l'onglet body, changez la valeur sur raw et sélectionnez JSON dans la liste déroulante.

      Ces paramètres sont nécessaires pour permettre à Postman d'envoyer les données JSON correctement. Par conséquent, votre application Flask comprendra qu'elle reçoit JSON :

      POST http://127.0.0.1:5000/json-example
      Body
      raw JSON
      

      Ensuite, copiez l'exemple JSON précédent dans la saisie de texte.

      Envoyez la requête. Vous devriez recevoir la réponse « JSON Object Example ». Il s'agit d'une approche assez étrange, mais il faudra vous y attendre, car il reste encore à écrire le code qui permet de gérer la réponse des données JSON.

      Pour lire les données, vous devez comprendre de quelle manière Flask traduit les données JSON en structures de données Python :

      • Tout ce qui est un objet est converti en un dict. Python {"key" : "value"}, dans JSON cela correspond à somedict['key'] qui renvoie une valeur dans Python.
      • Un tableau dans JSON est converti en une liste dans Python. Étant donné que la syntaxe est la même, voici un exemple de liste : [1,2,3,4,5]
      • Les valeurs entre crochets dans l'objet JSON deviennent des chaînes dans Python.
      • Les valeurs booléennes true et false deviennent True et False dans Python.
      • Enfin, les numéros sans parenthèse se transforment en numéros dans Python.

      Travaillons maintenant sur le code afin de pouvoir lire les données JSON entrantes.

      Tout d'abord, attribuons tout ce qui se trouve dans l'objet JSON à une variable en utilisant request.get_json().

      request.get_json() convertit l'objet JSON en données Python. Attribuons maintenant les données des requêtes entrantes aux variables et renvoyons-les en apportant les modifications suivantes à l'itinéraire json-example :

      app.py

      # GET requests will be blocked
      @app.route('/json-example', methods=['POST'])
      def json_example():
          request_data = request.get_json()
      
          language = request_data['language']
          framework = request_data['framework']
      
          # two keys are needed because of the nested object
          python_version = request_data['version_info']['python']
      
          # an index is needed because of the array
          example = request_data['examples'][0]
      
          boolean_test = request_data['boolean_test']
      
          return '''
                 The language value is: {}
                 The framework value is: {}
                 The Python version is: {}
                 The item at index 0 in the example list is: {}
                 The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
      

      Notez de quelle manière vous accédez aux éléments qui ne sont pas au niveau supérieur. ['version']['python'] est utilisé, car vous êtes en train de saisir un objet imbriqué. Et ['example'][0] permet d'accéder à l'index 0 dans le tableau des exemples.

      Si l'objet JSON envoyé avec la requête n'est pas accessible dans votre fonction de visualisation, cela signifie que la requête échouera. Si vous ne souhaitez pas qu'elle échoue en l'absence d'une clé, il vous faudra préalablement vérifier si la clé existe avant d'essayer d'y accéder.

      app.py

      # GET requests will be blocked
      @app.route('/json-example', methods=['POST'])
      def json_example():
          request_data = request.get_json()
      
          language = None
          framework = None
          python_version = None
          example = None
          boolean_test = None
      
          if request_data:
              if 'language' in request_data:
                  language = request_data['language']
      
              if 'framework' in request_data:
                  framework = request_data['framework']
      
              if 'version_info' in request_data:
                  if 'python' in request_data['version_info']:
                      python_version = request_data['version_info']['python']
      
              if 'examples' in request_data:
                  if (type(request_data['examples']) == list) and (len(request_data['examples']) > 0):
                      example = request_data['examples'][0]
      
              if 'boolean_test' in request_data:
                  boolean_test = request_data['boolean_test']
      
          return '''
                 The language value is: {}
                 The framework value is: {}
                 The Python version is: {}
                 The item at index 0 in the example list is: {}
                 The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
      

      Exécutez l'application et envoyez l'exemple de requête JSON en utilisant Postman. Dans la réponse, vous obtiendrez la sortie suivante :

      Output

      The language value is: Python The framework value is: Flask The Python version is: 3.9 The item at index 0 in the example list is: query The boolean value is: false

      Désormais, vous comprenez de quelle manière sont manipulés les objets JSON.

      Conclusion

      Au cours de ce tutoriel, vous avez créé une application Flask avec trois itinéraires qui acceptent soit les chaînes de requête, les données de formulaire ou les objets JSON.

      En outre, n'oubliez pas que toutes les approches ont bien pris en compte la problématique récurrente de l'échec normal généré par l'absence d'une clé.

      Avertissement : le nettoyage des entrées des utilisateurs n'a pas été abordé dans cet article. Le nettoyage des entrées des utilisateurs permet de garantir que les données lues par l'application ne génèrent pas la défaillance inattendue d'un élément ou ne contournent pas les mesures de sécurité.

      Si vous souhaitez en savoir plus sur Flask, veuillez consulter notre page thématique Flask dans laquelle vous trouverez des exercices et des projets de programmation.



      Source link