Sirviendo archivos estáticos con Flask

Flask es una excelente opción para crear aplicaciones web de forma modular utilizando Python. A diferencia de Django y otros análogos como Ruby on Rails, Flask es una micro-fra...

Configuración de Flask

Matraz es una excelente opción para crear aplicaciones web de forma modular utilizando Python. A diferencia de Django y otros análogos como Ruby on Rails, Flask es un micro-framework. Esto significa que incluye solo lo que es necesario para hacer el desarrollo web central, dejando la mayor parte de las opciones más allá de ese subconjunto mínimo para usted.

Este enfoque tiene una gran ventaja al mantener el código y el flujo de trabajo simples, especialmente en proyectos más pequeños. Aquí le mostraremos cómo servir archivos estáticos como JS, CSS e imágenes usando Flask.

Asegúrate de tener Python 3 instalado. Puede usar pyenv para esto, lo que lo ayuda a seleccionar las versiones de Python. Sigue esta guía para configurar Python 3 usando **pyenv **. Si prefiere entorno virtual en su lugar, asegúrese de consultar la documentación, pero solo asegúrese de tener un entorno de Python 3 activo.

Antes de que podamos comenzar a servir archivos estáticos con Flask, debemos instalarlo y poner en marcha una aplicación simple. Para hacer esto, instale Flask usando el comando:

1
$ pip install flask

Ahora crearemos una aplicación básica de Flask que sirva como página de inicio en la que mostraremos el texto clásico, "Hello World".

1
$ mkdir serving_static

En este nuevo directorio, cree un nuevo archivo que cree la aplicación Flask y la ejecute. En este archivo, creamos una ruta de Flask donde mostraremos un mensaje de bienvenida utilizando una plantilla de Flask.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# serve.py

from flask import Flask
from flask import render_template

# creates a Flask application, named app
app = Flask(__name__)

# a route where we will display a welcome message via an HTML template
@app.route("/")
def hello():
    message = "Hello, World"
    return render_template('index.html', message=message)

# run the application
if __name__ == "__main__":
    app.run(debug=True)

Ahora vamos a crear la plantilla para mostrar nuestro mensaje. Cree un archivo HTML en la ubicación "serving_static/templates/index.html" con el siguiente código HTML. Tenga en cuenta la variable message de Python pasada desde el archivo serve.py anterior.

1
2
3
4
5
6
7
8
9
<!-- templates/index.html -->
<html>
  <head>
    <title>Flask Shop</title>
  </head>
  <body>
    <h1>{{message}}</h1>
  </body>
</html>

Ahora estamos listos para ejecutar la aplicación. De vuelta en el directorio raíz "serving_static", ejecute la aplicación usando el comando:

1
$ python serve.py

Si el servidor se inició correctamente, recibirá un mensaje de que se inició y una URL para ver la aplicación. Abra esta URL en su navegador y ahora debería ver nuestro mensaje "Hello, World" en el navegador.

Hello World

Flask crea rutas de aplicaciones usando decoradores como el que se ve en serve.py arriba. Un decorador como @app.route("/") crea una nueva ruta en la ruta proporcionada. La definición de función a continuación contiene la lógica de la aplicación que se ejecutará cuando se reciba una solicitud en esa URL.

Servir archivos estáticos usando un directorio estático

Los archivos estáticos más comunes que querrá servir en una aplicación web son los archivos CSS de su aplicación para diseñar la aplicación, así como los archivos JavaScript que agregan un comportamiento dinámico a la página. En esta sección, veremos cómo servir archivos CSS y JavaScript al agregarlos a la aplicación simple que creamos anteriormente.

Los archivos estáticos en Flask tienen una ruta especial. Todas las URL de aplicaciones que comienzan con "/static", por convención, se sirven desde una carpeta ubicada en "/static" dentro de la carpeta raíz de su aplicación.

Esto significa que si creamos una carpeta "/estática" dentro de nuestra carpeta principal "serving_static", podremos servir archivos estáticos como CSS, JS, imágenes y otros activos simplemente colocándolos dentro de esa " carpeta /static".

Ahora cambiemos el mensaje de bienvenida en la página de índice de nuestra aplicación para presentar "The Flask Shop", una tienda ficticia donde los visitantes pueden comprar libros de Flask.

Primero, queremos que la plantilla de página de índice muestre al visitante el nombre de la tienda, así como una lista de libros que están en oferta. Actualice su plantilla HTML en "serving_static_/templates/index.html" con estos cambios para que tenga el siguiente aspecto.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!-- templates/index.html -->
<html>
  <head>
    <title>Flask Shop</title>
    <link rel="stylesheet" href="/static/style.css">
  </head>
  <body>
    <h1>{{message}}</h1>

    <h3>On sale this week alone:</h3>
    <ol>
      <li>Flask By Example</li>
      <li>Uncluttered Flask</li>
      <li>Flask From First Principles</li>
    </ol>

    <script src="/static/scripts.js" charset="utf-8"></script>
  </body>
</html>

