Introdução ao Flask: Um Guia Abrangente

Flask: Uma Visão Geral

Lançado em 2010, o Flask é um microframework web para Python, criado por Armin Ronacher. Ele se destaca pela sua leveza e flexibilidade, servindo como um núcleo que pode ser estendido com bibliotecas de terceiros para funcionalidades adicionais, como gerenciamento de e-mail (Flask-Mail), autenticação de usuários (Flask-Login) e integração com bancos de dados (Flask-SQLAlchemy). O Flask não impõe um ORM ou um banco de dados específico, permitindo a escolha entre SQL e NoSQL.

Componentes Essenciais: Werkzeug e Jinja2

O funcionamento do Flask é sustentado por duas bibliotecas principais:

  • Werkzeug: Um toolkit WSGI (Web Server Gateway Interface) que lida com as tarefas de baixo nível do framework, incluindo roteamento de requisições, manipulação de objetos de requisição e resposta, depuração e o próprio servidor web. O módulo de roteamento (routing) do Werkzeug é responsável por mapear URLs a funções de visualização (view functions) correspondentes. Ele utiliza classes como Rule para definir padrões de URL e Map para armazenar essas regras.
  • Jinja2: Um motor de templates moderno e poderoso que permite a criação de HTML dinâmico. Ele suporta sintaxes para variáveis ({{ variavel }}), estruturas de controle ({% if condicao %} ... {% else %} ... {% endif %}) e loops ({% for item in lista %} ... {% endfor %}).

Extensões Populares do Flask

A comunidade Flask desenvolveu diversas extensões para facilitar tarefas comuns:

  • Flask-SQLAlchemy: Para interagir com bancos de dados via ORM.
  • Flask-Script: Para gerenciar tarefas e scripts da aplicação.
  • Flask-Migrate: Para gerenciar migrações de banco de dados.
  • Flask-Session: Para configurar o armazenamento de sessões.
  • Flask-WTF: Para manipulação de formulários web.
  • Flask-Mail: Para envio de e-mails.
  • Flask-Babel: Suporte para internacionalização e localização.
  • Flask-Login: Para autenticação e gerenciamento de estado do usuário.
  • Flask-RESTful: Para desenvolver APIs RESTful.
  • Flask-Bootstrap: Integração com o framework frontend Twitter Bootstrap.
  • Flask-Moment: Formatação e localização de datas e horas.
  • Flask-Admin: Criação de interfaces administrativas.

Configuração do Ambiente Flask

Para iniciar, instale o Flask utilizando o pip:

pip install Flask -i https://pypi.tuna.tsinghua.edu.cn/simple

Exemplo Simples de Flask

Um aplictaivo Flask mínimo envolve a criação de uma instância do aplicativo e a definição de rotas:

from flask import Flask

# Instanciação do objeto Flask
app = Flask(__name__)

# Definição de uma rota e sua função de visualização associada
@app.route("/")
def hello_world():
   return "<h1>Olá, Flask!</h1>"

if __name__ == '__main__':
   # Execução do servidor de desenvolvimento
   # O parâmetro 'debug=True' ativa o modo de depuração, que reinicia o servidor automaticamente após alterações no código.
   app.run(debug=True)

Ao executar este script, o Flask iniciará um servidor de desenvolvimento, geralmente acessível em http://127.0.0.1:5000/. Parâmetros como host e port podem ser especificados em app.run() para customizar o endereço e a porta de escuta. O argumento __name__ ajuda o Flask a determinar o caminho raiz do aplicativo para carregar recursos como templates e arquivos estáticos.

Roteamento no Flask

O roteamento é o mecanismo que mapeia URLs para funções específicas em seu aplicativo. Você pode inspecionar as rotas registradas de uma aplicação Flask:

# Supondo que 'app' seja sua instância Flask
   print(app.url_map)
   # Saída esperada:
   # Map([<Rule '/' (HEAD, GET, OPTIONS) -> hello_world>, <Rule '/static/<filename>' (HEAD, GET, OPTIONS) -> static>])
   

