Python Flask Microservices en pratique : le code et les commandes qui comptent vraiment

Python Flask Microservices : l'essentiel en un article — vrai code, schémas et étapes concrètes, extraits d'un cours de 24 leçons.

Python Flask Microservices en pratique : le code et les commandes qui comptent vraiment

Pas de théorie interminable ici : on ouvre le terminal et on pratique. Voici l'essentiel de Python Flask Microservices, extrait directement d'un cours complet de 24 leçons — avec du vrai code que tu peux copier-coller maintenant.

tl;dr
  • Flask fundamentals
  • Architecture microservices
  • Communication REST
  • Message bus async
  • gRPC entre services
~$ cat ./parcours.md # Python Flask Microservices — 8 chapitres
01
Flask fundamentals
→ Flask vs Django vs FastAPI→ Premier app et blueprints+ 1 autres leçons
02
Architecture microservices
→ Monolith vs microservices→ Decomposer par domaine (DDD)+ 1 autres leçons
03
Communication REST
→ HTTP synchrone avec requests/httpx→ Retry, circuit breaker, timeout+ 1 autres leçons
04
Message bus async
→ RabbitMQ et pika→ Kafka pour event streaming+ 1 autres leçons
05
gRPC entre services
→ Protobuf et grpcio→ Streaming bidirectionnel+ 1 autres leçons
06
Orchestration
→ Docker Compose multi-services→ Kubernetes basics+ 1 autres leçons
07
Observabilité
→ Logging centralise→ Distributed tracing+ 1 autres leçons
08
Projet final e-commerce
→ Decomposition en services→ Implementation services + Gateway+ 1 autres leçons
🏁
Projet final
→ Tu repars avec un projet concret et démontrable

Monolith vs microservices

Monolithe

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

# 1 codebase, 1 deployment, 1 DB
# Toutes les fonctions dans le meme process

Microservices

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

# N services, N deployments, N DBs (1 par service)
# Communication via HTTP/gRPC/events

Comparaison

CritereMonolitheMicroservices
Dev velocity (debut)RapideLent (overhead)
Dev velocity (1000+ devs)Lent (conflicts)Rapide (isolation)
DeploymentTout-ou-rienIndependant par service
ScalingVertical/whole appHorizontal par service
Tech stackUniformePolyglotte
Database1 partagee1 par service
TestsSimplesComplexes (integration)
DebuggingStack trace claireDistributed tracing
Operations1 choseN choses (k8s)
LatencyIn-process (us)Network (ms)
Failure modeTout tombePartial (degraded)

Quand monolithe ?

NOTEChoisir monolithe si :
  • Equipe < 20 devs
  • MVP / startup early stage
  • Domaine pas encore clair
  • Pas besoin de scaling extreme
  • Operations limitees (pas devops dedie)

Quand microservices ?

NOTEChoisir microservices si :
  • Equipes nombreuses, autonomes (>50 devs)
  • Domaine bien compris, boundaries claires
  • Composants avec besoins scaling differents
  • Polyglotte tech necessaire
  • Capable de gerer la complexite ops

"Modular monolith" : le sweet spot 2026

output
# Structure d'un monolithe modulaire
myapp/
  modules/
    auth/
      api/
      services/
      models/
      tests/
    orders/
      api/
      services/
      models/
      tests/
    notifications/
  shared/
    db/
    events/        # bus interne
    logging/

# 1 deployment, mais frontieres claires
# Communication via events (in-process)
# Facilite l'extraction future en microservices

Couts caches des microservices

Patterns architecturaux

output
+-----------------+
|   API Gateway   |    <-- entry point unique
+-----------------+
        |
+-------+-------+-------+
|       |       |       |
v       v       v       v
+----+ +-----+ +-----+ +------+
|Auth| |User | |Cart | |Order |    <-- microservices
+----+ +-----+ +-----+ +------+
   |       |      |       |
   v       v      v       v
+----+ +-----+ +-----+ +------+
|DB1 | |DB2  | |Redis| |DB3   |    <-- chacun sa DB
+----+ +-----+ +-----+ +------+
                        |
                        v
                 +-------------+
                 | Kafka/MQ    |    <-- events async
                 +-------------+

Strangler Pattern (migration)

output
# Migrer progressivement monolithe -> microservices

# Etape 0 : Monolithe
#   client -> monolithe

# Etape 1 : Extract User Service
#   client -> API Gateway
#                |-- /users/* -> user-service (nouveau)
#                |-- /*       -> monolithe (reste)

