Las aplicaciones web requieren con frecuencia el procesamiento de los datos de las solicitudes entrantes de los usuarios. Esta carga útil puede tener la forma de cadenas de consulta, datos de formulario y objetos JSON. Flask, como cualquier otro marco web, le permite acceder a los datos de la solicitud.
En este tutorial, se creará una aplicación Flask con tres rutas que aceptan cadenas de consulta, datos de formulario u objetos JSON.
Para completar este tutorial, necesitará lo siguiente:
Este tutorial se verificó con Pipenv v2020.11.15, Python v3.9.0 y Flask v1.1.2.
Para demostrar las diferentes formas de usar solicitudes, deberá crear una aplicación Flask. Aunque la aplicación de ejemplo utiliza una estructura simplificada para las funciones y las rutas de vista, lo que se aprende en este tutorial puede aplicarse a cualquier método de organización de las vistas, como las vistas basadas en clases, los planos o una extensión como Flask-Via.
Primero, deberá crear un directorio de proyecto. Abra su terminal y ejecute el siguiente comando:
- mkdir flask_request_example
Luego, diríjase al nuevo directorio:
- cd flask_request_example
Luego, instale Flask. Abra su terminal y ejecute el siguiente comando:
- pipenv install Flask
El comando pipenv
creará un virtualenv para este proyecto, un Pipfile, para instalar flask
y un Pipfile.lock.
Para activar el virtualenv del proyecto, ejecute el siguiente comando:
- pipenv shell
Para acceder a los datos entrantes en Flask, tiene que usar el objeto request
. El objeto request
contiene todos los datos entrantes de la solicitud, que incluye el mimetype, recomendante, dirección IP, datos sin procesar, HTTP y encabezados, entre otras cosas.
Aunque toda la información que contiene el objeto de solicitud
puede ser útil, para los propósitos de este artículo, se centrará en los datos que normalmente son suministrados directamente por la persona que llama al punto final.
Para obtener acceso al objeto de solicitud en Flask, deberá importarlo desde la biblioteca Flask:
from flask import request
Luego, podrá usarlo en cualquiera de sus funciones de vista.
Utilice su editor de código para crear un archivo app.py
. Importe Flask
y el objeto request
. Y también establezca rutas para query-example
, form-example
, y json-example
:
# import main Flask class and request object
from flask import Flask, request
# create the Flask app
app = Flask(__name__)
@app.route('/query-example')
def query_example():
return 'Query String Example'
@app.route('/form-example')
def form_example():
return 'Form Data Example'
@app.route('/json-example')
def json_example():
return 'JSON Object Example'
if __name__ == '__main__':
# run app in debug mode on port 5000
app.run(debug=True, port=5000)
Luego, abra su terminal e inicie la aplicación con el siguiente comando:
- python app.py
La aplicación se iniciará en el puerto 5000, por lo que puede ver cada ruta en su navegador con los siguientes enlaces:
http://127.0.0.1:5000/query-example (or localhost:5000/query-example)
http://127.0.0.1:5000/form-example (or localhost:5000/form-example)
http://127.0.0.1:5000/json-example (or localhost:5000/json-example)
El código establece tres rutas y visitar cada una de ellas mostrará los mensajes de "Query String Example"
, "Form Data Example"
y "JSON Object Example"
, respectivamente.
Los argumentos de URL que se añaden a una cadena de consulta son una forma común de pasar los datos a una aplicación web. Al navegar por la web, es probable que haya encontrado alguna vez una cadena de consulta.
Una cadena de consulta se parece a lo siguiente:
example.com?arg1=value1&arg2=value2
La cadena de consulta comienza después del carácter de signo de interrogación (?
) :
example.com?arg1=value1&arg2=value2
Y tiene pares clave-valor separados por un carácter de “y” comercial (&
):
example.com?arg1=value1&arg2=value2
Para cada par, la clave va seguida por un signo de igualdad (=
) y, a continuación, el valor.
arg1 : value1
arg2 : value2
Las cadenas de consulta son útiles para pasar datos que no requieren que el usuario realice ninguna acción. Puede generar una cadena de consulta en algún lugar de su aplicación y añadirla a una URL para que cuando un usuario realice una solicitud, los datos se pasen automáticamente para ellos. Una cadena de consulta también puede generarse a través de formularios que tienen GET como método.
Vamos a añadir una cadena de consulta a la ruta query-example
. En este ejemplo hipotético, se proporcionará el nombre de un lenguaje de programación que se mostrará en la pantalla. Cree una clave de "language"
y un valor de "Python"
:
http://127.0.0.1:5000/query-example?language=Python
Si ejecuta la aplicación y navega a esa URL, verá que sigue mostrando un mensaje de "Query String Example"
.
Tendrá que programar la parte que maneja los argumentos de la consulta. Este código leerá la clave de language
usando request.args.get('language')
o request.args['language']
.
Al invocar request.args.get('language')
, la aplicación continuará ejecutándose si la clave de language
no existe en la URL. En ese caso, el resultado del método será None
.
Al invocar request.args['language']
, la aplicación mostrará un error 400 si la clave de language
no existe en la URL.
Cuando se trata de cadenas de consulta, se recomienda usar request.args.get()
para evitar que la aplicación falle.
Vamos a leer la clave language
y mostrarla como resultado.
Modifique la ruta query-example
en app.py
con el siguiente código:
@app.route('/query-example')
def query_example():
# if key doesn't exist, returns None
language = request.args.get('language')
return '''<h1>The language value is: {}</h1>'''.format(language)
Luego, ejecute la aplicación y diríjase a la URL:
http://127.0.0.1:5000/query-example?language=Python
El navegador debe mostrar el siguiente mensaje:
OutputThe language value is: Python
El argumento de la URL se asigna a la variable language
y luego se devuelve al navegador.
Para añadir más parámetros de cadena de consulta, puede añadir ampersands y los nuevos pares clave-valor al final de la URL. Cree una clave de "framework"
y un valor de "Flask"
:
http://127.0.0.1:5000/query-example?language=Python&framework=Flask
Y si desea más, continúe añadiendo ampersands y pares clave-valor. Cree una clave de "website"
y un valor de "DigitalOcean"
:
http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean
Para obtener acceso a esos valores, seguirá usando request.args.get()
o request.args[]
. Vamos a usar ambos para demostrar lo que sucede cuando falta una clave. Modifique la ruta query_example
para asignar el valor de los resultados a variables y luego mostrarlos:
@app.route('/query-example')
def query_example():
# if key doesn't exist, returns None
language = request.args.get('language')
# if key doesn't exist, returns a 400, bad request error
framework = request.args['framework']
# if key doesn't exist, returns None
website = request.args.get('website')
return '''
<h1>The language value is: {}</h1>
<h1>The framework value is: {}</h1>
<h1>The website value is: {}'''.format(language, framework, website)
Luego, ejecute la aplicación y diríjase a la URL:
http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean
El navegador debe mostrar el siguiente mensaje:
OutputThe language value is: Python
The framework value is: Flask
The website value is: DigitalOcean
Elimine la clave de language
de la URL:
http://127.0.0.1:5000/query-example?framework=Flask&website=DigitalOcean
El navegador debe mostrar el siguiente mensaje con None
cuando no se proporciona un valor para language
:
OutputThe language value is: None
The framework value is: Flask
The website value is: DigitalOcean
Elimine la clave de framework
de la URL:
http://127.0.0.1:5000/query-example?language=Python&website=DigitalOcean
El navegador debería encontrar un error porque está esperando un valor para framework
:
Outputwerkzeug.exceptions.BadRequestKeyError
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
KeyError: 'framework'
Ahora, ya comprende cómo se manejan las cadenas de consulta. Continuemos con el siguiente tipo de datos entrantes.
Los datos de formulario provienen de un formulario que ha sido enviado como solicitud POST a una ruta. Por lo tanto, en lugar de ver los datos en la URL (excepto en los casos en que el formulario se envía con una solicitud GET), los datos del formulario pasarán a la aplicación entre bastidores. Aunque no se pueden ver fácilmente los datos del formulario que se pasan, su aplicación puede leerlos.
Para demostrarlo, modifique la ruta de form-example
en app.py
para aceptar las solicitudes GET y POST, y devolver un formulario:
# allow both GET and POST requests
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
return '''
<form method="POST">
<div><label>Language: <input type="text" name="language"></label></div>
<div><label>Framework: <input type="text" name="framework"></label></div>
<input type="submit" value="Submit">
</form>'''
Luego, ejecute la aplicación y diríjase a la URL:
http://127.0.0.1:5000/form-example
El navegador debe mostrar un formulario con dos campos de entrada, uno para language
y otro para framework
, así como para un botón de envío.
Lo más importante que hay que saber sobre este formulario es que realiza una solicitud POST a la misma ruta que generó el formulario. Las claves que se leerán en la aplicación provienen de los atributos de nombre
de las entradas de nuestro formulario. En este caso, language
y framework
son los nombres de las entradas, por lo que tendrá acceso a ellos en la aplicación.
Dentro de la función de vista, deberá verificar si el método de solicitud es GET o POST. Si es una solicitud GET, puede mostrar el formulario. De lo contrario, si se trata de una solicitud POST, entonces querrá procesar los datos entrantes.
Modifique la ruta de form-example
en app.py
con el siguiente código:
# allow both GET and POST requests
@app.route('/form-example', methods=['GET', 'POST'])
def form_example():
# handle the POST request
if request.method == 'POST':
language = request.form.get('language')
framework = request.form.get('framework')
return '''
<h1>The language value is: {}</h1>
<h1>The framework value is: {}</h1>'''.format(language, framework)
# otherwise handle the GET request
return '''
<form method="POST">
<div><label>Language: <input type="text" name="language"></label></div>
<div><label>Framework: <input type="text" name="framework"></label></div>
<input type="submit" value="Submit">
</form>'''
Luego, ejecute la aplicación y diríjase a la URL:
http://127.0.0.1:5000/form-example
Complete el campo de language
con el valor de Python
y el campo de framework
con el valor de Flask
. Luego, presione Submit (Enviar).
El navegador debe mostrar el siguiente mensaje:
OutputThe language value is: Python
The framework value is: Flask
Ahora, entiende cómo manejar los datos del formulario. Continuaremos con el siguiente tipo de datos entrantes.
Los datos JSON generalmente se construye a través de un proceso que invoca la ruta.
Un ejemplo de objeto JSON tiene el siguiente aspecto:
{
"language": "Python",
"framework": "Flask",
"website": "Scotch",
"version_info": {
"python": "3.9.0",
"flask": "1.1.2"
},
"examples": ["query", "form", "json"],
"boolean_test": true
}
Esta estructura puede permitir que se pasen datos mucho más complicados en lugar de las cadenas de consulta y los datos del formulario. En el ejemplo, se ve los objetos JSON anidados y una matriz de elementos. Flask puede gestionar este formato de datos.
Modifique la ruta de form-example
en app.py
para aceptar las solicitudes POST e ignore otras solicitudes como GET:
@app.route('/json-example', methods=['POST'])
def json_example():
return 'JSON Object Example'
A diferencia del navegador web que se utiliza para las cadenas de consulta y los datos de formulario, para los fines de este artículo, para enviar un objeto JSON, se utilizará Postman para enviar solicitudes personalizadas a las URL.
Nota: Si necesita ayuda para navegar por la interfaz de Postman para las solicitudes, consulte la documentación oficial.
En Postman, añada la URL y cambie el tipo a POST. En la pestaña de cuerpo, cambie a raw y seleccione JSON en el menú desplegable.
Estos ajustes son necesarios para que Postman pueda enviar datos JSON correctamente, y para que su aplicación Flask comprenda que está recibiendo JSON:
POST http://127.0.0.1:5000/json-example
Body
raw JSON
Luego, copie el ejemplo JSON anterior en la entrada de texto.
Envíe la solicitud y debería obtener "JSON Object Example"
como respuesta. Eso es bastante decepcionante, pero es de esperar porque el código para gestionar la respuesta de los datos JSON aún no se ha escrito.
Para leer los datos, debe entender cómo Flask traduce los datos JSON en las estructuras de datos de Python:
{"key" : "value"}
en JSON corresponde a somedict['key']
, que devuelve un valor en Python.[1,2,3,4,5]
.true
y false
se convierten en True
y False
en Python.Ahora vamos a trabajar en el código para leer los datos JSON entrantes.
Primero, vamos a asignar todo desde el objeto JSON a una variable usando request.get_json()
.
request.get_json()
convierte el objeto JSON en datos de Python. Asignemos los datos de la solicitud entrante a las variables y devolvámoslos haciendo los siguientes cambios en la ruta json-example
:
# GET requests will be blocked
@app.route('/json-example', methods=['POST'])
def json_example():
request_data = request.get_json()
language = request_data['language']
framework = request_data['framework']
# two keys are needed because of the nested object
python_version = request_data['version_info']['python']
# an index is needed because of the array
example = request_data['examples'][0]
boolean_test = request_data['boolean_test']
return '''
The language value is: {}
The framework value is: {}
The Python version is: {}
The item at index 0 in the example list is: {}
The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
Tenga en cuenta cómo se accede a los elementos que no están en el nivel superior. Se utiliza ['version']['python']
porque se está entrando en un objeto anidado. Y ['examples'][0]
se utiliza para acceder al índice 0 en la matriz de ejemplos.
Si el objeto JSON enviado con la solicitud no tiene una clave a la que se accede en su función de vista, entonces la solicitud fallará. Si no quiere que la solicitud falle cuando no existe una clave, tendrá que verificar si la clave existe antes de intentar ingresarla.
# GET requests will be blocked
@app.route('/json-example', methods=['POST'])
def json_example():
request_data = request.get_json()
language = None
framework = None
python_version = None
example = None
boolean_test = None
if request_data:
if 'language' in request_data:
language = request_data['language']
if 'framework' in request_data:
framework = request_data['framework']
if 'version_info' in request_data:
if 'python' in request_data['version_info']:
python_version = request_data['version_info']['python']
if 'examples' in request_data:
if (type(request_data['examples']) == list) and (len(request_data['examples']) > 0):
example = request_data['examples'][0]
if 'boolean_test' in request_data:
boolean_test = request_data['boolean_test']
return '''
The language value is: {}
The framework value is: {}
The Python version is: {}
The item at index 0 in the example list is: {}
The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
Ejecute la aplicación y envíe la solicitud JSON de ejemplo usando Postman. En la respuesta, obtendrá el siguiente resultado:
OutputThe language value is: Python
The framework value is: Flask
The Python version is: 3.9
The item at index 0 in the example list is: query
The boolean value is: false
Ahora comprende cómo se manejan los objetos JSON.
En este artículo, se creó una aplicación Flask con tres rutas que aceptan cadenas de consulta, datos de formulario u objetos JSON.
Además, recuerde que todos los enfoques tuvieron que abordar la consideración recurrente de fallar con gracia cuando falta una clave.
Advertencia: Un tema que no se cubrió en este artículo fue cómo desinfectar la entrada de los usuarios. La sanitización de la entrada de lo usuario garantizaría que los datos leídos por la aplicación no causen un fallo inesperado o que se salten las medidas de seguridad.
Si desea obtener más información sobre Flask, consulte nuestra página del tema Flask para consultar ejercicios y proyectos de programación.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!