Podziel aplikację Python Flask na wiele plików

88

Mam problem ze zrozumieniem, jak podzielić aplikację Flask na wiele plików.

Tworzę usługę internetową i chcę podzielić interfejsy API na różne pliki (AccountAPI.py, UploadAPI.py, ...), aby nie mieć jednego ogromnego pliku Pythona.

Czytałem, że możesz to zrobić dzięki Blueprints, ale nie jestem do końca pewien, czy trasa jest dla mnie odpowiednia.

Ostatecznie chcę uruchomić jeden główny plik Pythona i dołączyć inne pliki, aby po uruchomieniu były traktowane jako jeden duży plik.

Na przykład, jeśli mam Main.py i AccountAPI.py, chcę móc to zrobić:

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"

Wiem, że na tym przykładzie to oczywiście nie zadziała, ale czy można coś takiego zrobić?

Dzięki

user1751547
źródło

Odpowiedzi:

159

Tak, schematy to właściwy sposób na zrobienie tego. To, co próbujesz zrobić, można osiągnąć w następujący sposób:

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"

Jeśli jest to opcja, możesz rozważyć użycie różnych prefiksów adresów URL dla różnych interfejsów API / schematów, aby wyraźnie je oddzielić. Można to zrobić z niewielką modyfikacją powyższego register_blueprintwywołania:

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

W celu uzyskania dalszej dokumentacji możesz również zajrzeć do oficjalnych dokumentów .

cyroxx
źródło
To zadziałało idealnie dla mnie, dzięki! Myślę, że powinienem był uważniej przeczytać dokumentację Blueprint.
user1751547
Hej, mam pytanie. Czy w poniższym kodzie adres URL dla accountList () jest dopasowany do „domeny / kont / konta”?
jeyraof
4
Czy Main.py i AccountAPI.py mogą mieć wspólną zmienną globalną, która znajduje się w którymkolwiek z plików?
matchifang
Czy istnieje proste rozwiązanie umożliwiające umieszczenie accountListwewnątrz klasy w tym samym pliku?
GA1
Działało jak urok, a ponadto jak dodać chroniony punkt końcowy za pomocą JWT w osobnych plikach .py
Ashok Sri,
41

Używając Blueprintmożesz dodać swoje trasy w routeskatalogu.

Struktura

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)

Jeśli chcesz dodać nowy plik trasy, powiedzmy accounts.py, że wystarczy utworzyć plik accounts.pyw routeskatalogu, tak jak index.pyi users.py, a następnie zaimportować go do routes.__init__.pypliku

from .accounts import *
Searene
źródło
1
Wyrzuca
Importowanie w środku pliku można uznać za złą praktykę?
TomSawyer
3

Jeśli używasz schematów i chcesz skierować / przekierować do adresu URL swojego planu w szablonie, którego używasz, musisz użyć poprawnej instrukcji url_for.

W twoim przypadku, jeśli chcesz otworzyć konto url swojego planu, musisz podać to w swoim szablonie w następujący sposób :

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

a dla głównej aplikacji wyglądałoby to tak:

redirect(url_for('account_api.account'))

W przeciwnym razie biblioteka werkzeug zgłosi błąd.

Thomas Krickl
źródło
1

Innym sposobem na to może być leniwe ładowanie , w którym jawnie dołączasz funkcje widoku na podstawie potrzeb.

Bhaskar
źródło