Grandes aplicaciones como paquetes

Imagina una estructura de aplicación simple de flask que se parece a esto:

/yourapplication
    yourapplication.py
    /static
        style.css
    /templates
        layout.html
        index.html
        login.html
        ...

Aunque esto está bien para aplicaciones pequeñas, para aplicaciones más grandes es una buena idea usar un paquete en lugar de un módulo. El Tutorial está estructurado para utilizar el patrón de paquete, véase el código de ejemplo.

Paquetes sencillos

Para convertirlo en uno más grande, simplemente crea una nueva carpeta yourapplication dentro de la existente y mueve todo debajo de ella. Entonces renombra yourapplication.py a __init__.py. (Asegúrate de borrar todos los archivos .pyc primero, de lo contrario lo más probable es que surgan errores)

Entonces deberías terminar con algo así:

/yourapplication
    /yourapplication
        __init__.py
        /static
            style.css
        /templates
            layout.html
            index.html
            login.html
            ...

But how do you run your application now? The naive python yourapplication/__init__.py will not work. Let’s just say that Python does not want modules in packages to be the startup file. But that is not a big problem, just add a new file called pyproject.toml next to the inner yourapplication folder with the following contents:

[project]
name = "yourapplication"
dependencies = [
    "flask",
]

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

Instala tu aplicación para que se pueda importar:

$ pip install -e .

Para usar el comando flask y ejecutar tu aplicación necesitas establecer la opción --app que le dice a Flask dónde encontrar la instancia de la aplicación:

$ flask --app yourapplication run

¿Qué ganamos con esto? Ahora podemos reestructurar un poco la aplicación en varios módulos. Lo único que tienes que recordar es la siguiente lista de comprobación rápida:

  1. la creación del objeto de aplicación Flask tiene que estar en el archivo __init__.py. De esta manera cada módulo puede importarlo con seguridad y la variable __name__ resolverá el paquete correcto.

  2. todas las funciones de vista (las que tienen un decorador route() encima) tienen que ser importadas en el archivo __init__.py. No el objeto en sí, sino el módulo en el que se encuentra. Importa el módulo de la vista después de crear el objeto de la aplicación.

Este es un ejemplo __init__.py:

from flask import Flask
app = Flask(__name__)

import yourapplication.views

Y así es como quedaría views.py:

from yourapplication import app

@app.route('/')
def index():
    return 'Hello World!'

Entonces deberías terminar con algo así:

/yourapplication
    pyproject.toml
    /yourapplication
        __init__.py
        views.py
        /static
            style.css
        /templates
            layout.html
            index.html
            login.html
            ...

Importaciones circulares

Todos los programadores de Python los odian, y sin embargo acabamos de añadir algunos: importaciones circulares (Es cuando dos módulos dependen el uno del otro. En este caso views.py depende de __init__.py). Ten en cuenta que esto es una mala idea en general, pero aquí está bien. La razón es que no estamos usando las vistas en __init__.py y sólo nos aseguramos de que el módulo es importado y lo hacemos al final del fichero.

Trabajar con Blueprints

Si tienes aplicaciones más grandes es recomendable dividirlas en grupos más pequeños donde cada grupo se implementa con la ayuda de un blueprint. Para una suave introducción a este tema, consulte el capítulo Aplicaciones modulares con Blueprints de la documentación.