Voltar ao Glossario
Glossario Python

Flask: O que É e Como Funciona | Python Brasil

Guia completo do Flask: microframework web Python com Blueprints, extensões e application factory. Exemplos práticos e comparação com Django.

O que é Flask?

O Flask é um microframework web para Python, criado por Armin Ronacher e lançado em 2010. Diferente do Django, o Flask segue uma filosofia minimalista: ele fornece apenas o essencial para criar aplicações web, deixando que você escolha as ferramentas e bibliotecas adicionais conforme a necessidade do seu projeto.

O Flask é construído sobre duas bibliotecas principais: Werkzeug (para WSGI e roteamento) e Jinja2 (para templates HTML). Juntas, elas formam uma base sólida e extensível.

A História do April Fools que Virou Framework

O Flask nasceu de uma brincadeira. Em 1° de abril de 2010, Armin Ronacher publicou o “Denied”, uma biblioteca de uma única linha que pretendia ser um microframework. A piada caiu tão bem na comunidade Python que ele decidiu criar algo real com aquela ideia. O Flask foi o resultado — um framework que provasse que “micro” não significa “menos capaz”.

Hoje, o Flask é um dos frameworks Python mais populares do mundo, com dezenas de milhões de downloads mensais no PyPI.

Werkzeug e Jinja2

Werkzeug é o kit de ferramentas WSGI que alimenta o Flask. Ele cuida de:

  • Roteamento de URLs
  • Manipulação de requisições e respostas HTTP
  • Utilitários de debugging (reloader automático, debugger interativo)
  • Gerenciamento de cookies e sessões

Jinja2 é o motor de templates do Flask. Ele permite gerar HTML dinâmico com uma sintaxe limpa:

<!-- templates/lista.html -->
<!DOCTYPE html>
<html>
<head><title>Usuários</title></head>
<body>
  <h1>Lista de Usuários</h1>
  <ul>
    {% for usuario in usuarios %}
      <li>{{ usuario.nome }} — {{ usuario.email }}</li>
    {% else %}
      <li>Nenhum usuário encontrado.</li>
    {% endfor %}
  </ul>
</body>
</html>

Exemplo Básico

from flask import Flask, jsonify, request, abort

app = Flask(__name__)

# Rota simples
@app.route("/")
def index():
    return "<h1>Olá, Flask!</h1>"

# API com JSON
@app.route("/api/usuarios", methods=["GET"])
def listar_usuarios():
    usuarios = [
        {"id": 1, "nome": "Maria", "email": "maria@email.com"},
        {"id": 2, "nome": "João", "email": "joao@email.com"},
    ]
    return jsonify(usuarios)

# Recebendo dados via POST
@app.route("/api/usuarios", methods=["POST"])
def criar_usuario():
    dados = request.get_json()
    if not dados or "nome" not in dados:
        abort(400)
    return jsonify({"mensagem": f"Usuário {dados['nome']} criado!"}), 201

# Rota com parâmetro dinâmico
@app.route("/api/usuarios/<int:usuario_id>", methods=["GET"])
def buscar_usuario(usuario_id):
    # Simulação de busca
    return jsonify({"id": usuario_id, "nome": "Maria"})

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

Application Factory Pattern

Para projetos maiores, o padrão Application Factory (fábrica de aplicação) é fundamental. Ele permite criar múltiplas instâncias do app — essencial para testes e para carregar configurações diferentes por ambiente.

# app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

def create_app(config="config.DevelopmentConfig"):
    app = Flask(__name__)
    app.config.from_object(config)

    # Inicializa extensões
    db.init_app(app)

    # Registra Blueprints
    from .usuarios import usuarios_bp
    from .produtos import produtos_bp
    app.register_blueprint(usuarios_bp, url_prefix="/api/usuarios")
    app.register_blueprint(produtos_bp, url_prefix="/api/produtos")

    return app
# config.py
import os

class Config:
    SECRET_KEY = os.environ.get("SECRET_KEY", "dev-secret-key")
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class DevelopmentConfig(Config):
    DEBUG = True
    SQLALCHEMY_DATABASE_URI = "sqlite:///dev.db"

class ProductionConfig(Config):
    DEBUG = False
    SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URL")

Blueprints

Blueprints são a forma do Flask organizar grandes aplicações em módulos. Cada Blueprint agrupa rotas, templates e estáticos relacionados.

# app/usuarios/routes.py
from flask import Blueprint, jsonify, request
from app import db
from .models import Usuario

usuarios_bp = Blueprint("usuarios", __name__)

@usuarios_bp.route("/", methods=["GET"])
def listar():
    usuarios = Usuario.query.all()
    return jsonify([u.to_dict() for u in usuarios])

