web-dev-qa-db-fra.com

Accepter plusieurs paramètres dans add_resource ()

Je souhaite gérer une demande GET dans mon API Flask REST. La demande inclura plusieurs paramètres, et vous pouvez vous attendre à ce qu'il s'agisse d'une demande GET typique: https: // localhost: 5000/item/analysis = true & class = A & class = B

Ainsi, une demande GET comprend:

  1. une variable booléenne appelée "analyse"
  2. une liste appelée "classe"

Je veux accepter ceci dans add_resource () comme suit:

add_resource(Item, '/item/<whatever-comes-here>')

Je n'ai aucune idée de la façon dont j'accepterais plusieurs paramètres (l'un d'entre eux étant une liste) dans add_resource (). Comment les accepter dans la fonction add_resource () et comment les décompresser dans la fonction get ()?

J'ai passé du temps à faire de l'ingénierie inverse, mais je n'ai pas encore réussi. Est-ce que je fais quelque chose de mal?

(Je comprends qu'il existe peut-être un meilleur moyen d'envoyer des listes avec une demande d'API GET REST, alors j'apprécierais toutes les indications à ce sujet!) Merci d'avance!

6
Omkar Neogi

Les paramètres d'URL sont définis après ?, votre URL devrait donc être:

https: // localhost: 5000/item? analysis = true & class = A & class = B

Vous n'avez rien à spécifier dans add_resource pour de tels paramètres d'URL.

Vous pouvez simplement obtenir les paramètres de l'objet proxy Flask de request dans votre méthode GET d'API:

from flask import Flask, request
from flask_restful import Api, Resource

app = Flask(__name__)
api = Api(app)

# Flask mishandles boolean as string
TRUTHY = ['true', 'True', 'yes']

class Item(Resource):
   def get():
      # Get `class` list from request args
      classes = request.args.getlist('class') 

      # Get `analysis` boolean from request args
      analysis = True if request.args.get('analysis') in TRUTHY else False

api.add_resource(Item, '/item')

Pour plus de flexibilité dans les paramètres que vous pouvez recevoir, vous pouvez utiliser le propre analyseur de requêtes de Flask Restful comme décrit ici / pour analyser la requête. 

Le code devient:

from flask import Flask
from flask_restful import Api, Resource, reqparse

app = Flask(__name__)
api = Api(app)

# Define parser and request args
parser = reqparse.RequestParser()
parser.add_argument('class', type=list)
parser.add_argument('analysis', type=bool, default=False, required=False, help='Enable analysis')

class Item(Resource):
   def get():
       args = parser.parse_args()
       classes = args['class']  # List ['A', 'B']
       analysis = args['analysis'] # Boolean True

api.add_resource(Item, '/item')

Enfin, parfois, un format plus compact pour une liste peut être souhaité (par exemple, limiter la taille de l'URL), auquel cas j'utilise souvent une liste séparée par des virgules: https: // localhost: 5000/item? Analysis = true & class = A, B

et dans l'analyseur de requête, acceptez-le simplement comme une chaîne et divisez-le en ',':

parser.add_argument('class', type=str)
...
classes = args['class'].split(',')

À votre santé !

7
JahMyst

La chaîne de requête ne peut pas être utilisée de cette façon.

Il sera écrasé, utilisez donc une chaîne telle que:

class=A,B
0
CheStar