Pobierz dane otrzymane w żądaniu Flask

Chcę być w stanie przesłać dane do mojej aplikacji Flask. Próbowałem uzyskać dostęp do request.data, ale jest to pusty ciąg znaków. Jak uzyskać dostęp do danych żądań?

from flask import request

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

Odpowiedź na to pytanie skłoniła mnie do zadania Get raw POST body in Python Flask niezależnie od nagłówka Content-Type next, który polega na pobraniu surowych danych, a nie przetwarzanych danych.

Author: davidism, 2012-05-03

19 answers

Dokumenty opisują atrybuty dostępne na żądanie. W większości przypadków request.data będzie pusty, ponieważ jest używany jako alternatywa:

request.data zawiera przychodzące dane żądania jako ciąg znaków w przypadku, gdy dostarczony z kolbą typu MIME nie obsługuje.

  • request.args: klucz / wartość w łańcuchu zapytań URL
  • request.form: pary klucz / wartość w treści, z formularza Post HTML lub żądania JavaScript, który nie jest JSON encoded
  • request.files: pliki w ciele, które Kolba utrzymuje oddzielnie od form. Formularze HTML muszą używać enctype=multipart/form-data, inaczej pliki nie zostaną przesłane.
  • request.values: połączone args i form, preferując args jeśli klawisze nakładają się
  • request.json: przetwarzane dane JSON. Żądanie musi mieć typ zawartości application/json lub używać request.get_json(force=True) aby zignorować typ zawartości.

Wszystkie z nich są MultiDict instancje (z wyjątkiem json). Możesz wartości dostępu za pomocą:

  • request.form['name']: użyj indeksowania, jeśli wiesz, że klucz istnieje
  • request.form.get('name'): użyj get Jeśli klucz może nie istnieć
  • request.form.getlist('name'): użyj getlist, jeśli klucz jest wysyłany wiele razy i chcesz mieć listę wartości. get zwraca tylko pierwszą wartość.
 1547
Author: Robert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 21:48:13

Aby uzyskać surowe dane, Użyj request.data. Działa to tylko wtedy, gdy nie można go przetworzyć jako dane formularza, w przeciwnym razie będzie on pusty i request.form będzie miał przetworzone dane.

from flask import request
request.data
 229
Author: clyfish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 20:38:49

Dla parametrów zapytań URL użyj request.args.

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

Do wpisania formularza należy użyć request.form.

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

Dla JSON zamieszczonego z typem treści application/json, użyj request.get_json().

data = request.get_json()
 208
Author: Fizer Khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 20:41:58

Oto przykład parsowania opublikowanych danych JSON i cofania ich.

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/foo', methods=['POST']) 
def foo():
    data = request.json
    return jsonify(data)

Aby dodać JSON z curl:

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

Lub użyć listonosza:

using postman to post JSON

 120
Author: Little Roys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-05 14:03:09

Jeśli umieścisz JSON z typem zawartości application/json, Użyj request.get_json(), aby uzyskać go w Flask. Jeśli typ zawartości jest nieprawidłowy, zwracane jest None. Jeśli dane nie są JSON, pojawia się błąd.

@app.route("/something", methods=["POST"])
def do_something():
    data = request.get_json()
 44
Author: Amit Karnik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 20:49:25

Aby uzyskać surowe ciało posta niezależnie od typu zawartości, użyj request.get_data(). Jeśli użyjesz request.data, wywoła request.get_data(parse_form_data=True), co wypełni request.form MultiDict i zostawić data puste.

 44
Author: Xiao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 20:53:57

Aby uzyskać request.form jako zwykły słownik, użyj request.form.to_dict(flat=False).

Aby zwrócić dane JSON dla API, przekaż je do jsonify.

Ten przykład zwraca dane formularza jako dane JSON.

@app.route('/form_to_json', methods=['POST'])
def form_to_json():
    data = request.form.to_dict(flat=False)
    return jsonify(data)
Oto przykład danych formularza POST z curl, zwracanych jako JSON:
$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
  "name": "ivanleoncz", 
  "role": "Software Developer"
}
 24
Author: ivanleoncz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-28 04:52:10

Użyj request.get_json(), aby uzyskać opublikowane dane JSON.

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

Użyj request.form, Aby uzyskać dane podczas przesyłania formularza za pomocą metody POST.

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

Użyj request.args, aby uzyskać dane przekazane w ciągu zapytania URL, jak podczas przesyłania formularza za pomocą metody GET.

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

request.form itd. są podobne do dict, użyj metody get, aby uzyskać wartość z wartością domyślną, jeśli nie została przekazana.

 19
Author: Ravin Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 21:40:21

Aby opublikować JSON bez typu zawartości application/json, Użyj request.get_json(force=True).

@app.route('/process_data', methods=['POST'])
def process_data():
    req_data = request.get_json(force=True)
    language = req_data['language']
    return 'The language value is: {}'.format(language)
 15
Author: Tarik Fojnica,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 20:55:46

Aby opublikować JSON z jQuery w JavaScript, użyj JSON.stringify do zrzutu danych i ustaw typ zawartości na application/json.

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

$.ajax({
    type: 'POST',
    url: '/process',
    data: JSON.stringify(value_data),
    contentType: 'application/json',
    success: function (response_data) {
        alert("success");
    }   
});

Parse it in Flask with request.get_json().

data = request.get_json()
 13
Author: vaishali chaudhari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-02 17:46:41

Surowe dane są przekazywane do aplikacji Flask z serwera WSGI jako request.stream. Długość strumienia jest w nagłówku Content-Length.

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

Jest zwykle bezpieczniejsze użycie request.get_data() zamiast tego.

 12
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 21:07:48

Aby przetworzyć JSON, użyj request.get_json().