Notarás que el título de la página ahora es "Flask Shop", y hemos incluido una lista de libros de Flask a la venta. El visitante debería poder ver en la página esta lista de libros cuando visite la página de inicio de nuestra aplicación de tienda.

Eche un vistazo a la sección de encabezado de la plantilla HTML nuevamente. Notará que ahora estamos vinculando a un nuevo archivo, específicamente una hoja de estilo CSS llamada "style.css". La ruta "/static/style.css" muestra que este archivo se encuentra en nuestra carpeta "/static".

Recuerde que Flask sirve archivos colocados en "/static" automáticamente como archivos estáticos, en lugar de intentar ejecutar estos archivos como archivos fuente de Python.

Ahora vamos a crear una carpeta estática en "serving_static/static" para contener todos nuestros archivos estáticos.

Dentro de esta carpeta estática, creemos el nuevo archivo "style.css", y agreguemos las siguientes reglas CSS para agregar algo de estilo a nuestra aplicación de escaparate.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/* static/style.css */

h1 {
    color: navajowhite;
    font-variant-caps: all-small-caps;
    font-size: 46px;
}

h3 {
  color: white;
  font-size: 36px;
}

li {
  color: red;
  font-size: 50px;
}

body {
    background: firebrick;
}

Con estas reglas de estilo definidas, nuestra aplicación cambiará el fondo blanco liso que vimos en nuestro ejemplo de "Hola, mundo" por un fondo rojo "ladrillo refractario" más colorido. También estamos definiendo un estilo blanco distintivo para el texto de la página.

Ahora actualicemos el mensaje que mostramos en la página. Vuelve a "serving_static/serve.py" y actualiza la variable message para que sea el nombre de la tienda. Busque la función hello() y actualice la variable message de la siguiente manera:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# serve.py

...

# a route where we will display a welcome message via an HTML template
@app.route("/")
def hello():
    message = "The Flask Shop"
    return render_template('index.html', message=message)

...    

Ahora, reinicie su servidor y ejecute python serve.py nuevamente. Luego visite la URL de la aplicación en localhost:5000 y debería ver nuestra lista de libros Flask.

The Flask Shop

Tenga en cuenta que el estilo de la aplicación ahora se está tomando de nuestro archivo CSS que se sirve desde el directorio "/static" de nuestra aplicación Flask.

Si vuelve a mirar nuestra plantilla "serving_static/templates/index.html", antes de la etiqueta de cierre </body>, estamos insertando una etiqueta de secuencia de comandos de JavaScript.

La URL de este script es "/static/scripts.js". Este es otro archivo estático que será entregado por Flask desde nuestra carpeta "/static".

Ahora vamos a crear este archivo JavaScript en "serving_static/static/scripts.js". El contenido será un código JavaScript para cambiar dinámicamente el color de fondo de nuestra aplicación de tienda cada segundo. Esto crea un efecto dramático para llamar la atención sobre la venta por tiempo limitado en nuestra tienda ficticia Flask.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// scripts.js

// a couple of different backgrounds to style the shop
var background1 = 'black';
var background2 = 'firebrick';

// this lets us toggle the background state
var color = true;

// every 1 second, switch the background color, alternating between the two styles
setInterval(function () {
  document.body.style.backgroundColor = (color ? background1 : background2)
  color = !color;
}, 1000);

Ahora, detenga su servidor y vuelva a ejecutar python serve.py una vez más. Cuando visita nuestra aplicación en el navegador, el fondo de la página debe parpadear y cambiar cada segundo de un tono rojo, esto:

Red background

a un tono de negro, así:

Black background

La función setInterval en nuestro código JavaScript cambia el fondo cada segundo en un bucle de tiempo continuo.

Ahora ofrecemos archivos JavaScript y CSS desde nuestra carpeta "/static" para diseñar y mejorar el comportamiento de nuestra aplicación.

Si tiene archivos CSS o JavaScript adicionales, puede agregarlos a la carpeta "/static" de la misma manera y hacer referencia a ellos como lo hicimos anteriormente.

Servir archivos JavaScript

Otro caso de uso común cuando se trata de servir archivos estáticos en aplicaciones web es servir bibliotecas de terceros como Backbone.js, Vue.js, Bootstrap o React.

Cualquier tipo de biblioteca que desee incluir se puede servir casi de la misma manera que vimos anteriormente desde nuestro directorio "/static".

Como ejemplo, veamos cómo incluir la biblioteca JavaScript Backbone.js en nuestra aplicación.

Una buena idea al servir bibliotecas de terceros es ubicarlas dentro de un directorio especial lib o vendor dentro de la carpeta "/static". Puede nombrar esta carpeta de terceros como desee.

La clave, sin embargo, es colocar las bibliotecas externas en su propia carpeta donde puede actualizar fácilmente las versiones o realizar otras tareas de administración separadas del código de su propia aplicación.

Con esto en mente, cree una nueva carpeta en "serving_static/static/lib". Ya que estamos incluyendo Backbone.js, descargue la versión de un solo archivo de Backbone.js aquí, y luego colóquelo dentro de la nueva carpeta lib dentro de nuestra carpeta "/static".

