Python Flask Microservices na prática: o código e os comandos que realmente importam

Python Flask Microservices: o essencial em um artigo — código real, diagramas e etapas concretas, extraídos de um curso de 24 lições.

Python Flask Microservices na prática: o código e os comandos que realmente importam

Sem teoria interminável aqui: abra o terminal e pratique. Aqui está o essencial de Python Flask Microservices, extraído diretamente de um curso completo de 24 lições — com código real que você pode copiar e colar agora.

tl;dr
  • Flask fundamentals
  • Architecture microservices
  • Communication REST
  • Message bus async
  • gRPC entre services
~$ cat ./parcours.md # Python Flask Microservices — 8 capítulos
01
Flask fundamentals
→ Flask vs Django vs FastAPI→ Primeiro app e blueprints+ 1 mais lições
02
Architecture microservices
→ Monolith vs microservices→ Decompor por domínio (DDD)+ 1 mais lições
03
Communication REST
→ HTTP síncrono com requests/httpx→ Retry, circuit breaker, timeout+ 1 mais lições
04
Message bus async
→ RabbitMQ e pika→ Kafka para event streaming+ 1 mais lições
05
gRPC entre services
→ Protobuf e grpcio→ Streaming bidirecional+ 1 mais lições
06
Orchestration
→ Docker Compose multi-services→ Kubernetes basics+ 1 mais lições
07
Observabilité
→ Logging centralizado→ Distributed tracing+ 1 mais lições
08
Projeto final e-commerce
→ Decomposição em serviços→ Implementação de serviços + Gateway+ 1 mais lições
🏁
Projeto final
→ Você sai com um projeto concreto e demonstrável

Monolith vs microservices

Monolithe

output
+----------------------------------------+
|        Application monolithique         |
|  +-----+  +-------+  +-------+          |
|  | UI  |  | Auth  |  | Order |  ...     |
|  +-----+  +-------+  +-------+          |
|  +----------------------------------+   |
|  |           Database               |   |
|  +----------------------------------+   |
+----------------------------------------+

# 1 codebase, 1 deployment, 1 DB
# Todas as funções no mesmo processo

Microservices

output
+---------------+  +---------------+  +---------------+
| Auth Service  |  | Order Service |  | Email Service |
| +DB users     |  | +DB orders    |  | +SMTP         |
+---------------+  +---------------+  +---------------+
        |                 |                  |
        +--------+--------+------------------+
                 |
        +--------+--------+
        | Message Broker  |
        | (Kafka/RabbitMQ)|
        +-----------------+

# N serviços, N deploys, N DBs (1 por serviço)
# Comunicação via HTTP/gRPC/events

Comparaison

CritérioMonólitoMicrosserviços
Velocidade de dev (início)RápidaLenta (overhead)
Velocidade de dev (1000+ devs)Lenta (conflitos)Rápida (isolamento)
DeployTudo ou nadaIndependente por serviço
EscalabilidadeVertical/app inteiroHorizontal por serviço
Stack techUniformePoliglota
Banco de dados1 compartilhado1 por serviço
TestesSimplesComplexos (integração)
DebugStack trace claraDistributed tracing
Operações1 coisaN coisas (k8s)
LatênciaIn-process (µs)Rede (ms)
Modo de falhaTudo caiParcial (degradado)

Quand monolithe ?

NOTEEscolha monólito se:
  • Equipe < 20 devs
  • MVP / startup em estágio inicial
  • Domínio ainda não claro
  • Sem necessidade de scaling extremo
  • Operações limitadas (sem devops dedicado)

Quand microservices ?

NOTEEscolha microsserviços se:
  • Equipes numerosas e autônomas (>50 devs)
  • Domínio bem compreendido, limites claros
  • Componentes com necessidades de scaling diferentes
  • Stack poliglota necessária
  • Capaz de gerenciar a complexidade operacional

"Modular monolith" : le sweet spot 2026

output
# Estrutura de um monólito modular
myapp/
  modules/
    auth/
      api/
      services/
      models/
      tests/
    orders/
      api/
      services/
      models/
      tests/
    notifications/
  shared/
    db/
    events/        # bus interno
    logging/