@app.route("/something", methods=["POST"])
def do_something():
    result = handle(request.get_json())
    return jsonify(data=result)
 11
Author: zhangqy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 21:05:36

Oto przykład zamieszczania danych formularza, aby dodać użytkownika do bazy danych. Sprawdź request.method == "POST", aby sprawdzić, czy formularz został złożony. Użyj klawiszy z request.form, Aby pobrać dane formularza. Renderuj szablon HTML za pomocą <form> w przeciwnym razie. Pola w formularzu powinny mieć atrybuty name pasujące do kluczy w request.form.

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route("/user/add", methods=["GET", "POST"])
def add_user():
    if request.method == "POST":
        user = User(
            username=request.form["username"],
            email=request.form["email"],
        )
        db.session.add(user)
        db.session.commit()
        return redirect(url_for("index"))

    return render_template("add_user.html")
<form method="post">
    <label for="username">Username</label>
    <input type="text" name="username" id="username">
    <label for="email">Email</label>
    <input type="email" name="email" id="email">
    <input type="submit">
</form>
 11
Author: Dulangi_Kanchana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-07 22:42:42

Jeśli typ zawartości jest rozpoznawany jako dane formularza, request.data przetworzy go do request.form i zwróci pusty łańcuch.

Aby uzyskać surowe dane niezależnie od typu zawartości, wywołaj request.get_data(). request.data wywołuje get_data(parse_form_data=True), podczas gdy domyślną wartością jest False, jeśli wywołujesz ją bezpośrednio.

 6
Author: Zavec,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 21:11:37

Jeśli ciało zostanie rozpoznane jako dane formularza, będzie w request.form. Jeśli to JSON, to będzie w request.get_json(). W przeciwnym razie surowe dane będą w request.data. Jeśli nie jesteś pewien, w jaki sposób dane zostaną przesłane, możesz użyć łańcucha or, Aby uzyskać pierwszy z danymi.

def get_request_data():
    return (
        request.args
        or request.form
        or request.get_json(force=True, silent=True)
        or request.data
    )

request.args zawiera args przetwarzane z ciągu zapytania, niezależnie od tego, co było w ciele, więc można usunąć to z get_request_data(), Jeśli zarówno to, jak i ciało powinny dane w tym samym czasie.

 6
Author: Paul Gowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 21:28:32

Mój problem był podobny. Otrzymałem payload prośbę o POST, gdy użytkownik kliknął button z mojego slackbota. Content-Type było application/x-www-form-urlencoded. Użyłem kolby Python3.

Próbowałem tego rozwiązania i nie zadziałało

@app.route('/process_data', methods=['POST'])
def process_data():
   req_data = request.get_json(force=True)
   language = req_data['language']
   return 'The language value is: {}'.format(language)

Moje rozwiązanie 1 było:

from urllib.parse import parse_qs
# Some code
@ app.route('/slack/request_handler', methods=['POST'])
def request_handler():    
    # request.get_data() returned a bytestring
    # parse_qs() returned a dict from a bytestring. This dict has 1 pair
    # I tried payload_dict.keys() to see what keys in the dict and it had one key only
    payload_dict = parse_qs(request.get_data())

    # Get the value of the key from payload_dict
    # Value of the key from payload_dict is an array, length = 1
    payload_dict_value_arr = payload_dict[b'payload']

    # Get data from the index[0] of the array payload_dict_value_arr
    data = payload_dict_value_arr[0]   

    # convert a string (representation of a Dict)) to a Dict
    # Note that if you have single quotes as a part of your keys or values this will
    # fail due to improper character replacement.
    # This solution is only recommended if you have a strong aversion 
    # to the eval solution.
    datajson = json.loads(data)

    # get value of key "channel"
    channel = datajson["channel"]
    print(channel) {'id': 'D01ACC2E8S3', 'name': 'directmessage'}

Moje rozwiązanie 2, trochę krótsze:

@ app.route('/slack/request_handler', methods=['POST'])
def request_handler():
   payload = request.form  # return an ImmutableMultiDict with 1 pair

   a1 = payload['payload']  # get value of key 'payload'

   # Note that if you have single quotes as a part of your keys or values this will
   # fail due to improper character replacement.
   # convert a string (representation of a Dict)) to a Dict
   a2 = json.loads(a1)

   # get value of key "channel"
   channel = a2["channel"] 
   print(channel) # {'id': 'D01ACC2E8S3', 'name': 'directmessage'}

Piersiówka.Prośba.get_data , Unicode in Flask

 5
Author: Phoebe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-24 04:13:43

Wysyłając dane formularza za pomocą formularza HTML, upewnij się, że znaczniki input mają atrybuty name, w przeciwnym razie nie będą obecne w request.form.

@app.route('/', methods=['GET', 'POST'])
def index():
    print(request.form)
    return """
<form method="post">
    <input type="text">
    <input type="text" id="txt2">
    <input type="text" name="txt3" id="txt3">  
    <input type="submit">
</form>
"""
ImmutableMultiDict([('txt3', 'text 3')])

Tylko wejście txt3 miało name, więc jest to jedyny klucz obecny w request.form.

 3
Author: freezed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-04 21:21:01
@app.route('/addData', methods=['POST'])
def add_data():
     data_in = mongo.db.Data
     id = request.values.get("id")
     name = request.values.get("name")
     newuser = {'id' : id, 'name' : name}
     if voter.find({'id' : id, 'name' : name}).count() > 0:
            return "Data Exists"
     else:
            data_in.insert(newuser)
            return "Data Added"
 2
Author: Divyani Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-21 10:54:38
request.data

Jest to świetne w użyciu, ale pamiętaj, że wchodzi jako ciąg znaków i będzie wymagał iteracji.

 -2
Author: James McCannon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-09 12:55:35