A decoração @app.route() é usada para associar uma URL a uma função. Ela aceita argumentos opcionais, como methods, para especificar os métodos HTTP permitidos. A função url_for() é útil para gerar URLs dinamicamente com base nos nomes das funções de visualização.

from flask import url_for

   # Em algum lugar do seu código, após definir a rota 'hello_world':
   # url_para_home = url_for('hello_world') # Gera '/'; se a rota for '/home', geraria '/home'
   

Funções de Visualização

As funções de visualização (view functions) são o coração da lógica de cada rota. Elas recebem a requisição HTTP, processam os dados necessários e retornam uma resposta. Essa resposta pode ser uma string HTML simples, uma renderização de template, um redirecionamento ou uma resposta JSON.

from flask import Flask, render_template

   app = Flask(__name__)

   @app.route("/")
   def index():
       # Renderiza um template HTML chamado 'home.html'
       return render_template('home.html')

   @app.route("/usuarios/<nome_usuario>")
   def perfil_usuario(nome_usuario):
       # Processa um parâmetro da URL
       return f"Perfil do usuário: {nome_usuario}"

   if __name__ == '__main__':
       app.run(debug=True)
   </nome_usuario>

Templates com Jinja2

O Flask utiliza o Jinja2 por padrão para renderizar templates HTML dinamicamente. A função render_template() carrega e processa esses arquivos.