# 1 deploy, mas fronteiras claras
# Comunicação via eventos (in-process)
# Facilita a extração futura para microsserviços

Couts caches des microservices

Patterns architecturaux

output
+-----------------+
|   API Gateway   |    <-- ponto de entrada único
+-----------------+
        |
+-------+-------+-------+
|       |       |       |
v       v       v       v
+----+ +-----+ +-----+ +------+
|Auth| |User | |Cart | |Order |    <-- microsserviços
+----+ +-----+ +-----+ +------+
   |       |      |       |
   v       v      v       v
+----+ +-----+ +-----+ +------+
|DB1 | |DB2  | |Redis| |DB3   |    <-- cada um com seu DB
+----+ +-----+ +-----+ +------+
                        |
                        v
                 +-------------+
                 | Kafka/MQ    |    <-- eventos assíncronos
                 +-------------+

Strangler Pattern (migration)

output
# Migrar progressivamente monólito -> microsserviços

# Etapa 0 : Monólito
#   client -> monólito

# Etapa 1 : Extrair User Service
#   client -> API Gateway
#                |-- /users/* -> user-service (novo)
#                |-- /*       -> monólito (permanece)

# Etapa 2 : Extrair Order Service
#   client -> API Gateway
#                |-- /users/*  -> user-service
#                |-- /orders/* -> order-service
#                |-- /*        -> monólito

# ... e assim por diante até o desmantelamento total do monólito

Resume

NOTEPara lembrar
  • Monólito = comece aqui, evolua para microsserviços se necessário
  • Microsserviços = taxa de complexidade, mas scaling/autonomia
  • "Modular monolith" costuma ser o bom meio-termo
  • Custo oculto: rede, consistência, ops
  • Strangler pattern para migrar progressivamente

Flask vs Django vs FastAPI

Tableau comparatif

AspectoFlaskDjangoFastAPI
FilosofiaMicro, minimalistaBatteries includedModerno, assíncrono
ORMSQLAlchemy (livre)Django ORMSQLAlchemy/Tortoise
AdminNão (Flask-Admin)Auto-geradoNão
AuthFlask-LoginCompleto nativoJWT/OAuth (manual)
AsyncLimitado (3.0+)ParcialNativo
ValidaçãoMarshmallow/PydanticForms/SerializersPydantic nativo
OpenAPIFlask-Smorestdrf-spectacularAuto-gerado
PerformanceBoaBoaExcelente (async)
Curva de aprendizadoMuito fácilModeradaFácil
Caso de usoMicrosserviços, APIsApps web complexasAPIs modernas

Quand choisir Flask

NOTEIdeal para:
  • Microsserviços (leve, inicialização rápida)
  • APIs JSON simples sem necessidade de admin
  • Apps de prototipagem rápida
  • Backend para SPA React/Vue com API REST
  • Webhook receivers, bots, jobs HTTP
  • Migração progressiva de legacy
NOTENão ideal para:
  • Aplicações com muito CRUD admin
  • Necessidade de auth/permissions/migrations nativas
  • Equipes que preferem framework opinionated

Hello World comparatif

output
# Flask
from flask import Flask
app = Flask(__name__)

@app.route("/hello")
def hello():
    return {"message": "Hello"}

# 5 linhas, 1 arquivo, roda com: flask run
output
# FastAPI (para comparar)
from fastapi import FastAPI
app = FastAPI()

@app.get("/hello")
async def hello():
    return {"message": "Hello"}

# uvicorn main:app
output
# Django REST Framework (para comparar)
# Requer: settings.py, urls.py, views.py, manage.py...
# Muito mais boilerplate, mas ENORME quantidade de features

Installation Flask

output
python -m venv .venv
source .venv/bin/activate              # Linux/Mac
.venv\Scripts\activate                 # Windows

pip install flask

# Ou com dependências clássicas de microsserviço
pip install flask gunicorn requests sqlalchemy alembic \
            marshmallow flask-marshmallow flask-smorest \
            python-dotenv pytest

