Alisson Machado
28 October 2016

Flask - Blueprints

Essa é uma continuação do post Flask Básico, no primeiro post foi explicado a estrutura básica de um projeto em flask da forma mais simples possível, porém não é uma boa prática ter todo o seu projeto em um arquivo só, apesar de isso ser possível. Para trabalhar com projetos grandes torna-se necessário modularizar a aplicação separando as responsabilidades em arquivos diferentes, no Flask esse conceito é chamado de Blueprints. As Blueprints são aplicações em Flask que se acoplam em uma aplicação principal, como no caso da que foi feita no primeiro post que eu fiz sobre Flask, então vou reaproveitar o primeiro código.

#!/usr/bin/python
 
from flask import Flask
 
app = Flask(__name__)
 
@app.route("/")
def index():
    return "Essa e a pagina principal"
 
if __name__ == '__main__':
    app.run(debug=True)

Agora se eu quiser criar uma área de admin para essa aplicação, não faz sentido colocar o código dentro do run.py que é o código acima. Então vou criar um segundo arquivo chamado admin.py.

#!/usr/bin/python

from flask import Blueprint

admin = Blueprint('admin',__name__,url_prefix="/admin")

@admin.route("/")
def index():
    return "Essa e a pagina de admin"

@admin.route("/users")
def users():
    return "Essa e a pagina onde o admin gerencia os usuarios"

A estrutura é basicamente a mesma, na aplicação principal instanciamos um objeto chamado app do módulo Flask e na Blueprint instanciamos um objeto chamado admin do módulo Blueprint. Note que foram passados 3 argumentos ao instanciar a blueprint, sendo o primeiro um nome que você vai dar para a sua blueprint, o segundo é o __name__, esses dois primeiros são obrigatórios, o último que foi o url_prefix é opcional, esse último argumento serve para informar a aplicação que qualquer rota que tenha abaixo teve ter /admin como prefixo, dessa maneira você não precisa escrever admin na url todas as vezes que você for criar uma nova rota. Se não fosse passado o url_prefix o código ficaria da seguinte forma.

#!/usr/bin/python

from flask import Blueprint

admin = Blueprint('admin',__name__)

@admin.route("/admin")
def index():
    return "Essa e a pagina de admin"

@admin.route("/admin/users")
def users():
    return "Essa e a pagina onde o admin gerencia os usuarios"

Note que a palavra admin teve ser passada em todas as rotas, causando redundância no código, e se você quiser mudar esse prefixo da rota teria que mudar uma por uma, utilizando o url_prefix você não tem esse trabalho. Agora voltando para o run.py nele é necessário importar essa blueprint e registra-la na aplicação. Para fazer o import adicione a seguinte linha:

from admin import admin

Não esqueça de criar um arquivo chamado __init__.py no mesmo diretório, o arquivo é em branco mesmo, pois é esse arquivo que diz ao python que esse é um pacote do python, lembre-se que isso só necessário por estou usando a versão 2 do python, na versão 3 isso não é necessário. Voltando ao run.py, adicione a seguinte linha:

# essa linha ja estava no codigo
app = Flask(__name__)
# a linha abaixo que foi a nova adicionada
app.register_blueprint(admin)

Somente com isso a sua blueprint já vai estar funcionando. O código do run.py ficou da seguinte maneira:

#!/usr/bin/python

from flask import Flask
from admin import admin

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

@app.route("/")
def index():
    return "Essa e a pagina principal"

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


Agora basta executar a sua aplicação e acessar a url no navegador. No meu caso vou fazer um teste com curl e postar o resultado:

$ python run.py y
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger pin code: 308-004-411

Acima estou executando o run.py Agora testando as urls:

alisson@alisson-pc:~$ curl localhost:5000
Essa e a pagina principal

alisson@alisson-pc:~$  curl localhost:5000/admin/
Essa e a pagina de admin

alisson@alisson-pc:~$  curl localhost:5000/admin/users
Essa e a pagina onde o admin gerencia os usuarios

Fim (: