Cours Python · Module 12: Projet final
Documentation technique
Dans cette leçon3
Le meilleur guide de la savane ne sert à rien si son savoir disparaît avec lui. Un nouveau membre de l'expédition ne reçoit alors qu'une copie des traces, sans légende. C'est pareil avec le code : un projet sans documentation, une seule personne sait le lancer, et au bout de trois mois même elle a oublié comment. La documentation, c'est le pont entre le code et les gens. Une bonne documentation fait vivre le projet même pendant que tu dors, et permet à un recruteur ou à un nouveau coéquipier de le comprendre en cinq minutes.
On construit la documentation sur trois niveaux : un README pour la personne qui découvre le dépôt, des docstrings pour celle qui lit le code, et une documentation d'API générée pour celles qui l'utilisent. Un bon ordre de travail : d'abord le README, puis les docstrings, puis la configuration de la documentation d'API générée, et enfin CHANGELOG.md, le journal des changements d'une version à l'autre.
README.md - La carte de visite du projet
Le README est la première chose que GitHub affiche sous la liste des fichiers. Ordre typique des sections : titre, description ou fonctionnalités, démarrage rapide, et la licence à la fin. Voici un exemple complet pour notre assistant :
1# AI Document Assistant
2
3Un assistant intelligent pour rechercher dans les documents grâce au RAG.
4
5## Fonctionnalités
6
7- Recherche sémantique dans les documents
8- Réponses en langage naturel
9- Prise en charge de PDF, DOCX, TXT
10- Réponses rapides (<2s)
11
12## Démarrage rapide
13
14### Prérequis
15- Python 3.12+
16- Docker (pour Qdrant)
17
18### Installation
19
20```bash
21# Cloner le dépôt
22git clone https://github.com/user/ai-doc-assistant.git
23cd ai-doc-assistant
24
25# Créer l'environnement
26python -m venv venv
27source venv/bin/activate
28
29# Installer les dépendances
30pip install -r requirements.txt
31
32# Lancer Qdrant
33docker compose up -d qdrant
34
35# Définir les variables d'environnement
36cp .env.example .env
37# Édite .env et ajoute OPENAI_API_KEY
38
39# Lancer l'application
40uvicorn app.main:app --reload
41```
42
43## Documentation de l'API
44
45Après le lancement : http://localhost:8000/docs
46
47## Architecture
48
49[Lien vers le diagramme d'architecture]
50
51## Tests
52
53```bash
54pytest tests/ -v
55```
56
57## Licence
58
59MITLe guide d'installation est une suite de commandes qu'on peut copier et exécuter : clone, environnement virtuel, dépendances, base de données, variables d'environnement, démarrage. Fais attention à cp .env.example .env : les vraies clés n'arrivent jamais dans le dépôt, seulement un modèle du fichier. docker compose (avec une espace) est la version actuelle de l'outil, intégrée à Docker sous forme de plugin.
Docstrings - La documentation dans le code
Une docstring est une chaîne entre triples guillemets juste sous la définition d'une classe ou d'une fonction. La PEP 257 décrit les conventions générales, et c'est toi qui choisis le format des sections. Les plus populaires sont le Google style et le NumPy style, tous deux compris par Sphinx (l'extension napoleon). Nous utilisons le Google style : les sections Attributes, Args, Returns, Raises et Example.
1from typing import Optional
2
3class RAGService:
4 """
5 Service RAG pour répondre aux questions à partir de documents.
6
7 Ce service implémente le pipeline RAG complet :
8 1. Embedding de la question
9 2. Recherche de documents similaires
10 3. Génération d'une réponse avec contexte
11
12 Attributes:
13 vector_store: Client de la base de données vectorielle
14 llm: Client du modèle de langage
15 embedder: Service d'embedding
16
17 Example:
18 >>> service = RAGService(vector_store, llm, embedder)
19 >>> response = await service.query("What is Python?")
20 >>> print(response.answer)
21 Python is a programming language...
22 """La docstring de la classe dit ce que fait le service et de quoi il se compose. L'exemple au format >>> montre l'utilisation, et la ligne en dessous est le résultat affiché. Le constructeur est simple et n'a pas besoin de description séparée :
1 def __init__(
2 self,
3 vector_store: VectorStore,
4 llm: LLMClient,
5 embedder: EmbeddingService
6 ):
7 self.vector_store = vector_store
8 self.llm = llm
9 self.embedder = embedderLes types des arguments (VectorStore, LLMClient, EmbeddingService) sont des interfaces de la couche infrastructure, conformément à l'architecture de la leçon précédente. C'est la méthode publique qui demande le plus de description :
1 async def query(
2 self,
3 question: str,
4 top_k: int = 5,
5 filters: Optional[dict] = None
6 ) -> Response:
7 """
8 Exécute une requête RAG.
9
10 Args:
11 question: Question de l'utilisateur en langage naturel
12 top_k: Nombre de documents à récupérer (défaut : 5)
13 filters: Filtres de métadonnées optionnels
14
15 Returns:
16 Response: Objet contenant la réponse et les sources
17
18 Raises:
19 ValueError: Quand la question est vide
20 LLMError: Quand une erreur de génération survient
21
22 Example:
23 >>> response = await service.query(
24 ... "How does RAG work?",
25 ... top_k=3,
26 ... filters={"category": "ai"}
27 ... )
28 """
29 if not question.strip():
30 raise ValueError("Question cannot be empty")
31
32 # Implémentation...La section Raises est souvent oubliée, alors que c'est elle qui dit ce qui peut mal tourner. Tu peux lire une docstring dans la console avec help(RAGService.query), c'est donc une documentation toujours sous la main. Attention : l'exemple avec await est fait pour être lu, un doctest classique ne l'exécutera pas.
Documentation de l'API avec FastAPI
FastAPI génère automatiquement la documentation de l'API au standard OpenAPI (anciennement Swagger), à partir des types et des modèles Pydantic. D'abord, les métadonnées de l'application :
1from fastapi import FastAPI, HTTPException
2from pydantic import BaseModel, Field
3
4app = FastAPI(
5 title="AI Document Assistant API",
6 description="API REST pour un assistant documentaire intelligent",
7 version="1.0.0",
8 docs_url="/docs",
9 redoc_url="/redoc"
10)Sous /docs, tu obtiens la Swagger UI interactive, sous /redoc la vue alternative ReDoc. Passons aux modèles de requête et de réponse. Pydantic valide les données, et Field ajoute des contraintes et des descriptions :
1class QueryRequest(BaseModel):
2 """Requête RAG."""
3 question: str = Field(
4 ...,
5 description="Question en langage naturel",
6 examples=["What is machine learning?"]
7 )
8 top_k: int = Field(
9 default=5,
10 ge=1,
11 le=20,
12 description="Nombre de documents sources"
13 )
14
15class QueryResponse(BaseModel):
16 """Réponse du système RAG."""
17 answer: str = Field(description="Réponse générée")
18 sources: list[dict] = Field(description="Documents sources")
19 latency_ms: float = Field(description="Temps de réponse en ms")ge=1, le=20 signifie « de 1 à 20 », donc top_k=50 est rejeté avec une erreur 422 avant même d'atteindre ton code. Les valeurs d'exemple se donnent avec examples=[...]. L'ancien paramètre example= est déprécié dans Pydantic v2 et produit un avertissement. Enfin, l'endpoint :
1@app.post(
2 "/query",
3 response_model=QueryResponse,
4 summary="Poser une question",
5 description="Exécute une requête RAG et renvoie une réponse avec ses sources"
6)
7async def query(request: QueryRequest) -> QueryResponse:
8 """
9 Endpoint pour poser des questions au système RAG.
10
11 - **question** : Question en langage naturel
12 - **top_k** : Nombre de documents à rechercher
13 """
14 passsummary et description apparaissent dans la Swagger UI, tout comme la docstring avec son markdown. Tu n'écris aucun fichier de documentation séparé, le schéma est construit à partir du code, il ne peut donc pas s'éloigner de la réalité.
Mon conseil : écris le README le jour même où tu crées le dépôt, pas à la fin du projet. Une documentation écrite au fil de l'eau est plus courte et plus fidèle. Dans la prochaine leçon, on passe au déploiement.
Souviens-toi : la documentation, c'est le carnet de l'expédition qui permet à la suivante de marcher sur tes traces sans deviner.
Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Quel format les docstrings Python utilisent-elles le plus souvent ?
2. Quel outil est le plus couramment utilisé pour documenter une API REST ?
Tâches pratiques dans le jeu
- Éditeur de code
Écris une docstring Python pour une classe avec une description des paramètres et des méthodes
- Tri vertical
Range les éléments de la documentation d'un projet du plus important au moins important :
- Tri horizontal
Range les sections de base d'un README.md dans le bon ordre :