Obtenga los datos recibidos en una solicitud de Flask

736

Quiero poder enviar los datos a mi aplicación Flask. He intentado acceder request.datapero es una cadena vacía. ¿Cómo accede a los datos de la solicitud?

from flask import request

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

La respuesta a esta pregunta me llevó a preguntar Obtener cuerpo POST sin procesar en Python Flask, independientemente del encabezado Content-Type siguiente, que se trata de obtener los datos sin procesar en lugar de los datos analizados.

ddinchev
fuente

Respuestas:

1269

Los documentos describen los atributos disponibles en la solicitud. En la mayoría de los casos request.data, estará vacío porque se usa como reserva:

request.data Contiene los datos de la solicitud entrante como una cadena en caso de que venga con un tipo Mime Flask no maneja.

  • request.args: los pares clave / valor en la cadena de consulta URL
  • request.form: los pares clave / valor en el cuerpo, desde un formulario de publicación HTML o una solicitud de JavaScript que no está codificada en JSON
  • request.files: los archivos en el cuerpo, de los cuales Flask mantiene separados form. Deben usarse formularios HTML enctype=multipart/form-datao los archivos no se cargarán.
  • request.values: combinado argsy form, argssi las teclas se superponen
  • request.json: analizó datos JSON. La solicitud debe tener el application/jsontipo de contenido, o usar request.get_json(force=True)para ignorar el tipo de contenido.

Todos estos son MultiDictcasos (excepto para json). Puede acceder a los valores usando:

  • request.form['name']: use la indexación si sabe que la clave existe
  • request.form.get('name'): se usa getsi la clave puede no existir
  • request.form.getlist('name'): utilícelo getlistsi la clave se envía varias veces y desea una lista de valores. getsolo devuelve el primer valor.
Robert
fuente
205

Para obtener los datos sin procesar, use request.data. Esto solo funciona si no se puede analizar como datos de formulario; de lo contrario, estará vacío y request.formtendrá los datos analizados.

from flask import request
request.data
clyfish
fuente
178

Para los parámetros de consulta de URL, use request.args.

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

Para la entrada de formulario publicado, use request.form.

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

Para JSON publicado con tipo de contenido application/json, use request.get_json().

data = request.get_json()
Fizer Khan
fuente
98

Aquí hay un ejemplo de análisis de datos JSON publicados y eco de ellos.

from flask import Flask, request, jsonify

app = Flask(__name__)

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

Para publicar JSON con curl:

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

O para usar Postman:

usando cartero para publicar JSON

Little Roys
fuente
36

Si publica JSON con tipo de contenido application/json, úselo request.get_json()para obtenerlo en Flask. Si el tipo de contenido no es correcto, Nonese devuelve. Si los datos no son JSON, se genera un error.

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

Para obtener el cuerpo de la publicación sin formato, independientemente del tipo de contenido, use request.get_data(). Si lo usa request.data, llama request.get_data(parse_form_data=True), lo que rellenará request.form MultiDicty dejará datavacío.

Xiao
fuente
18

Para obtener request.formcomo un diccionario normal, use request.form.to_dict(flat=False).

Para devolver datos JSON para una API, páselos a jsonify .

Este ejemplo devuelve datos de formulario como datos JSON.

@app.route('/form_to_json', methods=['POST'])
def form_to_json():
    data = request.form.to_dict(flat=False)
    return jsonify(data)

Aquí hay un ejemplo de datos de formulario POST con curl, regresando como JSON:

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

Utilícelo request.get_json()para obtener datos JSON publicados.

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

Utilícelo request.formpara obtener datos cuando envíe un formulario con el método POST.

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

Utilícelo request.argspara pasar los datos en la cadena de consulta de la URL, como cuando envía un formulario con el método GET.

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

request.formetc. son similares a dict, use el getmétodo para obtener un valor con un valor predeterminado si no se pasó.

Ravin Gupta
fuente
10

Para publicar JSON sin el application/jsontipo de contenido, use 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
fuente
10

Los datos sin procesar se pasan a la aplicación Flask desde el servidor WSGI como request.stream. La longitud de la secuencia está en el Content-Lengthencabezado.

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

Por lo general, es más seguro usarlo request.get_data().

Daniel
fuente
9

Para publicar JSON con jQuery en JavaScript, use JSON.stringifypara volcar los datos y configure el tipo de contenido en 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");
    }   
});

Analízalo en Frasco con request.get_json().

data = request.get_json()
vaishali chaudhari
fuente
8

Para analizar JSON, use request.get_json().

@app.route("/something", methods=["POST"])
def do_something():
    result = handle(request.get_json())
    return jsonify(data=result)
zhangqy
fuente
5

Aquí hay un ejemplo de publicación de datos de formulario para agregar un usuario a una base de datos. Verifique request.method == "POST"para verificar si se envió el formulario. Use las teclas de request.formpara obtener los datos del formulario. Renderice una plantilla HTML con un lo <form>contrario. Los campos en el formulario deben tener nameatributos que coincidan con las claves 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
fuente
4

Si el tipo de contenido se reconoce como datos de formulario, request.datalo analizará request.formy devolverá una cadena vacía.

Para obtener los datos sin procesar independientemente del tipo de contenido, llame request.get_data(). request.datallamadas get_data(parse_form_data=True), mientras que el valor predeterminado es Falsesi lo llama directamente.

Zavec
fuente
4

Si el cuerpo se reconoce como datos de formulario, estará en request.form. Si es JSON, estará adentro request.get_json(). De lo contrario, los datos sin procesar estarán en request.data. Si no está seguro de cómo se enviarán los datos, puede usar una orcadena para obtener el primero con datos.

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

request.argscontiene argumentos analizados a partir de la cadena de consulta, independientemente de lo que haya en el cuerpo, por lo que lo eliminaría get_request_data()si tanto él como un cuerpo deben tener datos al mismo tiempo.

Paul Gowder
fuente
2

Al publicar datos de formulario con un formulario HTML, asegúrese de que las inputetiquetas tengan nameatributos, de lo contrario no estarán presentes 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')])

Solo la txt3entrada tenía un name, así que es la única clave presente en request.form.

congelado
fuente