Quickstart¶
¿Ansioso por empezar? Esta página ofrece una buena introducción a Flask. Sigue Instalación para configurar un proyecto e instalar Flask primero.
Una aplicación sencilla¶
Una aplicación Flask sencilla se parece a esto:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
¿Y qué hacía ese código?
Primero importamos la clase
Flask
. Una instancia de esta clase será nuestra aplicación WSGI.A continuación creamos una instancia de esta clase. El primer argumento es el nombre del módulo o paquete de la aplicación.
__name__
es un atajo conveniente para esto que es apropiado para la mayoría de los casos. Esto es necesario para que Flask sepa dónde buscar recursos como plantillas y archivos estáticos.A continuación, utilizamos el decorador
route()
para indicar a Flask qué URL debe activar nuestra función.La función devuelve el mensaje que queremos mostrar en el navegador del usuario. El tipo de contenido por defecto es HTML, por lo que el HTML de la cadena será renderizado por el navegador.
Guárdalo como hello.py
o algo similar. Asegúrate de no llamar a tu aplicación flask.py
porque esto entraría en conflicto con el propio Flask.
To run the application, use the flask
command or
python -m flask
. You need to tell the Flask where your application
is with the --app
option.
$ flask --app hello run
* Serving Flask app 'hello'
* Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
Comportamiento del descubrimiento de aplicaciones
Como atajo, si el archivo se llama app.py
o wsgi.py
, no tienes que usar --app
. Consulta Interfaz de línea de comandos para más detalles.
Esto lanza un servidor incorporado muy simple, que es lo suficientemente bueno para las pruebas, pero probablemente no es lo que quieres usar en producción. Para ver las opciones de despliegue vea Despliegue en producción.
Ahora dirígete a http://127.0.0.1:5000/, y deberías ver tu saludo de hola mundo.
Si otro programa ya está usando el puerto 5000, verás OSError: [Errno 98]
o OSError: [WinError 10013]
cuando el servidor intente iniciarse. Ver Dirección ya utilizada para saber cómo manejar esto.
Servidor visible desde el exterior
Si ejecutas el servidor notarás que el servidor sólo es accesible desde tu propio ordenador, no desde ningún otro de la red. Este es el valor por defecto porque en el modo de depuración un usuario de la aplicación puede ejecutar código Python arbitrario en su ordenador.
Si tienes el depurador desactivado o confías en los usuarios de tu red, puedes hacer que el servidor esté disponible públicamente simplemente añadiendo --host=0.0.0
a la línea de comandos:
$ flask run --host=0.0.0.0
Esto le dice a su sistema operativo que escuche en todas las IPs públicas.
Modo de depuración¶
El comando flask run
puede hacer algo más que iniciar el servidor de desarrollo. Al activar el modo de depuración, el servidor se recargará automáticamente si el código cambia, y mostrará un depurador interactivo en el navegador si se produce un error durante una solicitud.
Advertencia
El depurador permite ejecutar código Python arbitrario desde el navegador. Está protegido por un pin, pero sigue representando un riesgo de seguridad importante. No ejecute el servidor de desarrollo o el depurador en un entorno de producción.
To enable debug mode, use the --debug
option.
$ flask --app hello run --debug
* Serving Flask app 'hello'
* Debug mode: on
* Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: nnn-nnn-nnn
Vea también:
Servidor de desarrollo and Interfaz de línea de comandos for information about running in debug mode.
Depuración de errores de la aplicación para información sobre el uso del depurador incorporado y otros depuradores.
Registro y Manejo de los errores de la aplicación para registrar errores y mostrar páginas de error agradables.
Escape de HTML¶
Cuando se devuelve HTML (el tipo de respuesta por defecto en Flask), cualquier valor proporcionado por el usuario en la salida debe ser escapado para protegerlo de ataques de inyección. Las plantillas HTML renderizadas con Jinja, introducidas más tarde, harán esto automáticamente.
escape()
, que se muestra aquí, puede utilizarse manualmente. Se omite en la mayoría de los ejemplos por razones de brevedad, pero siempre debes ser consciente de cómo estás utilizando datos no confiables.
from markupsafe import escape
@app.route("/<name>")
def hello(name):
return f"Hello, {escape(name)}!"
Si un usuario logró enviar el nombre <script>alert("bad")</script>
, el escape hace que se renderice como texto, en lugar de ejecutar el script en el navegador del usuario.
La variable <name>
en la ruta captura un valor de la URL y lo pasa a la función de la vista. Estas reglas de las variables se explican a continuación.
Enrutamiento¶
Las aplicaciones web modernas utilizan URLs significativas para ayudar a los usuarios. Es más probable que a los usuarios les guste una página y vuelvan si la página utiliza una URL significativa que puedan recordar y utilizar para visitar directamente una página.
Utilice el decorador route()
para vincular una función a una URL.
@app.route('/')
def index():
return 'Index Page'
@app.route('/hello')
def hello():
return 'Hello, World'
Puedes hacer más. Puedes hacer que partes de la URL sean dinámicas y adjuntar múltiples reglas a una función.
Normas variables¶
Puedes añadir secciones variables a una URL marcando las secciones con <nombre_de_variable>
. Su función recibe entonces el <nombre_de_variable>
como argumento de palabra clave. Opcionalmente, puedes usar un convertidor para especificar el tipo de argumento como <converter:nombre_de_variable>
.
from markupsafe import escape
@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return f'User {escape(username)}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return f'Post {post_id}'
@app.route('/path/<path:subpath>')
def show_subpath(subpath):
# show the subpath after /path/
return f'Subpath {escape(subpath)}'
Tipos de convertidores:
|
(Por defecto) acepta cualquier texto sin barra |
|
acepta números enteros positivos |
|
acepta valores positivos en coma flotante |
|
como |
|
acepta cadenas (string) UUID |
URLs únicas / Comportamiento de la redirección¶
Las dos reglas siguientes difieren en el uso de la barra diagonal final:
@app.route('/projects/')
def projects():
return 'The project page'
@app.route('/about')
def about():
return 'The about page'
La URL canónica del endpoint projects
tiene una barra al final. Es similar a una carpeta en un sistema de archivos. Si accedes a la URL sin la barra final (/projects
), Flask te redirige a la URL canónica con la barra final (/projects/
).
La URL canónica para el endpoint about
no tiene una barra al final. Es similar a la ruta de un archivo. El acceso a la URL con una barra al final (/about/
) produce un error 404 «Not Found». Esto ayuda a mantener las URLs únicas para estos recursos, lo que ayuda a los motores de búsqueda a evitar indexar la misma página dos veces.
Construcción de URLs¶
Para construir una URL a una función específica, utilice la función url_for()
. Acepta el nombre de la función como primer argumento y cualquier número de argumentos de palabra clave, cada uno correspondiente a una parte variable de la regla de la URL. Las partes variables desconocidas se añaden a la URL como parámetros de consulta.
¿Por qué querrías construir URLs usando la función de inversión de URLs url_for()
en lugar de codificarlas en tus plantillas?
La inversión suele ser más descriptiva que la codificación de las URL.
Puedes cambiar tus URLs de una sola vez en lugar de tener que recordar cambiar manualmente las URLs codificadas.
La construcción de URLs maneja el escape de caracteres especiales de forma transparente.
Las rutas generadas son siempre absolutas, evitando el comportamiento inesperado de las rutas relativas en los navegadores.
Si tu aplicación está situada fuera de la raíz de la URL, por ejemplo, en
/mi_aplicacion
en lugar de/
,url_for()
lo gestiona adecuadamente.
Por ejemplo, aquí usamos el método test_request_context()
para probar url_for()
. test_request_context()
le dice a Flask que se comporte como si estuviera manejando una petición incluso mientras usamos un shell de Python. Ver Contextos locales.
from flask import url_for
@app.route('/')
def index():
return 'index'
@app.route('/login')
def login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return f'{username}\'s profile'
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('login', next='/'))
print(url_for('profile', username='John Doe'))
/
/login
/login?next=/
/user/John%20Doe
Métodos HTTP¶
Las aplicaciones web utilizan diferentes métodos HTTP para acceder a las URL. Debes familiarizarte con los métodos HTTP mientras trabajas con Flask. Por defecto, una ruta sólo responde a peticiones GET
. Puedes utilizar el argumento methods
del decorador route()
para manejar diferentes métodos HTTP:
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return do_the_login()
else:
return show_the_login_form()
El ejemplo anterior mantiene todos los métodos para la ruta dentro de una función, lo que puede ser útil si cada parte utiliza algunos datos comunes.
También puedes separar las vistas para diferentes métodos en diferentes funciones. Flask proporciona un atajo para decorar dichas rutas con get()
, post()
, etc. para cada método HTTP común.
@app.get('/login')
def login_get():
return show_the_login_form()
@app.post('/login')
def login_post():
return do_the_login()
Si GET
está presente, Flask añade automáticamente soporte para el método HEAD
y maneja las peticiones HEAD
de acuerdo con el HTTP RFC. Del mismo modo, OPTIONS
se implementa automáticamente por ti.
Archivos estáticos¶
Las aplicaciones web dinámicas también necesitan archivos estáticos. Por lo general, de ahí vienen los archivos CSS y JavaScript. Idealmente tu servidor web está configurado para servirlos por ti, pero durante el desarrollo Flask puede hacerlo también. Simplemente crea una carpeta llamada static
en tu paquete o junto a tu módulo y estará disponible en /static
en la aplicación.
Para generar URLs para archivos estáticos, utilice el nombre de endpoint especial 'static'
:
url_for('static', filename='style.css')
El archivo debe ser almacenado en el sistema de archivos como static/style.css
.
Plantillas de renderizado¶
Generar HTML desde Python no es divertido, y en realidad es bastante engorroso porque tienes que hacer el escape de HTML por tu cuenta para mantener la aplicación segura. Por eso Flask configura el motor de plantillas Jinja2 por ti automáticamente.
Templates can be used to generate any type of text file. For web applications, you’ll primarily be generating HTML pages, but you can also generate markdown, plain text for emails, and anything else.
For a reference to HTML, CSS, and other web APIs, use the MDN Web Docs.
Para renderizar una plantilla puedes utilizar el método render_template()
. Todo lo que tienes que hacer es proporcionar el nombre de la plantilla y las variables que quieres pasar al motor de plantillas como argumentos de palabra clave. Este es un ejemplo sencillo de cómo renderizar una plantilla:
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
Flask buscará las plantillas en la carpeta templates
. Así que si su aplicación es un módulo, esta carpeta está al lado de ese módulo, si es un paquete está realmente dentro de su paquete:
Caso 1: Un módulo:
/application.py
/templates
/hello.html
Caso 2: Un paquete:
/application
/__init__.py
/templates
/hello.html
Para las plantillas puedes utilizar toda la potencia de las plantillas de Jinja2. Dirígete a la documentación oficial de Jinja2 Template Documentation para más información.
Aquí tiene una plantilla de ejemplo:
<!doctype html>
<title>Hello from Flask</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
Dentro de las plantillas también tienes acceso a los objetos config
, request
, session
y g
1 así como a las funciones url_for()
y get_flashed_messages()
.
Las plantillas son especialmente útiles si se utiliza la herencia. Si quieres saber cómo funciona, consulta Herencia de plantillas. Básicamente la herencia de plantillas permite mantener ciertos elementos en cada página (como la cabecera, la navegación y el pie de página).
El escape automático está activado, así que si name
contiene HTML será escapado automáticamente. Si puedes confiar en una variable y sabes que será HTML seguro (por ejemplo, porque proviene de un módulo que convierte el marcado wiki en HTML) puedes marcarla como segura usando la clase Markup
o usando el filtro |safe
en la plantilla. Dirígete a la documentación de Jinja 2 para ver más ejemplos.
He aquí una introducción básica al funcionamiento de la clase Markup
:
>>> from markupsafe import Markup
>>> Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>'
Markup('<strong>Hello <blink>hacker</blink>!</strong>')
>>> Markup.escape('<blink>hacker</blink>')
Markup('<blink>hacker</blink>')
>>> Markup('<em>Marked up</em> » HTML').striptags()
'Marked up » HTML'
Changelog
Distinto en la versión 0.5: El autoescapado ya no está activado para todas las plantillas. Las siguientes extensiones de plantillas activan el autoescapado: .html
, .htm
, .xml
, .xhtml
. Las plantillas cargadas desde una cadena tendrán el autoescapado desactivado.
- 1
¿No sabes qué es ese objeto
g
? Es algo en lo que puedes almacenar información para tus propias necesidades. Consulta la documentación deflask.g
y Uso de SQLite 3 con Flask.
Acceso a los datos de la solicitud¶
Para las aplicaciones web es crucial reaccionar a los datos que un cliente envía al servidor. En Flask esta información la proporciona el objeto global request
. Si tienes algo de experiencia con Python te preguntarás cómo puede ser global ese objeto y cómo consigue Flask seguir siendo threadsafe. La respuesta es el contexto local:
Contextos locales¶
Información privilegiada
Si quieres entender cómo funciona esto y cómo puedes implementar pruebas con locales de contexto, lee esta sección, de lo contrario sólo sáltatela.
Algunos objetos en Flask son objetos globales, pero no del tipo habitual. Estos objetos son en realidad proxies de objetos que son locales a un contexto específico. Menudo trabalenguas. Pero en realidad es bastante fácil de entender.
Imagina que el contexto es el hilo de manejo. Llega una petición y el servidor web decide generar un nuevo hilo (o algo más, el objeto subyacente es capaz de tratar con sistemas de concurrencia distintos de los hilos). Cuando Flask inicia su gestión interna de peticiones, averigua que el hilo actual es el contexto activo y vincula la aplicación actual y los entornos WSGI a ese contexto (hilo). Lo hace de una manera inteligente para que una aplicación pueda invocar a otra sin romperse.
¿Qué significa esto para ti? Básicamente puedes ignorar por completo que esto es así a menos que estés haciendo algo como pruebas unitarias. Te darás cuenta de que el código que depende de un objeto request se romperá de repente porque no hay un objeto request. La solución es crear un objeto request y vincularlo al contexto. La solución más fácil para las pruebas unitarias es utilizar el gestor de contexto test_request_context()
. En combinación con la sentencia with
vinculará una petición de prueba para que puedas interactuar con ella. Aquí hay un ejemplo:
from flask import request
with app.test_request_context('/hello', method='POST'):
# now you can do something with the request until the
# end of the with block, such as basic assertions:
assert request.path == '/hello'
assert request.method == 'POST'
La otra posibilidad es pasar todo un entorno WSGI al método request_context()
:
with app.request_context(environ):
assert request.method == 'POST'
El objeto Request¶
El objeto request está documentado en la sección API y no lo cubriremos aquí en detalle (ver Request
). A continuación, un amplio resumen de algunas de las operaciones más comunes. En primer lugar tienes que importarlo desde el módulo flask
:
from flask import request
El método de solicitud actual está disponible utilizando el atributo method
. Para acceder a los datos del formulario (datos transmitidos en una petición POST
o PUT
) se puede utilizar el atributo form
. He aquí un ejemplo completo de los dos atributos mencionados anteriormente:
@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
if valid_login(request.form['username'],
request.form['password']):
return log_the_user_in(request.form['username'])
else:
error = 'Invalid username/password'
# the code below is executed if the request method
# was GET or the credentials were invalid
return render_template('login.html', error=error)
¿Qué ocurre si la clave no existe en el atributo form
? En ese caso se produce un KeyError
especial. Puedes cogerlo como un KeyError
estándar, pero si no lo haces, se muestra una página de error HTTP 400 Bad Request en su lugar. Así que para muchas situaciones no tienes que lidiar con ese problema.
Para acceder a los parámetros enviados en la URL (?key=value
) puede utilizar el atributo args
:
searchword = request.args.get('key', '')
Recomendamos acceder a los parámetros de la URL con get o capturando el KeyError
porque los usuarios podrían cambiar la URL y presentarles una página 400 de solicitud incorrecta en ese caso no es amigable para el usuario.
Para una lista completa de métodos y atributos del objeto request, dirígete a la documentación de Request
.
Carga de archivos¶
Puedes manejar los archivos subidos con Flask fácilmente. Sólo asegúrese de no olvidar establecer el atributo enctype="multipart/form-data"
en su formulario HTML, de lo contrario el navegador no transmitirá sus archivos en absoluto.
Los archivos subidos se almacenan en la memoria o en una ubicación temporal en el sistema de archivos. Puede acceder a esos archivos mirando el atributo files
del objeto request. Cada archivo subido se almacena en ese diccionario. Se comporta como un objeto file
estándar de Python, pero también tiene un método save()
que permite almacenar ese fichero en el sistema de ficheros del servidor. Aquí hay un ejemplo sencillo que muestra cómo funciona:
from flask import request
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['the_file']
f.save('/var/www/uploads/uploaded_file.txt')
...
Si quieres saber cómo se nombró el archivo en el cliente antes de subirlo a tu aplicación, puedes acceder al atributo filename
. Sin embargo, ten en cuenta que este valor puede ser falsificado, así que nunca confíes en él. Si quieres utilizar el nombre de archivo del cliente para almacenar el archivo en el servidor, pásalo a través de la función secure_filename()
que te proporciona Werkzeug:
from werkzeug.utils import secure_filename
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
file = request.files['the_file']
file.save(f"/var/www/uploads/{secure_filename(file.filename)}")
...
Para ver algunos ejemplos mejores, consulte Carga de archivos.
Redirecciones y errores¶
Para redirigir a un usuario a otro endpoint, utilice la función redirect()
; para abortar una solicitud antes de tiempo con un código de error, utilice la función abort()
:
from flask import abort, redirect, url_for
@app.route('/')
def index():
return redirect(url_for('login'))
@app.route('/login')
def login():
abort(401)
this_is_never_executed()
Este es un ejemplo bastante inútil porque un usuario será redirigido desde el índice a una página a la que no puede acceder (401 significa acceso denegado) pero muestra cómo funciona.
Por defecto se muestra una página de error en blanco y negro para cada código de error. Si quieres personalizar la página de error, puedes usar el decorador errorhandler()
:
from flask import render_template
@app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'), 404
Observa el 404
después de la llamada render_template()
. Esto le dice a Flask que el código de estado de esa página debe ser 404 que significa no encontrado. Por defecto se asume 200 que se traduce en: todo ha ido bien.
Consulte Manejo de los errores de la aplicación para más detalles.
Acerca de las respuestas¶
El valor de retorno de una función de la vista se convierte automáticamente en un objeto de respuesta. Si el valor devuelto es una cadena, se convierte en un objeto de respuesta con la cadena como cuerpo de la respuesta, un código de estado 200 OK
y un mimetype:text/html. Si el valor de retorno es un dict o una lista, se llama a jsonify()
para producir una respuesta. La lógica que aplica Flask para convertir los valores de retorno en objetos de respuesta es la siguiente:
Si se devuelve un objeto response del tipo correcto se devuelve directamente desde la vista.
Si es una cadena, se crea un objeto response con esos datos y los parámetros por defecto.
Si se trata de un iterador o generador que devuelve cadenas o bytes, se trata como una respuesta de flujo.
Si es un dict o una lista, se crea un objeto de respuesta utilizando
jsonify()
.Si se devuelve una tupla, los elementos de la tupla pueden proporcionar información extra. Estas tuplas tienen que tener la forma
(response, state)
,(response, headers)
, o(response, state, headers)
. El valorstatus
anulará el código de state yheaders
puede ser una lista o diccionario de valores de cabecera adicionales.Si nada de esto funciona, Flask asumirá que el valor de retorno es una aplicación WSGI válida y lo convertirá en un objeto response.
Si quieres obtener el objeto respuesta resultante dentro de la vista puedes utilizar la función make_response()
.
Imagina que tienes una vista como esta:
from flask import render_template
@app.errorhandler(404)
def not_found(error):
return render_template('error.html'), 404
Sólo tienes que envolver la expresión de retorno con make_response()
y obtener el objeto de respuesta para modificarlo, luego devolverlo:
from flask import make_response
@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template('error.html'), 404)
resp.headers['X-Something'] = 'A value'
return resp
APIs con JSON¶
Un formato de respuesta común al escribir una API es JSON. Es fácil empezar a escribir una API de este tipo con Flask. Si devuelves un dict
o list
desde una vista, se convertirá en una respuesta JSON.
@app.route("/me")
def me_api():
user = get_current_user()
return {
"username": user.username,
"theme": user.theme,
"image": url_for("user_image", filename=user.image),
}
@app.route("/users")
def users_api():
users = get_all_users()
return [user.to_json() for user in users]
Este es un atajo para pasar los datos a la función jsonify()
, que serializará cualquier tipo de datos JSON soportado. Esto significa que todos los datos en el dict o la lista deben ser JSON serializable.
Para los tipos complejos, como los modelos de bases de datos, querrás utilizar una biblioteca de serialización para convertir los datos en tipos JSON válidos primero. Hay muchas bibliotecas de serialización y extensiones de la API de Flask mantenidas por la comunidad que soportan aplicaciones más complejas.
Sesiones¶
Además del objeto request, existe un segundo objeto llamado session
que permite almacenar información específica de un usuario de una solicitud a otra. Esto se implementa encima de las cookies para usted y firma las cookies criptográficamente. Lo que esto significa es que el usuario podría mirar el contenido de su cookie pero no modificarlo, a menos que conozca la clave secreta utilizada para la firma.
Para utilizar las sesiones hay que establecer una clave secreta. Así es como funcionan las sesiones:
from flask import session
# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'
@app.route('/')
def index():
if 'username' in session:
return f'Logged in as {session["username"]}'
return 'You are not logged in'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
'''
@app.route('/logout')
def logout():
# remove the username from the session if it's there
session.pop('username', None)
return redirect(url_for('index'))
Cómo generar buenas claves secretas
Una clave secreta debe ser lo más aleatoria posible. Su sistema operativo tiene formas de generar datos bastante aleatorios basados en un generador aleatorio criptográfico. Utilice el siguiente comando para generar rápidamente un valor para Flask.secret_key
(o SECRET_KEY
):
$ python -c 'import secrets; print(secrets.token_hex())'
'192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
Una nota sobre las sesiones basadas en cookies: Flask tomará los valores que pongas en el objeto de sesión y los serializará en una cookie. Si encuentra que algunos valores no persisten a través de las solicitudes, las cookies están efectivamente habilitadas, y no está recibiendo un mensaje de error claro, compruebe el tamaño de la cookie en las respuestas de su página en comparación con el tamaño soportado por los navegadores web.
Además de las sesiones por defecto basadas en el lado del cliente, si quieres manejar las sesiones en el lado del servidor, hay varias extensiones de Flask que soportanhis.
Mensajes Flash¶
Las buenas aplicaciones e interfaces de usuario se basan en la retroalimentación. Si el usuario no recibe suficiente retroalimentación, probablemente terminará odiando la aplicación. Flask proporciona una forma muy sencilla de dar retroalimentación a un usuario con el sistema de parpadeo. El sistema de parpadeo básicamente permite grabar un mensaje al final de una solicitud y acceder a él en la siguiente (y sólo la siguiente) solicitud. Esto se suele combinar con una plantilla de diseño para exponer el mensaje.
Para flashear un mensaje utilice el método flash()
, para obtener los mensajes puede utilizar get_flashed_messages()
que también está disponible en las plantillas. Ver Mensaje Flash para un ejemplo completo.
Registro¶
Changelog
Nuevo en la versión 0.3.
A veces puedes encontrarte en una situación en la que tratas con datos que deberían ser correctos, pero que en realidad no lo son. Por ejemplo, puedes tener algún código del lado del cliente que envíe una petición HTTP al servidor pero que esté obviamente malformada. Esto puede ser causado por un usuario que manipula los datos, o por un fallo en el código del cliente. La mayoría de las veces está bien responder con 400 Bad Request
en esa situación, pero a veces eso no es suficiente y el código tiene que seguir trabajando.
Puede que aún así quieras registrar que ha ocurrido algo sospechoso. Aquí es donde los registradores son útiles. A partir de la versión 0.3 de Flask, se ha preconfigurado un registrador para su uso.
Aquí hay algunos ejemplos de llamadas de registro:
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
El logger
adjunto es un Logger
estándar de registro, así que dirígete a la documentación oficial de logging
para más información.
Hooking en el WSGI middleware¶
Para añadir WSGI middleware a tu aplicación Flask, envuelve el atributo wsgi_app
de la aplicación. Por ejemplo, para aplicar el middleware ProxyFix
de Werkzeug para ejecutar detrás de Nginx:
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)
Envolver app.wsgi_app
en lugar de app
significa que app
sigue apuntando a tu aplicación Flask, no al middleware, por lo que puedes seguir utilizando y configurando app
directamente.
Uso de las extensiones de Flask¶
Las extensiones son paquetes que ayudan a realizar tareas comunes. Por ejemplo, Flask-SQLAlchemy proporciona soporte para SQLAlchemy que lo hace simple y fácil de usar con Flask.
Para más información sobre las extensiones de Flask, véase Extensiones.
Despliegue en un servidor web¶
¿Listo para desplegar tu nueva aplicación Flask? Consulte Despliegue en producción.