Ao desenvolver aplicações web com Python e o framework Flask, uma prática comum em projetos de maior porte é o uso de Blueprints (Blueprints). Um Blueprint permite modularizar uma aplicação, dividindo-a em componentes que implementam funcionalidades distintas. Embora um Blueprint possa invocar funções de visão (view functions) de outro, é necessário referenciar o nome do Blueprint correspondente.
Vantagens dos Blueprints: Promovem um design mais desacoplado e flexível, aumentam a reutilização de código, e podem melhorar a eficiência na depuração, reduzindo a probabilidade de erros.
Desvantagens dos Blueprints: Uma vez que a aplicação é criada, não é possível desregistrar (unregister) um Blueprint individualmente sem recriar o objeto da aplicação inteira.
É possível registrar um Blueprint múltiplas vezes, mas o suceso dessa prática depende de como o Blueprint foi implementado, especificamente se ele consegue responder adequadamente em diferentes contextos de URL.
Uso Oficial e Casos de Uso
- Decompor uma aplicação em um conjunto de Blueprints é uma abordagem ideal para projetos grandes. Uma única aplicação pode instanciar múltiplas extensões e registrar diversos Blueprints.
- Registrar um Blueprint sob um prefixo de URL ou subdomínio específico. Os parâmetros do prefixo/subdomínio se tornam, por padrão, parâmetros comuns para todas as funções de visão dentro daquele Blueprint.
- Permitir que o mesmo Blueprint seja registrado na aplicação com diferentes regras de URL.
- Fornecer, através do Blueprint, filtros de template, arquivos estáticos, templates e outras utilidades. Um Blueprint não precisa, necessariamente, definir rotas ou funções de visão.
- Durante a inicialização de uma extensão Flask, registrar um Blueprint para quaisquer dos propósitos acima.
Conceito Fundamental
A ideia central de um Blueprint é que ele representa um conjunto de operações que serão executadas após ser registrado em uma aplicação. Ao lidar com uma requisição, o Flask associa o Blueprint à função de visão correspondente e gera a URL entre dois endpoints.
Parâmetros do Blueprint
Primeiro Parâmetro (nome): Ao usar o decorador @simple_page.route, o Blueprint registra a função show. Quando o Blueprint é registrado na aplicação, esta função é adicionada à aplicação. Além disso, o nome fornecido ao Blueprint (por exemplo, simple_page) é usado como prefixo para o endpoint da função.
Segundo Parâmetro (import_name): Especifica o módulo Python lógico associado ao Blueprint, geralmente __name__. Este argumento ajuda a localizar a pasta de recursos do Blueprint. Se apontar para um pacote Python (uma pasta), essa é a pasta de recursos. A propriedade Blueprint.root_path mostra o caminho para essa pasta.
>>> print(simple_page.root_path)
'/caminho/para/seu/projeto/seu_aplicativo'
O método open_resource() pode ser usado para acessar recursos dentro dessa pasta:
with simple_page.open_resource('static/style.css') as arquivo:
conteudo = arquivo.read()
Terceiro Parâmetro (static_folder): Define a pasta que contém os arquivos estáticos do Blueprint. Pode ser um caminho absoluto ou relativo.
admin_bp = Blueprint('admin_bp', __name__, static_folder='static_assets')
Por padrão, o último segmento do caminho da pasta (ex: static_assets) é exposto na URL. Isso pode ser alterado com static_url_path. Se o Blueprint é registrado com um prefixo /admin, a URL para seus arquivos estáticos se torna /admin/static_assets.
url_for('admin_bp.static', filename='style.css')
Se o Blueprint não tiver um url_prefix, seus arquivos estáticos podem não ser acessíveis, pois a rota /static da aplicação principal terá prioridade. Ao contrário das pastas de template, se um arquivo estático não existir na pasta da aplicação principal, a pasta do Blueprint não será consultada.
Conceitos Relacionados
Funções de Visão (View Functions): Recebem requisições, processam a lógica de negócio e retornam uma resposta. Não é permitido ter funções de visão com o mesmo nome, embora caminhos de URL possam ser repetidos (podendo usar métodos HTTP diferentes).
Templates: Recebem os dados retornados pela visão e os renderizam em uma resposta formatada (ex: HTML).
Padrão MVT (Model-View-Template): Um padrão de design que visa desacoplar componentes. A lógica de negócio (Model), a apresentação/lógica de requisição (View) e a formatação (Template) são separadas em módulos especializados.
Sistema de Rotas Interno: As regras de mapeamento URL-view são armazenadas em uma lista e verificadas sequencialmente. A classe Rule armazena o mapeamento individual entre uma função de visão e uma URL. A classe Map contém todas as instâncias de Rule. A classe MapAdapter é responsável por encontrar a correspondência (via regex) de uma URL com uma Rule e invocar a função associada.