# Executar em dev
flask --app app run --debug --port 5000

Stack Flask moderne 2026

output
# Stack de microsserviço em produção
flask                       # framework
flask-smorest               # API + OpenAPI auto
marshmallow                 # serialização (ou Pydantic)
sqlalchemy[asyncio]         # ORM
alembic                     # migrations
gunicorn                    # WSGI prod
gevent                      # async workers
httpx                       # cliente HTTP moderno
pydantic-settings           # config 12-factor
prometheus-flask-exporter   # metrics
sentry-sdk[flask]           # errors
opentelemetry-instrumentation-flask  # traces
pytest pytest-cov           # tests

Ecosysteme Flask

WSGI : Flask = synchrone par defaut

output
# Flask 3.0+ suporta async views
@app.route("/async-data")
async def get_data():
    data = await fetch_from_api()
    return data

# MAS continua WSGI: cada async view bloqueia uma thread de worker
# Para async de verdade: use ASGI (FastAPI, Quart) ou Gunicorn+gevent

gunicorn --worker-class gevent --workers 4 app:app
# gevent torna I/O não-bloqueante mesmo com views sync

Deploy K8s + tests integration

Projeto final • CI/CD • E2E

Tests unitaires

output
# services/order/tests/test_order_service.py
import pytest
from unittest.mock import Mock

def test_place_order_creates_order_and_outbox(db, app):
    cart_client = Mock()
    cart_client.get.return_value = {"items": [{"product_id": "p1", "qty": 2}]}
    
    catalog_client = Mock()
    catalog_client.get_product.return_value = {
        "id": "p1", "name": "Book", "price_cents": 1500,
    }
    
    service = OrderService(db, cart_client, catalog_client)
    order = service.place_order(user_id="user-1")
    
    assert order.total_cents == 3000
    assert len(order.items) == 1
    
    # Verificar outbox
    events = Outbox.query.all()
    assert len(events) == 1
    assert events[0].event_type == "order.created"
    assert events[0].payload["total_cents"] == 3000
    cart_client.clear.assert_called_once_with("user-1")

def test_empty_cart_raises():
    cart_client = Mock()
    cart_client.get.return_value = {"items": []}
    
    service = OrderService(db, cart_client, Mock())
    with pytest.raises(ValidationError):
        service.place_order("user-1")

Tests d'integration multi-services

output
# tests/integration/test_e2e_checkout.py
import pytest, httpx, time

# conftest.py inicia docker-compose
@pytest.fixture(scope="session")
def stack():
    subprocess.run(["docker", "compose", "up", "-d", "--wait"], check=True)
    yield
    subprocess.run(["docker", "compose", "down", "-v"])

def test_full_checkout_flow(stack):
    base = "http://localhost"
    
    # 1. Signup
    r = httpx.post(f"{base}/api/auth/signup", json={
        "email": "alice@x.com", "password": "pass", "name": "Alice",
    })
    assert r.status_code == 201
    token = r.json()["access_token"]
    headers = {"Authorization": f"Bearer {token}"}
    
    # 2. List products
    r = httpx.get(f"{base}/api/products")
    product = r.json()["items"][0]
    
    # 3. Add to cart
    r = httpx.post(
        f"{base}/api/cart/items",
        json={"product_id": product["id"], "qty": 2},
        headers=headers,
    )
    assert r.status_code == 200
    
    # 4. Checkout
    r = httpx.post(f"{base}/api/checkout", headers=headers)
    assert r.status_code == 201
    order_id = r.json()["order_id"]
    
    # 5. Aguarda processamento assíncrono (saga)
    for _ in range(30):        # máx 30s
        r = httpx.get(f"{base}/api/orders/{order_id}", headers=headers)
        if r.json()["status"] == "paid":
            break
        time.sleep(1)
    else:
        pytest.fail("Order never reached 'paid' status")

Contract tests (Pact)

output
# Verifica se o contrato REST entre consumer (web-gateway) e provider (catalog) é mantido

