Uzyskaj dane otrzymane w żądaniu Flask

735

Chcę mieć możliwość przesłania danych do mojej aplikacji Flask. Próbowałem uzyskać dostęp, request.dataale jest to pusty ciąg. Jak uzyskać dostęp do danych żądania?

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 pytania Uzyskaj surowe ciało POST w Pythonie Flask, niezależnie od nagłówka Content-Type , który dotyczy raczej pobierania surowych danych niż analizowanych danych.

ddinchev
źródło

Odpowiedzi:

1265

W docs opisują atrybuty dostępne na życzenie. W większości przypadków request.databędzie pusty, ponieważ jest używany jako rezerwowy:

request.data Zawiera dane żądania przychodzącego jako ciąg, w przypadku gdy przyszedł z kolbą typu mimetycznego, która nie obsługuje.

  • request.args: pary klucz / wartość w ciągu zapytania adresu URL
  • request.form: pary klucz / wartość w treści, z formularza HTML lub żądania JavaScript, które nie jest zakodowane w JSON
  • request.files: pliki w ciele, od których Flask przechowuje osobno form. Formularze HTML muszą być używane, w enctype=multipart/form-dataprzeciwnym razie pliki nie zostaną przesłane.
  • request.values: połączone argsi form, najlepiej argsjeśli klucze się pokrywają
  • request.json: przeanalizowano dane JSON. Żądanie musi mieć application/jsontyp zawartości lub użyć, request.get_json(force=True)aby zignorować typ zawartości.

Wszystkie są MultiDictinstancjami (z wyjątkiem json). Dostęp do wartości można uzyskać za pomocą:

  • request.form['name']: użyj indeksowania, jeśli wiesz, że klucz istnieje
  • request.form.get('name'): użyj, getjeśli klucz może nie istnieć
  • request.form.getlist('name'): użyj, getlistjeśli klucz jest wysyłany wiele razy, a chcesz listę wartości. getzwraca tylko pierwszą wartość.
Robert
źródło
204

Aby uzyskać nieprzetworzone dane, użyj request.data. Działa to tylko wtedy, gdy nie można go przeanalizować jako danych formularza, w przeciwnym razie będzie pusty i request.formbędzie miał przeanalizowane dane.

from flask import request
request.data
Clyfish
źródło
177

Aby uzyskać parametry zapytania URL, użyj request.args.

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

Do wprowadzania formularzy zaksięgowanych użyj request.form.

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

W przypadku JSON opublikowanego z typem zawartości application/jsonużyj request.get_json().

data = request.get_json()
Fizer Khan
źródło
98

Oto przykład parsowania wysłanych danych JSON i ich powtórzenia.

from flask import Flask, request, jsonify

app = Flask(__name__)

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

Aby opublikować 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:

za pomocą listonosza, aby opublikować JSON

Little Roys
źródło
36

Jeśli publikujesz JSON z typem zawartości application/json, użyj go, request.get_json()aby uzyskać go w Flask. Jeśli typ zawartości jest nieprawidłowy, Nonejest zwracany. Jeśli dane nie są JSON, zgłaszany jest błąd.

@app.route("/something", methods=["POST"])
def do_something():
    data = request.get_json()
Amit Karnik
źródło
31

Aby uzyskać nieprzetworzoną treść postu bez względu na typ zawartości, użyj request.get_data(). Jeśli używasz request.data, wywołuje request.get_data(parse_form_data=True), co spowoduje wypełnienie request.form MultiDicti pozostawienie datapustego.

Xiao
źródło
18

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

Aby zwrócić dane JSON dla interfejsu 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 zawijaniem, zwracanych jako JSON:

$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
  "name": "ivanleoncz", 
  "role": "Software Developer"
}
ivanleoncz
źródło
12

Służy request.get_json()do wysyłania danych JSON.

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

Służy request.formdo pobierania danych podczas przesyłania formularza metodą POST.

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

Służy request.argsdo przekazywania danych w ciągu zapytania adresu URL, na przykład podczas przesyłania formularza metodą GET.

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

request.formitp. są podobne do dykt, użyj getmetody, aby uzyskać wartość domyślną, jeśli nie została przekazana.

Ravin Gupta
źródło
10

Aby wysłać JSON bez application/jsontypu zawartości, 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)
Tarik Fojnica
źródło
10

Surowe dane są przekazywane do aplikacji Flask z serwera WSGI jako request.stream. Długość strumienia znajduje się w Content-Lengthnagłówku.

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

Zwykle jest to bezpieczniejsze w użyciu request.get_data().

Daniel
źródło
9

Aby opublikować JSON z jQuery w JavaScript, użyj JSON.stringifydo zrzucenia 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");
    }   
});

Parsuj w Flask za pomocą request.get_json().

data = request.get_json()
vaishali chaudhari
źródło
8

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

@app.route("/something", methods=["POST"])
def do_something():
    result = handle(request.get_json())
    return jsonify(data=result)
zhangqy
źródło
5

Oto przykład publikowania danych formularza w celu dodania użytkownika do bazy danych. Sprawdź, request.method == "POST"czy formularz został przesłany. Użyj kluczy z, request.formaby uzyskać dane formularza. Renderuj szablon HTML z innym <form>sposobem. Pola w formularzu powinny mieć nameatrybuty 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>
Dulangi_Kanchana
źródło
4

Jeśli typ zawartości zostanie rozpoznany jako dane formularza, request.dataprzeanalizuje go request.formi zwróci pusty ciąg.

Aby uzyskać nieprzetworzone dane bez względu na typ zawartości, zadzwoń request.get_data(). request.datapołączeń get_data(parse_form_data=True), podczas gdy domyślnie jest Falseto połączenie bezpośrednie.

Zavec
źródło
4

Jeśli treść zostanie rozpoznana jako dane formularza, będzie w request.form. Jeśli to JSON, to będzie request.get_json(). W przeciwnym razie będą surowe dane request.data. Jeśli nie masz pewności, jak dane zostaną przesłane, możesz użyć orłańcucha, 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.argszawiera argumenty parsowane z ciągu zapytania, niezależnie od tego, co znajdowało się w treści, więc usunąłbyś to, get_request_data()gdyby zarówno on, jak i treść miały dane w tym samym czasie.

Paul Gowder
źródło
2

Wysyłając dane formularza za pomocą formularza HTML, upewnij się, że inputtagi mają nameatrybuty, w przeciwnym razie nie będą one obecne 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 txt3wejście miało name, więc jest to jedyny obecny klucz request.form.

zamrożone
źródło