Divida o aplicativo Python Flask em vários arquivos

88

Estou tendo problemas para entender como dividir um aplicativo Flask em vários arquivos.

Estou criando um serviço da web e quero dividir a API em arquivos diferentes (AccountAPI.py, UploadAPI.py, ...), apenas para não ter um arquivo python enorme.

Eu li que você pode fazer isso com o Blueprints, mas não tenho certeza se essa rota é a certa para mim.

Em última análise, quero executar um arquivo python principal e incluir outros arquivos para que, quando for executado, eles sejam considerados um arquivo grande.

Por exemplo, se eu tiver Main.py e AccountAPI.py, quero poder fazer isso:

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"

Eu sei que com este exemplo obviamente não funcionará, mas é possível fazer algo assim?

obrigado

user1751547
fonte

Respostas:

159

Sim, os projetos são a maneira certa de fazer isso. O que você está tentando fazer pode ser alcançado assim:

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"

Se esta for uma opção, você pode considerar o uso de diferentes prefixos de URL para as diferentes APIs / Blueprints a fim de separá-los de forma limpa. Isso pode ser feito com uma pequena modificação na register_blueprintchamada acima :

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

Para obter mais documentação, você também pode dar uma olhada nos documentos oficiais .

cyroxx
fonte
Isso funcionou perfeitamente para mim, obrigado! Eu acho que deveria ter lido os documentos do Blueprint com mais cuidado.
user1751547
Ei, eu tenho uma pergunta. No seguinte código acima, o url para accountList () corresponde a 'domínio / contas / conta'?
jeyraof de
4
Main.py e AccountAPI.py podem ter uma variável global compartilhada que está em qualquer um dos arquivos?
matchifang
Existe uma solução simples para colocar accountListdentro de uma classe no mesmo arquivo?
GA1
Funcionou perfeitamente, além de como adicionar um ponto de extremidade protegido usando JWT em arquivos .py separados
Ashok Sri
41

Usando Blueprintvocê pode adicionar suas rotas no routesdiretório.

Estrutura

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)

Se você quiser adicionar um novo arquivo de rota, digamos accounts.py, você só precisa criar o arquivo accounts.pyno routesdiretório, assim como index.pye users.py, em seguida, importá-lo no routes.__init__.pyarquivo

from .accounts import *
Searene
fonte
1
Está
gerando
Importar no meio do arquivo pode ser considerado uma má prática?
TomSawyer de
3

Se você estiver usando blueprints e quiser rotear / redirecionar para um url do seu blueprint dentro de um modelo que está usando, você precisa usar a instrução url_for correta.

No seu caso, se você gostaria de abrir a conta url do seu projeto, você deve declará-lo assim em seu modelo :

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

e para o aplicativo principal seria assim:

redirect(url_for('account_api.account'))

Caso contrário, a biblioteca werkzeug apresentará um erro.

Thomas Krickl
fonte
1

Uma outra maneira de fazer isso pode ser com o carregamento lento , em que você anexaria explicitamente as funções de visualização conforme a necessidade.

Bhaskar
fonte