from pact import Consumer, Provider

pact = Consumer("web-gateway").has_pact_with(Provider("catalog"), pact_dir="./pacts")

def test_get_product_contract():
    expected = {
        "id": "p1", "name": "Book", "price_cents": 1500, "stock": 10,
    }
    pact.given("product p1 exists") \
        .upon_receiving("a request for product p1") \
        .with_request("GET", "/products/p1") \
        .will_respond_with(200, body=expected)
    
    with pact:
        result = catalog_client.get_product("p1")
        assert result == expected

# Pact file gerado -> enviado para Pact Broker
# Provider lê o pact -> verifica sua API

Dockerfile production

output
# services/*/Dockerfile
FROM python:3.12-slim AS deps
WORKDIR /app
RUN pip install --no-cache-dir uv
COPY requirements.txt .
RUN uv pip install --system --no-cache -r requirements.txt

FROM python:3.12-slim
RUN useradd -m -u 1000 app
USER app
WORKDIR /app

COPY --from=deps /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=deps /usr/local/bin/gunicorn /usr/local/bin/gunicorn
COPY src/ ./src/

ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
EXPOSE 5000

HEALTHCHECK --interval=10s CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:5000/health')"

CMD ["gunicorn", "-c", "gunicorn.conf.py", "src.wsgi:app"]

CI/CD GitHub Actions

output
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        service: [auth, catalog, cart, order, payment, notification]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: {python-version: "3.12"}
      
      - name: Install deps
        working-directory: services/${{ matrix.service }}
        run: |
          pip install -e ../../shared
          pip install -r requirements.txt
          pip install pytest pytest-cov ruff mypy
      
      - name: Lint
        working-directory: services/${{ matrix.service }}
        run: |
          ruff check src
          mypy src
      
      - name: Tests
        working-directory: services/${{ matrix.service }}
        run: pytest --cov=src --cov-report=xml
      
      - uses: codecov/codecov-action@v4
  
  integration:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4
      - name: Start stack
        run: docker compose up -d --wait
      - name: Run integration tests
        run: pytest tests/integration/
      - name: Logs on failure
        if: failure()
        run: docker compose logs

CD : build + push + deploy

output
# .github/workflows/cd.yml
name: CD
on:
  push:
    tags: ["v*"]

jobs:
  build:
    strategy:
      matrix:
        service: [auth, catalog, cart, order, payment, notification]
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      
      - name: Build & push
        uses: docker/build-push-action@v5
        with:
          context: services/${{ matrix.service }}
          push: true
          tags: |
            ghcr.io/myorg/${{ matrix.service }}:${{ github.ref_name }}
            ghcr.io/myorg/${{ matrix.service }}:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max
  
  deploy:
    needs: build
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: azure/setup-helm@v4
      - name: Deploy via Helm
        run: |
          helm upgrade --install ecommerce ./k8s/charts/umbrella \
            -f ./k8s/values-prod.yaml \
            --set global.imageTag=${{ github.ref_name }} \
            --namespace prod \
            --atomic --timeout 10m
va-plus-loin

Este artigo cobre os trechos mais úteis — o curso completo Python Flask Microservices (8 capítulos, 24 lições, exercícios corrigidos e projeto final) leva você até o fim.

./acceder-au-cours-complet curso gratuito: Vibe Coding

FAQ

Quanto tempo para aprender Python Flask Microservices?
Com uma progressão estruturada (8 capítulos, 24 lições curtas e práticas), você atinge nível operacional em algumas semanas dedicando 30 a 60 minutos por dia. O importante é praticar cada conceito imediatamente.
Precisa de pré-requisitos?
Básico de informática é suficiente. Se você sabe usar um terminal e ler código simples, está pronto.
Por onde começar na prática?
Reproduza os comandos deste artigo e depois siga o curso completo Python Flask Microservices: ele encadeia as 24 lições em ordem, com exercícios e projeto final.

📬 Quer receber este tipo de guia toda semana? Inscreva-se gratuitamente — código real, zero enrolação.