Una razón Pitón es una excelente opción para el desarrollo web es la amplitud de marcos web disponibles en el idioma. Entre los más populares y útiles se encuentra Flask, que le permite comenzar de manera simple (“una gota a la vez”) pero crece con su aplicación para agregar casi todas las funciones que necesita.
En este artículo, explicaremos la configuración y el uso de Flask 3.0 para aplicaciones web básicas. También abordaremos el uso de Jinja2 para crear plantillas y abordar problemas comunes como cambiar los tipos de respuesta y manejar redirecciones.
Configurar el matraz
Flask 3.0 es fácil de configurar. Usar pip install flask
para instalar Flask y todas sus dependencias incluido el sistema de plantillas Jinja2.
Al igual que con cualquier marco de Python, es mejor crear un proyecto usando Flask dentro de un Entorno virtual de Python. Esto aísla su proyecto de su instalación principal de Python y de otros proyectos que podrían usar Flask y sus dependencias (ya que podría encontrarse manteniendo diferentes versiones para diferentes proyectos).
Tenga en cuenta que si desea instalar Flask con soporte para funciones asincrónicas o corrutinas, use pip install flask[async]
. En breve tendré más información sobre el uso de Flask con async.
Una aplicación básica de Flask
Una aplicación Flask simple de una ruta se puede escribir en solo unas pocas líneas de código. Guarde la siguiente aplicación de ejemplo simple en un archivo llamado app.py
:
from flask import Flask
app = Flask(__name__)
@app.route("https://www.infoworld.com/")
def home():
return "Hello, world"
Esta aplicación no hace mucho: simplemente crea un sitio web con una única ruta que muestra «Hola, mundo» en el navegador.
Esto es lo que hace cada elemento:
- La línea
app = Flask(__name__)
crea una nueva instancia de una aplicación Flask, llamadaapp
. La clase Flask toma un argumento que es el nombre del módulo o paquete de la aplicación. pasándolo__name__
(el nombre del módulo actual) es una forma rápida de utilizar el módulo actual como punto de partida de la aplicación. En teoría, puedes usar cualquier nombre, pero es habitual usar el nombre del módulo como predeterminado. - El
app.route
El decorador se utiliza para envolver una función e indicar la función que se utilizará para entregar una respuesta para una ruta determinada. En este caso, la ruta es la raíz del sitio ("https://www.infoworld.com/"
) y la respuesta es la cadena"Hello, world"
.
Para ejecutar la aplicación, utilice python -m flask run
en el mismo directorio que app.py
. Deberías ver algo como lo siguiente en la consola:
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Si abre un navegador web para http://127.0.0.1:5000/
deberías ver las palabras «Hola, mundo».
Tenga en cuenta que puede nombrar el archivo principal de su aplicación Flask como desee, pero llamándolo app.py
permite que Flask lo reconozca automáticamente. Para utilizar un nombre diferente, primero debe configurar el FLASK_APP
variable de entorno al nombre del nuevo archivo menos su extensión (por ejemplo, hello
para hello.py
).
También tenga en cuenta que cuando ejecuta una aplicación Flask de esta manera, la ejecuta utilizando el servidor de prueba integrado de Flask, que no es adecuado para implementaciones de producción. Pronto discutiremos cómo implementar Flask en producción.
Rutas y variables de ruta en Flask
Las aplicaciones web suelen utilizar componentes de una ruta como variables que se pasan a la función de ruta. Flask le permite hacer esto mediante una sintaxis de definición de ruta especial.
En este ejemplo, donde tenemos una ruta en el formato de /hi/
seguido de un nombre de usuario, el nombre se extrae y se pasa a la función como nombre de usuario variable.
@app.route("/hi/<username>")
def greet(username):
return f"Hello, {username}"
Visita esta ruta con /hi/Serdar
y verás “Hello, Serdar”
en el navegador.
Tipos de variables de ruta de Flask
Las variables de ruta también pueden ser tipo restringidoagregándoles información de tipo.
Por ejemplo, si usas <int:userid>
que asegura userid
sólo será un número entero. Si utiliza <path:datapath>
la parte de la URL desde esa posición en adelante se extraerá en la variable datapath
. Para ello, si tuviéramos una ruta como /show/<path:datapath>
y usé la URL /show/main/info
entonces main/info
se pasaría en la variable datapath
. (Ver el Documentación del matraz para obtener más información sobre las variables de ruta con restricción de tipo).
Tenga en cuenta que debe tener cuidado al utilizar múltiples rutas similares con diferentes tipos de datos. Si tienes la ruta /data/<int:userid>
y la ruta /data/<string:username>
, cualquier elemento en la segunda posición que no pueda coincidir como un número entero coincidirá como una cadena. Evite este tipo de estructuras de ruta si puede, ya que pueden resultar confusas y difíciles de depurar. Sea lo más claro posible con sus rutas.
Métodos de ruta en Flask
Los decoradores de rutas también pueden especificar el métodos utilizado para acceder a la ruta. Puedes crear múltiples funciones para manejar una sola ruta con diferentes métodos, como este:
@app.route('/post', methods=['GET'])
def post_message_route_get():
return show_post_message_form()
@app.route('/post', methods=['POST'])
def post_message_route_post():
return post_message_to_site()
O puede consolidar rutas en una sola función y tomar decisiones internamente según el método:
from flask import request
@app.route('/post', methods=['GET', 'POST'])
def post_message_route():
if request.method == 'POST':
return post_message_to_site()
# defaults to GET if not POST
return show_post_message_form()
Tenga en cuenta que necesitamos importar el global request
objeto para acceder a la propiedad del método. Exploraremos esto en detalle más adelante.
Flask 2.0 y superiores también te permiten usar app.get
y app.post
como atajos. Las rutas anteriores también podrían expresarse como:
@app.get('/post')
def post_message_route_get():
return show_post_message_form()
@app.post('/post')
def post_message_route_post():
return post_message_to_site()
Solicitar datos en Flask
En la última sección, obtuvimos el método utilizado para invocar una ruta desde el global request
objeto. request
es una instancia de el objeto de solicituddel cual podemos obtener muchos otros detalles sobre la solicitud: sus encabezados, cookies, datos del formulario, cargas de archivos, etc.
Algunas de las propiedades comunes de un Request
objeto incluyen:
.args
: un diccionario que contiene los parámetros de URL. Por ejemplo, una URL con argumentos como?id=1
se expresaría como el diccionario{"id": 1}
..cookies
: un diccionario que contiene las cookies enviadas en la solicitud..files
: un diccionario que contiene los archivos cargados con la solicitud, siendo la clave para cada elemento el nombre del archivo..form
: un diccionario que contiene los datos del formulario de la solicitud, si los hay..headers
: los encabezados sin formato de la solicitud..method
: El método utilizado por la solicitud (p. ej.,GET
,POST
).
Devolver respuestas en Flask
Cuando una función de ruta devuelve datos, Flask hace una mejor suposición para interpretar lo que se ha devuelto:
- Objetos de respuesta se devuelven tal cual. La creación de un objeto de respuesta le brinda un control detallado sobre lo que devuelve al cliente, pero para la mayoría de los casos de uso puede usar uno de los siguientes elementos.
- Las cadenas, incluida la salida de las plantillas Jinja2 (más sobre esto a continuación), se convierten en
Response
objetos, con un200 OK
código de estado y un tipo MIME detext/html
. - Los diccionarios se convierten a JSON.
- Las tuplas pueden ser cualquiera de las siguientes:
- (respuesta, código de estado [
int
]) - (respuesta, encabezados [
list/dict
]) - (respuesta, código de estado [
int
]encabezados [list/dict
])
- (respuesta, código de estado [
Generalmente, es mejor devolver lo que deje más claro el trabajo de la función de ruta. Por ejemplo, un controlador de errores 404 puede devolver una tupla doble: el código de error 404 y los detalles del mensaje de error. Esto mantiene la función de ruta ordenada.
Plantillas en Flask
El matraz incluye el Motor de plantillas Jinja2 para generar mediante programación salida HTML a partir de datos. tu usas el render_template
función para generar HTML y luego pasar las variables que se utilizarán en la plantilla.
A continuación se muestra un ejemplo de cómo se ve esto en una ruta:
from flask import render_template
@app.route('/hi/<username>')
def greet(username=None):
return render_template('hello.html', username=username)
Plantillas a las que hace referencia render_template
se encuentran de forma predeterminada en un subdirectorio del directorio del proyecto Flask, llamado plantillas. Para ello, el siguiente archivo estaría en templates/hello.html
:
<!doctype html>
<title>Hi there</title>
{% if username %}
<h1>Hello {{ username }}!</h1>
{% else %}
<h1>Hello, whoever you are!</h1>
{% endif %}
Las plantillas de Jinja2 son una especie de lenguaje en sí mismas, pero este fragmento debería darle una idea de cómo funcionan. Bloques delineados con {% %}
contienen lógica de plantilla y bloques con {{ }}
contienen expresiones que se insertarán en ese punto. Cuando llamamos a esta plantilla con render_template
arriba pasamos username
como argumento de palabra clave; Lo mismo se haría con cualquier otra variable que usaríamos.
Tenga en cuenta que las plantillas de Jinja2 tienen restricciones en el código que se puede ejecutar dentro de ellas, por motivos de seguridad. Por lo tanto, querrás realizar la mayor cantidad de procesamiento posible para una página determinada. antes pasándolo a una plantilla.
Manejadores de errores en Flask
Para crear una ruta que maneje una clase particular de error del servidor, use el errorhandler
decorador:
@app.errorhandler(404)
def page_not_found(error):
return f"error: {error}"
Para esta aplicación, cada vez que se genera un error 404, el resultado devuelto al cliente será generado por el page_not_found
función. El error
es la excepción generada por la aplicaciónpara que pueda extraer más detalles si es necesario y pasárselos al cliente.
Ejecución y depuración de Flask en producción
El servidor de prueba de Flask mencionado anteriormente en este artículo no es adecuado para implementar Flask en producción. Para implementaciones de producción, utilice un servidor totalmente compatible con WSGI, con la app
objeto creado por Flask()
como la aplicación WSGI.
La documentación de Flask tiene detalles sobre la implementación en las opciones de alojamiento más comunes, así como detalles sobre cómo alojar aplicaciones Flask usted mismo, por ejemplo, mediante Apache. mod_wsgi
o mediante uWSGI en Nginx.
Usando asíncrono en Flask
Originalmente, Flask no tenía soporte explícito para funciones o corrutinas asincrónicas. Las corrutinas ahora son una característica estándar en Python y, a partir de la versión 2.0, Flask admite métodos asíncronos para manejadores de rutas. Sin embargo, el soporte asíncrono en Flask viene como un complemento, por lo que debes usar pip install flask[async]
para instalar esta característica.
Aquí hay un ejemplo de un matraz. async
ruta:
@app.route("/embed/<embed_id>")
async def get_embed(embed_id):
data = await async_render_embed(embed_id)
return data
El soporte asíncrono de Flask no cambia el hecho de que se ejecuta como una aplicación WSGI con un solo trabajador para manejar las solicitudes entrantes. Si desea admitir solicitudes de larga duración, como conexiones API WebSocket, usar async solo en sus funciones de ruta no será suficiente. Es posible que desee considerar el uso el marco de Quartque es compatible con API con Flask pero utiliza la interfaz ASGI para manejar mejor las solicitudes de larga duración y múltiples solicitudes simultáneas.
Copyright © 2024 IDG Communications, Inc.