@usuarios_bp.route("/<int:id>", methods=["DELETE"])
def deletar(id):
    usuario = Usuario.query.get_or_404(id)
    db.session.delete(usuario)
    db.session.commit()
    return jsonify({"mensagem": "Usuário removido"}), 200

Flask-SQLAlchemy

A extensão Flask-SQLAlchemy integra o SQLAlchemy ao Flask, oferecendo ORM completo:

from app import db
from datetime import datetime

class Usuario(db.Model):
    __tablename__ = "usuarios"

    id = db.Column(db.Integer, primary_key=True)
    nome = db.Column(db.String(100), nullable=False)
    email = db.Column(db.String(150), unique=True, nullable=False)
    criado_em = db.Column(db.DateTime, default=datetime.utcnow)
    ativo = db.Column(db.Boolean, default=True)

    def to_dict(self):
        return {
            "id": self.id,
            "nome": self.nome,
            "email": self.email,
            "ativo": self.ativo,
        }

# Criar, buscar, atualizar
novo = Usuario(nome="Ana", email="ana@email.com")
db.session.add(novo)
db.session.commit()

usuario = Usuario.query.filter_by(email="ana@email.com").first()
usuario.nome = "Ana Silva"
db.session.commit()

Ecossistema de Extensões

Uma das maiores forças do Flask é seu ecossistema de extensões. As mais utilizadas são:

  • Flask-SQLAlchemy: ORM com SQLAlchemy
  • Flask-Login: autenticação e sessões de usuário
  • Flask-WTF: formulários com proteção CSRF
  • Flask-Migrate: migrações de banco de dados com Alembic
  • Flask-Mail: envio de e-mails
  • Flask-Caching: cache com Redis ou Memcached
  • Flask-CORS: suporte a CORS para APIs
  • Flask-JWT-Extended: autenticação com JWT

Testando Aplicações Flask

# tests/test_usuarios.py
import pytest
from app import create_app, db

@pytest.fixture
def client():
    app = create_app("config.TestingConfig")
    with app.test_client() as client:
        with app.app_context():
            db.create_all()
        yield client
        with app.app_context():
            db.drop_all()

def test_listar_usuarios(client):
    resposta = client.get("/api/usuarios/")
    assert resposta.status_code == 200
    assert isinstance(resposta.get_json(), list)

def test_criar_usuario(client):
    resposta = client.post(
        "/api/usuarios/",
        json={"nome": "Carlos", "email": "carlos@email.com"}
    )
    assert resposta.status_code == 201
    assert resposta.get_json()["nome"] == "Carlos"

Flask vs Django: Comparação Detalhada

AspectoFlaskDjango
FilosofiaMinimalista, você decideBatteries included
ORMOpcional (Flask-SQLAlchemy)Nativo e integrado
AdminExtensão (Flask-Admin)Nativo e automático
AutenticaçãoFlask-LoginNativo
TemplatesJinja2Django Template Language
Ideal paraAPIs, microsserviços, MVPsSaaS, portais, apps complexos
Curva de aprendizadoMenorMaior

Flask brilha em microsserviços, APIs leves, protótipos rápidos e situações onde você quer controle total sobre cada componente. Django é mais produtivo em sistemas complexos com muitas funcionalidades integradas.

Opções de Deploy

O Flask em produção precisa de um servidor WSGI. As opções mais comuns:

# Gunicorn (recomendado para produção)
pip install gunicorn
gunicorn "app:create_app()" --workers 4 --bind 0.0.0.0:5000

# uWSGI (alternativa robusta)
pip install uwsgi
uwsgi --http :5000 --module app:app --processes 4

Para containers Docker:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "app:create_app()", "--bind", "0.0.0.0:5000"]

Erros Comuns

  • Usar app.run() em produção: o servidor de desenvolvimento não é adequado para produção
  • Não usar Application Factory: dificulta testes e múltiplos ambientes
  • Contexto de aplicação: acessar db fora do contexto da aplicação gera erros; use with app.app_context()
  • SECRET_KEY fraca ou hardcoded: sempre use variáveis de ambiente para secrets

Boas Práticas

  • Adote o padrão Application Factory desde o início
  • Organize o código em Blueprints por domínio (usuarios, produtos, autenticacao)
  • Use variáveis de ambiente para configurações sensíveis
  • Escreva testes com o test_client do Flask
  • Use Flask-Migrate para gerenciar migrações de banco

Termos Relacionados

  • Django - Framework web completo com batteries included
  • FastAPI - Framework moderno para APIs de alta performance
  • API REST - Padrão de APIs RESTful
  • Decorators - Usado extensivamente no Flask para rotas