Diviser l'application Python Flask en plusieurs fichiers

88

J'ai du mal à comprendre comment diviser une application flask en plusieurs fichiers.

Je crée un service Web et je veux diviser les api en différents fichiers (AccountAPI.py, UploadAPI.py, ...), juste pour ne pas avoir un énorme fichier python.

J'ai lu que vous pouvez faire cela avec Blueprints, mais je ne suis pas tout à fait sûr que cette route soit la bonne pour moi.

En fin de compte, je veux exécuter un fichier python principal et inclure d'autres fichiers afin que, lorsqu'ils s'exécutent, ils soient considérés comme un gros fichier.

Par exemple, si j'ai Main.py et AccountAPI.py, je veux pouvoir le faire:

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"

Je sais qu'avec cet exemple cela ne fonctionnera évidemment pas, mais est-il possible de faire quelque chose comme ça?

Merci

user1751547
la source

Réponses:

159

Oui, les Blueprints sont la bonne façon de le faire. Ce que vous essayez de faire peut être réalisé comme ceci:

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 c'est une option, vous pouvez envisager d'utiliser différents préfixes d'URL pour les différentes API / Blueprints afin de les séparer proprement. Cela peut être fait avec une légère modification de l' register_blueprintappel ci - dessus :

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

Pour plus de documentation, vous pouvez également consulter la documentation officielle .

cyroxx
la source
Cela a parfaitement fonctionné pour moi merci! J'imagine que j'aurais dû lire les documents Blueprint plus attentivement.
user1751547
Hé, j'ai une question. Dans le code ci-dessus, l'URL de accountList () correspond-elle à "domaine / comptes / compte"?
jeyraof
4
Main.py et AccountAPI.py peuvent-ils avoir une variable globale partagée qui se trouve dans l'un ou l'autre des fichiers?
matchifang
Existe-t-il une solution simple pour insérer accountListune classe dans le même fichier?
GA1
A fonctionné comme un charme, comment ajouter un point de terminaison protégé en utilisant JWT dans des fichiers .py séparés
Ashok Sri
41

En utilisant, Blueprintvous pouvez ajouter vos itinéraires dans le routesrépertoire.

Structure

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 vous souhaitez ajouter un nouveau fichier d'itinéraire, par exemple accounts.py, il vous suffit de créer le fichier accounts.pydans le routesrépertoire, tout comme index.pyet users.py, puis de l'importer dans le routes.__init__.pyfichier

from .accounts import *
Searene
la source
1
Il lance une erreur d'importation
Abhishek Jebaraj
L'importation au milieu du fichier peut être considérée comme une mauvaise pratique?
TomSawyer
3

Si vous utilisez des blueprints et que vous souhaitez router / rediriger vers une URL de votre blueprint dans un template que vous utilisez, vous devez utiliser la bonne instruction url_for.

Dans votre cas, si vous souhaitez ouvrir le compte url de votre plan, vous devez l'indiquer comme ceci dans votre modèle :

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

et pour l' application principale, cela ressemblerait à ceci:

redirect(url_for('account_api.account'))

Sinon, la bibliothèque werkzeug générera une erreur.

Thomas Krickl
la source
1

Une autre façon de faire cela peut être le chargement différé , où vous attacheriez explicitement des fonctions de vue en fonction des besoins.

Bhaskar
la source