Divida la aplicación Python Flask en varios archivos

88

Tengo problemas para entender cómo dividir una aplicación de matraz en varios archivos.

Estoy creando un servicio web y quiero dividir las API en diferentes archivos (AccountAPI.py, UploadAPI.py, ...), para no tener un archivo python enorme.

Leí que puedes hacer esto con Blueprints, pero no estoy del todo seguro de que la ruta sea la adecuada para mí.

En última instancia, quiero ejecutar un archivo Python principal e incluir otros archivos para que cuando se ejecute, se consideren un archivo grande.

Por ejemplo, si tengo Main.py y AccountAPI.py, quiero poder hacer esto:

Main.py:

from flask import Flask
import AccountAPI

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

AccountAPI.py:

@app.route("/account")
def accountList():
    return "list of accounts"

Sé que con este ejemplo obviamente no funcionará, pero ¿es posible hacer algo así?

Gracias

usuario1751547
fuente

Respuestas:

159

Sí, los Blueprints son la forma correcta de hacerlo. Lo que está tratando de hacer se puede lograr así:

Main.py

from flask import Flask
from AccountAPI import account_api

app = Flask(__name__)

app.register_blueprint(account_api)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

AccountAPI.py

from flask import Blueprint

account_api = Blueprint('account_api', __name__)

@account_api.route("/account")
def accountList():
    return "list of accounts"

Si esta es una opción, puede considerar el uso de diferentes prefijos de URL para las diferentes API / Blueprints para poder separarlos limpiamente. Esto se puede hacer con una ligera modificación a la register_blueprintllamada anterior :

app.register_blueprint(account_api, url_prefix='/accounts')

Para obtener más documentación, también puede consultar los documentos oficiales .

cyroxx
fuente
Esto funcionó perfectamente para mí, ¡gracias! Supongo que debería haber leído los documentos de Blueprint con más atención.
user1751547
Oye, tengo una pregunta. En el siguiente código anterior, ¿la URL de accountList () coincide con 'dominio / cuentas / cuenta'?
jeyraof
4
¿Pueden Main.py y AccountAPI.py tener una variable global compartida que esté en cualquiera de los archivos?
matchifang
¿Existe una solución simple para poner accountListuna clase dentro del mismo archivo?
GA1
Funcionó como un encanto, además de cómo agregar un punto final protegido mediante el uso de JWT en archivos .py separados
Ashok Sri
41

Usando Blueprintpuede agregar sus rutas en el routesdirectorio.

Estructura

app.py
routes
    __init__.py
    index.py
    users.py

__init__.py

from flask import Blueprint
routes = Blueprint('routes', __name__)

from .index import *
from .users import *

index.py

from flask import render_template
from . import routes

@routes.route('/')
def index():
    return render_template('index.html')

users.py

from flask import render_template
from . import routes

@routes.route('/users')
def users():
    return render_template('users.html')

app.py

from routes import *
app.register_blueprint(routes)

Si desea agregar un nuevo archivo de ruta, digamos accounts.py, solo necesita crear el archivo accounts.pyen el routesdirectorio, como index.pyy users.py, luego importarlo en el routes.__init__.pyarchivo

from .accounts import *
Searene
fuente
1
Está arrojando un error de importación
Abhishek Jebaraj
¿Importar en medio del archivo puede considerarse una mala práctica?
TomSawyer
3

Si está utilizando blueprints y desea enrutar / redirigir a una URL de su blueprint dentro de una plantilla que está utilizando, debe usar la declaración url_for correcta.

En su caso, si desea abrir la cuenta de url de su plano, debe indicarlo así en su plantilla :

href="{{ url_for('account_api.account') }}"

y para la aplicación principal se vería así:

redirect(url_for('account_api.account'))

De lo contrario, la biblioteca werkzeug arrojará un error.

Thomas Krickl
fuente
1

Otra forma de hacer esto puede ser con la carga diferida , donde adjuntaría explícitamente funciones de vista según sea necesario.

Bhaskar
fuente