¿Cómo dividir la aplicación de matraz en múltiples archivos py?

146

Mi aplicación de matraz actualmente consta de un único test.pyarchivo con múltiples rutas y la main()ruta definida. ¿Hay alguna forma de que pueda crear un test2.pyarchivo que contenga rutas que no se manejaron test.py?

@app.route('/somepath')
def somehandler():
    # Handler code here

Me preocupa que haya demasiadas rutas test.pyy me gustaría hacerlo de modo que pueda correr python test.py, lo que también recogerá las rutas test.pycomo si fueran parte del mismo archivo. ¿Qué cambios tengo que hacer test.pyy / o incluir test2.pypara que esto funcione?

Rolando
fuente

Respuestas:

153

Puede usar la estructura habitual de paquetes de Python para dividir su aplicación en varios módulos, consulte los documentos de Flask.

Sin embargo,

Flask utiliza un concepto de planos para crear componentes de aplicaciones y admitir patrones comunes dentro de una aplicación o entre aplicaciones.

Puede crear un subcomponente de su aplicación como Blueprint en un archivo separado:

simple_page = Blueprint('simple_page', __name__, template_folder='templates')
@simple_page.route('/<page>')
def show(page):
    # stuff

Y luego úsalo en la parte principal:

from yourapplication.simple_page import simple_page

app = Flask(__name__)
app.register_blueprint(simple_page)

Los planos también pueden agrupar recursos específicos: plantillas o archivos estáticos. Consulte los documentos de Flask para obtener todos los detalles.

pixelistik
fuente
1
¿Cómo podemos tener las rutas del plano en el archivo que no sea el inicio de ese plano?
divyenduz
si quiero hacer un punto final seguro usando JWT, ¿cómo lo haré en cada archivo route.py
Ashok Sri
19

Puede usar un truco simple que es importar la variable de aplicación de matraz de main dentro de otro archivo, como:

test-routes.py

from __main__ import app

@app.route('/test', methods=['GET'])
def test():
    return 'it works!'

y en sus archivos principales, donde declaró la aplicación de matraz, importe rutas de prueba, como:

app.py

from flask import Flask, request, abort

app = Flask(__name__)

# import declared routes
import test-routes

Funciona desde mi lado.

nimeresam
fuente
2
Es solo un ejemplo, se __main__refiere a su archivo de entrada, ¡eso es!
nimeresam
3
Brillante, muchas gracias. Blueprint o el enfoque de paquete anterior son excesivos para aplicaciones pequeñas.
VH-NZZ
Aquí hay un enlace a los documentos donde se explica este método: https://flask.palletsprojects.com/en/1.1.x/patterns/packages/
Christopher
1
@nimeresam Funcionó para mí, pero tuve que aprender que import test-routesno puede estar en la parte superior del app.pyarchivo. Se estrelló gunicorn pero luego de mover la importación al final del archivo, funcionó. "solo nos aseguramos de que el módulo se importe y lo estamos haciendo al final del archivo"
Niklas R.
5

Dividir la aplicación en planos es una gran idea. Sin embargo, si esto no es suficiente, y si desea dividir el Blueprint en sí en múltiples archivos py, esto también es posible utilizando el sistema de importación del módulo Python normal y luego recorrer todas las rutas que se importan de los otros archivos .

Creé un Gist con el código para hacer esto:

https://gist.github.com/Jaza/61f879f577bc9d06029e

Hasta donde sé, esta es la única forma factible de dividir un Blueprint en este momento. No es posible crear "sub-planos" en Flask, aunque hay un problema abierto con mucha discusión sobre esto:

https://github.com/mitsuhiko/flask/issues/593

Además, incluso si fuera posible (y probablemente sea posible usar algunos de los fragmentos de ese hilo de problemas), los planos secundarios pueden ser demasiado restrictivos para su caso de uso de todos modos, por ejemplo, si no desea todas las rutas en un submódulo para tener el mismo sub-prefijo de URL.

Jaza
fuente
4

Esta tarea puede llevarse a cabo sin planos e importaciones difíciles utilizando el Mapa de URL centralizado

app.py

import views
from flask import Flask

app = Flask(__name__)

app.add_url_rule('/', view_func=views.index)
app.add_url_rule('/other', view_func=views.other)

if __name__ == '__main__':
    app.run(debug=True, use_reloader=True)

views.py

from flask import render_template

def index():
    return render_template('index.html')

def other():
    return render_template('other.html')
Bleiz
fuente