Python, alternative solide pour le web
Python n’est pas seulement le langage de la data science : c’est aussi un excellent choix pour le développement web. Sa syntaxe claire, son écosystème riche, et ses frameworks matures en font une option sérieuse face à Node.js ou PHP. Deux frameworks dominent : Django pour les applications complètes et structurées, FastAPI pour les API modernes et performantes. Ce tutoriel présente les deux et leur contexte d’usage.
Django : le framework « batteries included »
Django fournit tout ce qu’il faut pour construire une application web complète : ORM puissant, système de template, authentification, administration automatique, migrations de base, internationalisation, sécurité par défaut. Cette exhaustivité accélère considérablement le développement pour les projets classiques.
Créé en 2005 pour un journal en ligne, Django a fait ses preuves sur des sites à fort trafic : Instagram, Pinterest, Mozilla, Disqus. Sa maturité et sa documentation sont exceptionnelles.
Installation et premier projet Django
Créez un environnement virtuel Python : python -m venv venv, activez-le (source venv/bin/activate sur Unix, venv\Scripts\activate sur Windows). Installez Django : pip install django. Créez un projet : django-admin startproject monsite. Lancez : python manage.py runserver.
Une page par défaut s’affiche sur http://localhost:8000. Le projet contient : manage.py (interface en ligne de commande), monsite/ (configuration), db.sqlite3 (base créée au besoin).
Les applications Django
Django organise le code en « applications » réutilisables. python manage.py startapp blog crée une application. Chaque application contient : models.py (modèles de données), views.py (logique), urls.py (routage), templates/ (HTML), admin.py (interface d’administration).
Ajoutez l’application dans INSTALLED_APPS de settings.py pour qu’elle soit reconnue.
Les modèles et l’ORM
Les modèles définissent la structure des données Python :
class Article(models.Model):
titre = models.CharField(max_length=200)
contenu = models.TextField()
auteur = models.ForeignKey('auth.User', on_delete=models.CASCADE)
date_publication = models.DateTimeField(auto_now_add=True)
python manage.py makemigrations puis python manage.py migrate crée la table correspondante. L’ORM Django permet des requêtes expressives : Article.objects.filter(auteur=user).order_by(‘-date_publication’). Pas de SQL direct dans la plupart des cas.
Les vues et le routage
Les vues traitent les requêtes et retournent des réponses. Elles peuvent être basées sur des fonctions (simples) ou sur des classes (plus structurées). Exemple :
def article_detail(request, id):
article = get_object_or_404(Article, id=id)
return render(request, 'article_detail.html', {'article': article})
urls.py mappe les URLs aux vues : path(‘article/<int:id>/’, views.article_detail, name=’article_detail’).
Les templates
Django utilise son propre moteur de templates. Héritage de templates via {% extends %}, blocs extensibles avec {% block %}, boucles et conditions avec {% for %}, {% if %}, interpolation avec {{ variable }}. Ces constructions permettent des mises en page flexibles avec peu de code.
L’admin automatique
Fonction signature de Django : une interface d’administration générée automatiquement à partir des modèles. Après avoir enregistré les modèles dans admin.py, les administrateurs disposent d’un CRUD complet sans avoir à le coder. Pour les projets internes ou les back-offices, cela représente un gain de temps immense.
L’authentification et les permissions
Django intègre un système d’authentification complet : utilisateurs, groupes, permissions, login/logout, réinitialisation de mot de passe, sessions. Les décorateurs @login_required protègent les vues. Les permissions par objet permettent des règles fines.
Django REST Framework
Pour construire des API, Django REST Framework (DRF) est le complément naturel de Django. Il ajoute : serializers (conversion modèle/JSON), viewsets (vues génériques pour CRUD), authentification (JWT, tokens, basic auth), pagination, filtrage, permissions. Très puissant, un peu lourd pour des API simples.
pip install djangorestframework, ajout aux INSTALLED_APPS, définition de viewsets et routes. Vous obtenez rapidement une API complète.
FastAPI : le framework moderne
FastAPI, créé par Sebastián Ramírez, est plus récent et cible spécifiquement les API modernes. Ses atouts : performance excellente (comparable à Node.js et Go grâce à Starlette), typage Python fort (utilisant Pydantic), documentation OpenAPI générée automatiquement, syntaxe élégante, support natif de l’asynchrone.
Premier projet FastAPI
pip install fastapi uvicorn. Créez main.py :
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Article(BaseModel):
titre: str
contenu: str
@app.post("/articles")
def creer_article(article: Article):
return {"id": 1, **article.dict()}
uvicorn main:app –reload lance le serveur. La documentation interactive est disponible sur /docs.
Les apports de FastAPI
La validation des entrées est automatique grâce à Pydantic : si un champ requis manque, l’API retourne une erreur 422 avec le détail. La documentation Swagger est générée sans effort. La complétion dans l’IDE est excellente grâce au typage.
L’asynchrone natif (async def) permet des performances élevées pour les cas IO-bound. Parfait pour des API qui orchestrent plusieurs appels externes.
FastAPI avec base de données
SQLAlchemy est l’ORM Python de référence. Avec Alembic pour les migrations, il fournit un stack robuste. Pour plus de simplicité, SQLModel (du même auteur que FastAPI) combine SQLAlchemy et Pydantic pour une expérience intégrée.
Choisir entre Django et FastAPI
Django convient pour : applications web avec beaucoup de pages HTML rendues côté serveur, admin riche, besoins métier divers (auth, CMS, CRM), équipes qui apprécient l’exhaustivité et les conventions. FastAPI convient pour : API pures (pas de rendu HTML), priorité à la performance, architecture microservices, développement piloté par la spécification.
Pour un projet avec à la fois une API et une application web : combiner Django (pour le back-office) et FastAPI (pour l’API publique) est parfaitement possible. Ou utiliser Django + DRF si on préfère une seule base.
Le déploiement Python
Gunicorn ou Uvicorn servent l’application en production. Nginx comme reverse proxy, HTTPS via Let’s Encrypt. Pour Django : collectstatic pour les fichiers statiques, migrations à appliquer, settings séparés par environnement.
Les plateformes comme Railway, Render, Heroku, Fly.io simplifient le déploiement. Pour plus de contrôle, un VPS avec une stack classique (Nginx + Gunicorn + PostgreSQL) reste efficace et économique.
Les bonnes pratiques
Environnements virtuels toujours. Dépendances listées dans requirements.txt ou pyproject.toml. Variables d’environnement pour les secrets (python-decouple, python-dotenv). Tests avec pytest. Formattage avec black, vérification avec ruff. Pré-commit hooks pour automatiser.
L’écosystème data
Un avantage de Python : la connexion naturelle avec l’écosystème data (pandas, scikit-learn, PyTorch, LangChain). Pour des applications intégrant machine learning ou analyses avancées, Python évite les allers-retours entre langages.
Conclusion : deux choix robustes
Python offre des options matures pour le développement web. Django, par son exhaustivité et sa stabilité, reste un guide général. FastAPI, par sa modernité et ses performances, s’impose pour les nouvelles API. Pour une PME, le choix dépend du contexte et des compétences disponibles. Les deux frameworks disposent de documentation excellente et de communautés actives. Expérimentez sur un projet concret pour vous forger votre opinion.
Comprendre la différence ASGI vs WSGI avant de choisir
WSGI est le protocole synchrone historique de Python (PEP 3333), utilisé par Django jusqu’à la version 3.0 et la plupart des stacks Flask. Une requête bloque un worker tant qu’elle n’est pas terminée. ASGI (Asynchronous Server Gateway Interface) lève cette limite : un seul worker peut gérer des centaines de connexions simultanées non bloquantes, ce qui change radicalement la donne pour les API à fort trafic.
FastAPI est ASGI nativement. Django depuis la version 4 supporte ASGI via Daphne ou Uvicorn, ce qui permet d’écrire des vues async et d’utiliser les WebSockets via Channels. Pour une PME à Dakar qui démarre une API mobile money en 2026, le choix par défaut est ASGI : la latence reste maîtrisée même quand 200 utilisateurs poussent un transaction simultanément.
# Démarrage Uvicorn pour FastAPI
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
# Démarrage Daphne pour Django ASGI
daphne -b 0.0.0.0 -p 8000 monprojet.asgi:application
Vous saurez que tout fonctionne quand : sur un VPS Hetzner CX22 à 4 500 FCFA/mois, FastAPI avec Uvicorn tient 3 000-5 000 requêtes par seconde sur des endpoints simples. Django ASGI plafonne autour de 800-1 200 req/s à cause de l’overhead de l’ORM. C’est pour ça que beaucoup d’équipes utilisent les deux : Django pour l’admin et le CMS, FastAPI pour les API publiques.
Maîtriser Pydantic v2 et les annotations de type pour FastAPI
FastAPI tire 80 % de sa valeur de Pydantic v2 (réécrit en Rust en 2023, 5-50x plus rapide que la v1). Toute donnée d’entrée et de sortie est validée par un modèle déclaratif, ce qui élimine les classes Validator manuelles et garantit la cohérence des contrats d’API.
Le pattern type pour un endpoint qui crée un client dans une fintech à Abidjan ressemble à ceci.
from pydantic import BaseModel, EmailStr, Field
from typing import Annotated
class ClientCreate(BaseModel):
nom: Annotated[str, Field(min_length=2, max_length=80)]
email: EmailStr
telephone: Annotated[str, Field(pattern=r'^\+221[0-9]{9}$')]
@app.post("/clients")
async def creer_client(payload: ClientCreate):
return {"id": 1, **payload.model_dump()}
Résultat type : un POST avec un email malformé renvoie automatiquement une 422 Unprocessable Entity avec un détail JSON exploitable côté frontend. Pas besoin d’écrire un seul if. La doc OpenAPI/Swagger est générée à /docs avec le schéma exact.
Tester ses endpoints avec pytest et TestClient
Une API non testée est une API en sursis. FastAPI fournit TestClient (basé sur httpx) qui permet d’écrire des tests d’intégration sans serveur HTTP réel. Django, lui, propose pytest-django avec son client Django historique. Le pattern est similaire dans les deux cas : préparer un fixture de base, exécuter une requête, vérifier la réponse.
# test_clients.py - FastAPI
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_creer_client_ok():
r = client.post("/clients", json={
"nom": "Aminata Diallo",
"email": "aminata@exemple.sn",
"telephone": "+221771234567"
})
assert r.status_code == 200
assert r.json()["nom"] == "Aminata Diallo"
def test_creer_client_email_invalide():
r = client.post("/clients", json={"nom": "X", "email": "pas-un-email", "telephone": "+221771234567"})
assert r.status_code == 422
Lancez avec pytest -v. Sur une équipe distribuée entre Cotonou et Lomé, viser 70-80 % de couverture sur les endpoints critiques évite les régressions silencieuses lors des releases. Intégrez les tests dans GitHub Actions pour bloquer le merge si un test casse.
Implémenter des WebSockets pour le temps réel
Une boutique en ligne à Plateau qui veut afficher le stock en temps réel à 50 vendeurs simultanés a besoin de WebSockets. FastAPI supporte les WebSockets nativement avec async, sans dépendance supplémentaire. Django passe par django-channels et un broker Redis.
from fastapi import WebSocket
@app.websocket("/ws/stock")
async def ws_stock(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_json()
# broadcast aux autres clients
await websocket.send_json({"event": "stock_update", "data": data})
except Exception:
await websocket.close()
Pour Django, prévoyez un Redis sur le même VPS pour le channel layer. Coût opérationnel : un workflow simple (notifications push, suivi de commande live) coûte 10-15 minutes de setup avec FastAPI contre 1-2 heures avec Django Channels. Choisissez la stack en fonction de vos besoins, pas par habitude.
Comparer les performances réelles en 2026
Les benchmarks publics 2026 montrent FastAPI autour de 5 000-8 000 req/s sur un endpoint trivial, Django Ninja (FastAPI-like sur Django) autour de 3 000-4 000 req/s, Django classique 800-1 500 req/s, et Litestar (alternative ASGI moderne) autour de 6 000-9 000 req/s. Ces chiffres dépendent énormément de la base de données, du nombre de workers et du serveur hôte.
Pour une équipe qui démarre un projet en 2026 avec contrainte budget VPS Hetzner ou Contabo, la matrice de décision est simple. API REST publique haute performance : FastAPI ou Litestar. Application web complète avec admin, formulaires, CMS : Django classique, accepter le coût en performance, gagner en productivité. Stack hybride sur projet établi : Django Ninja qui combine ORM Django et routes type FastAPI.
Lectures complémentaires sur le déploiement Python en production, voir notre tutoriel API Claude qui couvre les patterns d’intégration LLM dans une API FastAPI, et notre guide Git et GitHub pour le versionnement de vos projets Python.
Préparer son équipe à la stack Python en Afrique de l’Ouest
L’écosystème Python web reste relativement peu maîtrisé dans les écoles d’ingénieurs ouest-africaines, qui privilégient Java et PHP. Pour un lead technique à Dakar ou à Niamey qui veut monter une équipe sur Django ou FastAPI, prévoyez 4 à 8 semaines d’onboarding sur les concepts ASGI, Pydantic et les patterns asynchrones. La courbe d’apprentissage paye sur le long terme grâce à la lisibilité du code et à la richesse des bibliothèques data.
Côté formation, les cours gratuits de TestDriven.io ou les vidéos officielles de tiangolo (auteur de FastAPI) couvrent l’essentiel en une vingtaine d’heures. Pour Django, le tutoriel officiel de djangoproject.com reste la meilleure porte d’entrée, complété par la chaîne YouTube de DennisIvy pour les patterns avancés. Ces ressources sont accessibles partout en français ou en anglais, sans abonnement payant requis.
Le piège classique : recruter un développeur Java senior et lui demander de faire du Django sans formation. Le résultat est presque toujours un code bloquant les performances asynchrones et reproduisant des patterns d’EJB obsolètes. Mieux vaut former en interne un développeur curieux ou recruter directement un profil Python avec 2-3 ans d’expérience documentée sur GitHub. Le surcoût initial se rentabilise dès le 6e mois grâce à la qualité du code livré et la stabilité de la production.