Backbone.js tiene una fuerte dependencia de Subrayado.js, otra biblioteca de JavaScript, que proporciona muchas utilidades esenciales. Así que descarga la última versión de Underscore.js aquí y colócalo junto a Backbone.js en tu carpeta "/static/lib".

Ahora podemos hacer uso de Backbone.js incluyéndolo en nuestra plantilla de página y llamando a sus funciones.

De vuelta en su plantilla, en el archivo "serving_static/templates/index.html", busque la etiqueta de cierre </ol>. Después, en una nueva línea, cree un nuevo elemento de encabezado que manipularemos con Backbone.js.

Además, agregue nuevas etiquetas de script antes de la etiqueta de cierre </body>. En estas etiquetas, incluimos Underscore.js y Backbone.js, así como también escribimos código para actualizar el DOM usando el código Backbone.

La parte actualizada de la plantilla index.html debería tener el siguiente aspecto.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!-- templates/index.html -->

...
<ol>
      <li>Flask By Example</li>
      <li>Uncluttered Flask</li>
      <li>Flask From First Principles</li>
</ol>

    <h4 id="version" style="color:white;">Backbone</h4>

    <script src="/static/scripts.js" charset="utf-8"></script>
    <script src="/static/lib/underscore.js" charset="utf-8"></script>
    <script src="/static/lib/backbone.js" charset="utf-8"></script>
    <script type="text/javascript">
      document.getElementById('version').innerHTML = "Proudly built with Backbone.js version " + Backbone.VERSION;
    </script>
  </body>
  ...

Nuestra última etiqueta <script> anterior utiliza Backbone.js. Si reinicia el servidor ahora, debería ver que el texto en la página en la parte inferior muestra la versión correcta de Backbone.js que estamos usando.

Backbone version

Si estuviéramos usando Vue.js, React o cualquier otra biblioteca, podríamos agregarla y servir sus archivos estáticos de la misma manera, haciéndola disponible para nuestra aplicación.

Servir imágenes y otros tipos de archivos

Otros tipos de archivos, como imágenes e incluso archivos .txt y .pdf se pueden servir de manera similar a los archivos JS y CSS que mostramos anteriormente. Simplemente colóquelos en "/static" y vincúlelos.

Veamos un ejemplo de código de servir imágenes. Aquí hay dos imágenes de libros relacionados: Libro 1 y [libro2](https://s3. amazonaws.com/wikihtp/media/serving-static-files-flask-8.jpg). Descárguelos y colóquelos en una nueva carpeta en "serving_static/static/images".

Ahora podemos agregar una sección de libros "Relacionados" a nuestra plantilla de índice, donde mostraremos las imágenes de estos libros.

Actualice su plantilla index.html con lo siguiente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!-- templates/index.html -->

...

<h4 id="version" style="color:white;">Backbone</h4>

<h3>Related</h3>
<img src="/static/images/book1.png" alt="Related Book 1" width="20%" height="auto">
<img src="/static/images/book2.jpg" alt="Related Book 2" width="20%" height="auto">

...

Ahora, cuando reinicie el servidor y visite la aplicación en el navegador, verá imágenes de los libros relacionados.

related books

Preparación de archivos estáticos con un sistema de compilación

Una de las cosas más importantes que faltan en nuestra configuración en este momento es la minimización de activos estáticos, la concatenación de JavaScript, CSS y otras optimizaciones para hacer que la aplicación sea más rápida. Además, el uso de preprocesadores y compiladores como Sass, Coffeescript y Babel debe manejarse manualmente en nuestra configuración actual.

Utilizando un sistema de construcción como paquete web, Trago, Desalmuerzo , o Navegador te ayuda a automatizar este proceso.

Si estás interesado en explorar esto, aquí tienes la [Guía de brunch](https://github.com/brunch/brunch-guide/blob/master/content/en/chapter04-starting-from-scratch. md) para agregar Brunch como sistema de compilación para su proyecto.

O puede revisar la documentación de su sistema de compilación preferido para familiarizarse con cómo configurarlo e integrarlo en su aplicación Flask.

Servicio de archivos estáticos en producción {#servicio de archivos estáticos en producción}

Ejecutar su código en producción es un poco diferente de un entorno de desarrollo. En producción, dependiendo de su aplicación, puede encontrar volúmenes de tráfico mucho más altos, lo que puede afectar su servidor.

En producción, se recomienda servir archivos estáticos con un servidor como nginx para mantener la carga en su servidor web de Python lo más ligera posible. Si sirve una gran cantidad de archivos, esto acelerará su aplicación.

Además, querrá utilizar un servidor web Python de grado de producción en lugar del servidor Flask integrado. Algunas buenas opciones son gunicornio, Gévent y Apache con [mod_wsgi](https://modwsgi.readthedocs.io/ es/desarrollar/).

Conclusión

En este artículo, vimos cómo puede servir fácilmente activos estáticos usando Flask. Puede servir JavaScript, CSS, imágenes y otros archivos estáticos. Esto se puede hacer de varias maneras, siendo la más simple usar el directorio "/static", que Flask usará para entregar archivos al cliente.