Sintaxe Jinja2

  • Variáveis: Exibidas usando chaves duplas: {{ nome_variavel }}.
  • Estruturas de Controle: Usam chaves e porcentagem: {% if condicao %} ... {% else %} ... {% endif %}.
  • Loops: Para iterar sobre listas ou sequências: {% for item in lista %} ... {% endfor %}.
  • Comentários: {# Isto é um comentário em Jinja2 #}.
  • Filtros: Modificam a saída de variáveis (ex: {{ nome | upper }} para converter para maiúsculas, {{ texto | safe }} para renderizar HTML sem escapar).
  • Macros: Permitem a criação de funções reutilizáveis dentro dos templates, similares a funções em Python.
  • Herança de Templates: Permite que templates estendam outros, definindo blocos substituíveis ({% block nome_bloco %}...{% endblock %}).
  • Inclusão de Templates: {% include 'outro_template.html' %} insere o conteúdo de outro template.

Exemplo Prático de Template

Arquivo templates/exemplo.html:


   <html lang="pt-br">
   <head>
       <meta charset="UTF-8">
       <title>Exemplo de Template</title>
   </head>
   <body>
       {# Exemplo de controle de fluxo #}
       {% if contador > 5 %}
           <p>O contador é maior que 5: {{ contador }}</p>
       {% else %}
           <p>O contador é 5 ou menor: {{ contador }}</p>
       {% endif %}

       {# Exemplo de loop #}
       {% for i in range(3) %}
           <p>Iteração número {{ i + 1 }}</p>
       {% endfor %}

       {# Exemplo de macro #}
       {% macro campo_input(nome, valor='', tipo='text') %}
           <input type="{{ tipo }}" name="{{ nome }}" value="{{ valor }}">
       {% endmacro %}
       {{ campo_input('usuario', 'Exemplo') }}
   </body>
   </html>

Arquivo app.py:

from flask import Flask, render_template

   app = Flask(__name__)

   @app.route("/mostrar/<valor>")
   def mostrar_exemplo(valor):
       nome_dinamico = "Dados dinâmicos"
       # Passa variáveis para o template
       return render_template('exemplo.html', contador=valor, nome=nome_dinamico)

   if __name__ == '__main__':
       app.run(debug=True)
   </valor>

Gerenciamento de Banco de Dados

O Flask pode ser intgerado com bancos de dados através de bibliotecas como SQLAlchemy.

SQLAlchemy: O ORM

O SQLAlchemy é um mapeador objeto-relacional (ORM) popular para Python.

pip install SQLAlchemy pymysql # Ou outro driver de banco de dados
   

Tipos e Restrições de Coluna: O SQLAlchemy oferece diversos tipos de dados (Integer, String, Text, DateTime, etc.) e restrições (primary_key, unique, nullable, default, etc.).

Relacionamentos: Suporta relacionamentos um-para-um, um-para-muitos e muitos-para-muitos usando relationship() e ForeignKey().

Operações CRUD com SQLAlchemy

As operações de criação, leitura, atualização e exclusão (CRUD) são realizadas através de uma sessão do SQLAlchemy:

from sqlalchemy import create_engine, Column, Integer, String
   from sqlalchemy.orm import sessionmaker, declarative_base

   # Configuração da conexão com o banco de dados
   engine = create_engine('mysql+pymysql://usuario:senha@host/database')
   Base = declarative_base()

   # Definição de um modelo de tabela
   class Usuario(Base):
       __tablename__ = 'usuarios'
       id = Column(Integer, primary_key=True)
       nome = Column(String(50), nullable=False)

   # Criação das tabelas no banco de dados (se não existirem)
   Base.metadata.create_all(engine)

   # Criação de uma sessão
   SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
   session = SessionLocal()

   # --- CRUD ---
   # Criação (Create)
   novo_usuario = Usuario(nome="Alice")
   session.add(novo_usuario)
   session.commit()

   # Leitura (Read)
   usuarios = session.query(Usuario).all()
   for u in usuarios:
       print(u.nome)

   # Atualização (Update)
   usuario_para_atualizar = session.query(Usuario).filter_by(nome="Alice").first()
   if usuario_para_atualizar:
       usuario_para_atualizar.nome = "Alice Smith"
       session.commit()

   # Exclusão (Delete)
   usuario_para_excluir = session.query(Usuario).filter_by(nome="Alice Smith").first()
   if usuario_para_excluir:
       session.delete(usuario_para_excluir)
       session.commit()

   session.close()
   

Flask-SQLAlchemy: Integração Simplificada

A extensão Flask-SQLAlchemy simplifica a integração do SQLAlchemy com o Flask.

pip install Flask-SQLAlchemy
   
from flask import Flask
   from flask_sqlalchemy import SQLAlchemy

   app = Flask(__name__)
   # Configuração da URI do banco de dados
   app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://usuario:senha@host/database'
   app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Desativa o rastreamento de modificações
   db = SQLAlchemy(app)

   class Produto(db.Model):
       id = db.Column(db.Integer, primary_key=True)
       nome = db.Column(db.String(100), nullable=False)

   # Criação das tabelas
   with app.app_context():
       db.create_all()

   # Operações CRUD com db.session
   novo_produto = Produto(nome="Teclado Gamer")
   db.session.add(novo_produto)
   db.session.commit()

   produtos = Produto.query.all() # Forma mais direta de consultar
   for p in produtos:
       print(p.nome)

   # Acesso à sessão é simplificado com db.session
   # db.session.query(...)
   # db.session.add(...)
   # db.session.commit()
   # db.session.delete(...)
   

Migração de Banco de Dados com Flask-Migrate

O Flask-Migrate (que usa Alembic por baixo dos panos) gerencia as alterações no esquema do banco de dados ao longo do tempo.

pip install Flask-Migrate Flask-Script
   
# No seu arquivo principal (ex: app.py)
   from flask import Flask
   from flask_sqlalchemy import SQLAlchemy
   from flask_migrate import Migrate
   from flask_script import Manager

   app = Flask(__name__)
   app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///meubanco.db' # Exemplo com SQLite
   db = SQLAlchemy(app)

   # Modelo de exemplo
   class Usuario(db.Model):
       id = db.Column(db.Integer, primary_key=True)
       nome = db.Column(db.String(50))

   migrate = Migrate(app, db)
   manager = Manager(app)

   # Adiciona o comando 'db' para gerenciar migrações
   manager.add_command('db', MigrateCommand)

   if __name__ == '__main__':
       manager.run()
   

Comandos no terminal:

  • python seu_script.py db init: Inicializa o diretório de migrações.
  • python seu_script.py db migrate -m "Descrição da migração": Cria um novo script de migração baseado nas mudanças nos modelos.
  • python seu_script.py db upgrade: Aplica as migrações ao banco de dados.
  • python seu_script.py db downgrade: Reverte a última migração.

Tags: Flask Python Web Development Microframework Werkzeug

Publicado em 6-22 20:05