web-dev-qa-db-fra.com

Comment obtenir les données reçues dans une demande de flacon

Je veux pouvoir envoyer les données à mon application Flask. J'ai essayé d'accéder à request.data mais c'est une chaîne vide. Comment accédez-vous aux données de la demande?

@app.route('/', methods=['GET', 'POST'])
def parse_request():
    data = request.data  # data is empty
    # need posted data here

La réponse à cette question m'a amené à demander Obtenir le corps brut POST dans un flacon Python quel que soit l'en-tête Content-Type next, qui concerne l'obtention des données brutes plutôt que des données analysées.

481
ddinchev

Les docs décrivent les attributs disponibles dans la requête. Dans la plupart des cas courants, request.data sera vide car il est utilisé comme solution de secours:

request.data Contient les données de la demande entrante sous forme de chaîne au cas où il serait livré avec un type MIME que Flask ne gérera pas.

  • request.args: les paires clé/valeur dans la chaîne de requête d'URL
  • request.form: les paires clé/valeur dans le corps, à partir d'un formulaire HTML ou d'une demande JavaScript non codée JSON
  • request.files: les fichiers dans le corps, que Flask garde séparés de form. Les formulaires HTML doivent utiliser enctype=multipart/form-data sinon les fichiers ne seront pas téléchargés.
  • request.values: combiné args et form, préférant args si les clés se chevauchent

Tous ces éléments sont MultiDict instances. Vous pouvez accéder aux valeurs à l'aide de:

  • request.form['name']: utilisez l'indexation si vous savez que la clé existe
  • request.form.get('name'): utilisez get si la clé n'existe peut-être pas
  • request.form.getlist('name'): utilisez getlist si la clé est envoyée plusieurs fois et que vous souhaitez une liste de valeurs. get ne renvoie que la première valeur.
795
Robert
from flask import request
request.data
174
clyfish

C'est simplement comme suit

Pour le paramètre URL Query, utilisez request.args

search = request.args.get("search")
page = request.args.get("page")

Pour Form input, utilisez request.form

email = request.form.get('email')
password = request.form.get('password')

Pour type de données application/json, utilisez request.data

# data in string format and you have to parse into dictionary
data = request.data
dataDict = json.loads(data)
137
Fizer Khan

Je donne un exemple complet de application/json:

from flask import Flask, abort, request 
import json

app = Flask(__name__)


@app.route('/foo', methods=['POST']) 
def foo():
    if not request.json:
        abort(400)
    print request.json
    return json.dumps(request.json)


if __== '__main__':
    app.run(Host='0.0.0.0', port=5000, debug=True)

utilisez Postman pour post request:

 enter image description here

utilisez la commande curl:

curl -i -H "Content-Type: application/json" -X POST -d '{"userId":"1", "username": "fizz bizz"}' http://localhost:5000/foo

P.S . Pour l'exemple de paramètre de requête URL, vous pouvez voir ma réponse dans Plusieurs paramètres dans Flask approute

59
Little Roys

Flask a un autre raccourci pour JSON:

Entête: 

{Content-Type: application/json}

@app.route("/something", methods=["POST"])
def do_something():
    data = request.get_json()
27
Amit Karnik

si vous souhaitez que le corps de la publication brute quel que soit le type de contenu, vous devez utiliser request.get_data(), car request.form est converti au format werkzeug.ImmutableMultiDict.

18
Xiao
@app.route('/', methods=['POST'])
def process_data():
    req_data = request.get_json(force=True) # force=True will make sure this works even if a client does not specify application/json
    language = req_data['language'] # or whatever key you have in your json

    return '''The language value is: {}'''.format(language)
8
Tarik Fojnica

Pour parler simplement, vous pouvez obtenir des données par le moyen ci-dessous:

@app.before_request
def before_request():
    g.data = request.get_json() or request.values

Maintenant, g.data est une instance de werkzeug.ImmutableMultiDict. Ensuite, vous pouvez utiliser g.data qui peut gérer la plupart de vos besoins. Par exemple, vous pouvez l'utiliser comme ceci:

@app.route("/something", methods=["POST"])
def do_something():
    result = handle(g.data)
    return jsonify(data=result)

Bien sûr, vous pouvez utiliser blueprint au lieu de app ~~

8
zhangqy

Utiliser request.form.

Au lieu d'obtenir une seule donnée de formulaire (request.form["field_name"]), vous pouvez obtenir toutes les données publiées en analysant l'objet ImmutableDict fourni par request.form, comme suit:

Flacon (Route)

@app.route('/data', methods=['POST'])                                           
def f_data():                                                                   
    if request.method == "POST":
        fields = [k for k in request.form]                                      
        values = [request.form[k] for k in request.form]
        data = dict(Zip(fields, values))
    return jsonify(data) 

Coquille

$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
  "name": "ivanleoncz", 
  "role": "Software Developer"
}

Pour plus de détails, ceci Gist .

7
ivanleoncz
length = request.headers["Content-Length"]
data=request.stream.read()

Maintenant, data est le corps de la requête

5
Daniel

Si le type mime est reconnu, alors request.data et request.get_data() renverront des chaînes vides.

Pour obtenir le contenu intégral, vous devez appeler request.get_data(as_text=True).

Voir http://flask.pocoo.org/docs/1.0/api/#flask.Request.get_data

4
Zavec

En javascript:

var value_data = [1,2,3,4];

$.ajax({
        type: 'POST',
        url: '/',
        data:JSON.stringify(value_data),
        success: function (response) {
            alert("Data added successfully");
         },    
});

En python:

client_data = request.get_data()
2
from flask import request

content = request.get_json()
name = content.get('name', '')

obtenir des données si le type de demande JSON et vous pouvez également mentionner les paramètres par défaut avec elle

from flask import request

content = request.form
name = content.get('name', '')

obtenir des données si formulaire de type de demande

from flask import request

request.args.get("name", "")

récupérer les paramètres de l'URL avec une requête GET

2
Ravin Gupta

C'est un peu un bidouillage pour obtenir toutes les données de demande, peu importe la façon dont elles ont été envoyées, mais j'utilise sérieusement: 

def get_request_info():
    args = str(request.args)
    form = str(request.form)
    files = str(request.files)
    maybe_json = request.get_json(silent=True, cache=False)
    if maybe_json:
        thejson = json.dumps(maybe_json)
    else:
        thejson = "no json"
    return # whatever you want 

et puis je retourne soit une chaîne qui les concatène, soit, si j’ai envie, je passe les appels de chaîne/json dump et fusionne tous les dicts alors cela peut être enregistré, retourné dans une fonction de vue, peu importe, et vous pouvez voir la demande entière, peu importe ce qu'elle contient.

2
Paul Gowder

Pour ceux qui, comme moi, ont un peu oublié HTML, assurez-vous que <input> dans votre <form> a un attribut name=""!

from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    print("Posted data : {}".format(request.form))

    return """
<form method="post">
    <input type="text">
    <input type="text" id="idtxt2">
    <input type="text" name="txt3" id="idtxt3">  
    <input type="submit" Value="Hopla!">
</form>
"""

if __== "__main__":
    app.run()

Résultat sur console:

freezed@machine % python3 run.py
 * Serving Flask app "flaskstuff.views" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 268-634-781
127.0.0.1 - - [20/Aug/2018 16:52:59] "POST / HTTP/1.1" 200 -
Posted data : ImmutableMultiDict([('txt3', 'text 3')])

No name attribut = no data in ImmutableMultiDict([])!

1
freezed