# Etape 2 : Extract Order Service
#   client -> API Gateway
#                |-- /users/*  -> user-service
#                |-- /orders/* -> order-service
#                |-- /*        -> monolithe

# ... etc jusqu'au demantellement total du monolithe

Resume

NOTEA retenir
  • Monolithe = start here, evolue en microservices si besoin
  • Microservices = complexity tax mais scaling/autonomy
  • "Modular monolith" est souvent le bon compromis
  • Cout cache : network, consistency, ops
  • Strangler pattern pour migrer progressivement

Flask vs Django vs FastAPI

Tableau comparatif

AspectFlaskDjangoFastAPI
PhilosophyMicro, minimalBatteries includedModern, async
ORMSQLAlchemy (libre)Django ORMSQLAlchemy/Tortoise
AdminNon (Flask-Admin)Auto-genereNon
AuthFlask-LoginBuiltin completJWT/OAuth (manuel)
AsyncLimite (3.0+)PartielNative
ValidationMarshmallow/PydanticForms/SerializersPydantic native
OpenAPIFlask-Smorestdrf-spectacularAuto-genere
PerformanceBonneBonneExcellente (async)
CourbeTres facileModereeFacile
Cas d'usageMicroservices, APIsApps web complexesAPIs modernes

Quand choisir Flask

NOTEIdeal pour :
  • Microservices (lightweight, demarrage rapide)
  • APIs JSON simples sans besoin d'admin
  • Apps prototypage rapide
  • Backend pour SPA React/Vue avec API REST
  • Webhook receivers, bots, jobs HTTP
  • Migration progressive depuis legacy
NOTEPas ideal pour :
  • Applications avec beaucoup de CRUD admin
  • Besoin d'auth/permissions/migrations builtin
  • Equipes preferant un framework opinionated

Hello World comparatif

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

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

# 5 lignes, 1 fichier, ca tourne avec : flask run
output
# FastAPI (pour comparer)
from fastapi import FastAPI
app = FastAPI()

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

# uvicorn main:app
output
# Django REST Framework (pour comparer)
# Necessite : settings.py, urls.py, views.py, manage.py...
# Beaucoup plus de boilerplate mais ENORMEMENT de features

Installation Flask

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

pip install flask

# Ou avec dependances classiques microservice
pip install flask gunicorn requests sqlalchemy alembic \
            marshmallow flask-marshmallow flask-smorest \
            python-dotenv pytest

# Lancer en dev
flask --app app run --debug --port 5000

Stack Flask moderne 2026

output
# Production microservice stack
flask                       # framework
flask-smorest               # API + OpenAPI auto
marshmallow                 # serialization (ou Pydantic)
sqlalchemy[asyncio]         # ORM
alembic                     # migrations
gunicorn                    # WSGI prod
gevent                      # async workers
httpx                       # client HTTP moderne
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+ supporte async views
@app.route("/async-data")
async def get_data():
    data = await fetch_from_api()
    return data

# MAIS reste WSGI : chaque async view bloque un worker thread
# Pour vrai async : utiliser ASGI (FastAPI, Quart) ou Gunicorn+gevent

gunicorn --worker-class gevent --workers 4 app:app
# gevent rend les I/O non-bloquants meme avec views sync

Deploy K8s + tests integration

Projet 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
    
    # Verifier 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 demarre 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. Wait for async processing (saga)
    for _ in range(30):        # max 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
# Verifier que le contrat REST entre consumer (web-gateway) et provider (catalog) tient

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 genere -> uploade vers Pact Broker
# Provider relit le pact -> verifie son 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

Cet article couvre les extraits les plus utiles — le cours complet Python Flask Microservices (8 chapitres, 24 leçons, exercices corrigés et projet final) t'emmène jusqu'au bout.

./acceder-au-cours-complet cours gratuit : Vibe Coding

FAQ

Combien de temps pour apprendre Python Flask Microservices ?
Avec une progression structurée (8 chapitres, 24 leçons courtes et pratiques), on atteint un niveau opérationnel en quelques semaines à raison de 30 à 60 minutes par jour. L'important est de pratiquer chaque notion immédiatement.
Faut-il des prérequis ?
Des bases en informatique suffisent. Si tu sais utiliser un terminal et lire du code simple, tu es prêt.
Par où commencer concrètement ?
Reproduis les commandes de cet article, puis suis le cours complet Python Flask Microservices : il enchaîne les 24 leçons dans l'ordre, avec exercices et projet final.

📬 Tu veux recevoir ce type de guide chaque semaine ? Abonne-toi gratuitement — code réel, zéro blabla.