diff --git a/scodoc.py b/scodoc.py
index 148916875f3442fc1306f8aaf19297bbd4b448b6..2e2f06d888c4712c49487873259150212c4564a7 100755
--- a/scodoc.py
+++ b/scodoc.py
@@ -724,7 +724,13 @@ def generate_ens_calendars():  # generate-ens-calendars
 
 
 @app.cli.command()
+@click.option(
+    "-e",
+    "--endpoint",
+    default="api",
+    help="Endpoint à partir duquel générer la carte des routes",
+)
 @with_appcontext
-def gen_api_map():
-    """Show the API map"""
-    tools.gen_api_map(app)
+def gen_api_map(endpoint):
+    """Génère la carte des routes de l'API."""
+    tools.gen_api_map(app, endpoint_start=endpoint)
diff --git a/tools/create_api_map.py b/tools/create_api_map.py
index f0383e66a913b21b65af49c8c4d42a4766edbc5d..953f384a6ea8df3ac0b2cb7b249a74e0fabcfd3e 100644
--- a/tools/create_api_map.py
+++ b/tools/create_api_map.py
@@ -1,15 +1,48 @@
+"""
+Script permettant de générer une carte SVG de l'API de ScoDoc
+
+Écrit par Matthias HARTMANN
+"""
+
 import xml.etree.ElementTree as ET
 import re
 
 
 class COLORS:
-    BLUE = "rgb(114,159,207)"
-    GREEN = "rgb(165,214,165)"
-    PINK = "rgb(230,156,190)"
-    GREY = "rgb(224,224,224)"
+    """
+    Couleurs utilisées pour les éléments de la carte
+    """
+
+    BLUE = "rgb(114,159,207)"  # Couleur de base / élément simple
+    GREEN = "rgb(165,214,165)"  # Couleur route GET / valeur query
+    PINK = "rgb(230,156,190)"  # Couleur route POST
+    GREY = "rgb(224,224,224)"  # Couleur séparateur
 
 
 class Token:
+    """
+    Classe permettant de représenter un élément de l'API
+    Exemple :
+
+    /ScoDoc/api/test
+
+    Token(ScoDoc)-> Token(api) -> Token(test)
+
+    Chaque token peut avoir des enfants (Token) et des paramètres de query
+    Chaque token dispose
+        d'un nom (texte écrit dans le rectangle),
+        d'une méthode (GET ou POST) par défaut GET,
+        d'une func_name (nom de la fonction associée à ce token)
+        [OPTIONNEL] d'une query (dictionnaire {param: <type:nom_param>})
+
+    Un token est une leaf si il n'a pas d'enfants.
+        Une LEAF possède un `?` renvoyant vers la doc de la route
+
+    Il est possible de forcer un token à être une pseudo LEAF en mettant force_leaf=True
+        Une PSEUDO LEAF possède aussi un `?` renvoyant vers la doc de la route
+        tout en ayant des enfants.
+    """
+
     def __init__(self, name, method="GET", query=None, leaf=False):
         self.children: list["Token"] = []
         self.name: str = name
@@ -19,24 +52,42 @@ class Token:
         self.func_name = ""
 
     def add_child(self, child):
+        """
+        Ajoute un enfant à ce token
+        """
         self.children.append(child)
 
     def find_child(self, name):
+        """
+        Renvoie l'enfant portant le nom `name` ou None si aucun enfant ne correspond
+        """
         for child in self.children:
             if child.name == name:
                 return child
         return None
 
     def __repr__(self, level=0):
+        """
+        représentation textuelle simplifiée de l'arbre
+        (ne prend pas en compte les query, les méthodes, les func_name, ...)
+        """
         ret = "\t" * level + f"({self.name})\n"
         for child in self.children:
             ret += child.__repr__(level + 1)
         return ret
 
     def is_leaf(self):
+        """
+        Renvoie True si le token est une leaf, False sinon
+        (i.e. s'il n'a pas d'enfants)
+        (force_leaf n'est pas pris en compte ici)
+        """
         return len(self.children) == 0
 
     def get_height(self, y_step):
+        """
+        Renvoie la hauteur de l'élément en prenant en compte la hauteur de ses enfants
+        """
         # Calculer la hauteur totale des enfants
         children_height = sum(child.get_height(y_step) for child in self.children)
 
@@ -51,14 +102,19 @@ class Token:
 
     def to_svg_group(
         self,
-        x_offset=0,
-        y_offset=0,
-        x_step=150,
-        y_step=50,
-        parent_coords=None,
-        parent_children_nb=0,
+        x_offset: int = 0,
+        y_offset: int = 0,
+        x_step: int = 150,
+        y_step: int = 50,
+        parent_coords: tuple[tuple[int, int], tuple[int, int]] = None,
+        parent_children_nb: int = 0,
     ):
-        group = ET.Element("g")
+        """
+        Transforme un token en un groupe SVG
+        (récursif, appelle la fonction sur ses enfants)
+        """
+
+        group = ET.Element("g")  # groupe principal
         color = COLORS.BLUE
         if self.is_leaf():
             if self.method == "GET":
@@ -66,22 +122,27 @@ class Token:
             elif self.method == "POST":
                 color = COLORS.PINK
 
+        # Création du rectangle avec le nom du token et placement sur la carte
         element = _create_svg_element(self.name, color)
         element.set("transform", f"translate({x_offset}, {y_offset})")
+        group.append(element)
+
+        # On récupère les coordonnées de début et de fin de l'élément pour les flèches
         current_start_coords, current_end_coords = _get_anchor_coords(
             element, x_offset, y_offset
         )
+        # Préparation du lien vers la doc de la route
         href = "#" + self.func_name.replace("_", "-")
         if self.query:
             href += "-query"
         question_mark_group = _create_question_mark_group(current_end_coords, href)
-        group.append(element)
 
-        # Add an arrow from the parent element to the current element
+        # Ajout de la flèche partant du parent jusqu'à l'élément courant
         if parent_coords and parent_children_nb > 1:
             arrow = _create_arrow(parent_coords, current_start_coords)
             group.append(arrow)
 
+        # Ajout du `/` si le token n'est pas une leaf (ne prend pas en compte force_leaf)
         if not self.is_leaf():
             slash_group = _create_svg_element("/", COLORS.GREY)
             slash_group.set(
@@ -89,6 +150,7 @@ class Token:
                 f"translate({x_offset + _get_element_width(element)}, {y_offset})",
             )
             group.append(slash_group)
+        # Ajout du `?` si le token est une leaf et possède une query
         if self.is_leaf() and self.query:
             slash_group = _create_svg_element("?", COLORS.GREY)
             slash_group.set(
@@ -96,17 +158,23 @@ class Token:
                 f"translate({x_offset + _get_element_width(element)}, {y_offset})",
             )
             group.append(slash_group)
+
+        # Actualisation des coordonnées de fin
         current_end_coords = _get_anchor_coords(group, 0, 0)[1]
 
+        # Gestion des éléments de la query
+        # Pour chaque élément on va créer :
+        # (param) (=) (valeur) (&)
         query_y_offset = y_offset
         query_sub_element = ET.Element("g")
         for key, value in self.query.items():
+            # Création d'un sous-groupe pour chaque élément de la query
             sub_group = ET.Element("g")
 
-            # <param>=<value>
+            # On décale l'élément de la query vers la droite par rapport à l'élément parent
             translate_x = x_offset + x_step
 
-            # <param>
+            # création élément (param)
             param_el = _create_svg_element(key, COLORS.BLUE)
             param_el.set(
                 "transform",
@@ -114,15 +182,16 @@ class Token:
             )
             sub_group.append(param_el)
 
-            # add Arrow from "query" to element
+            # Ajout d'une flèche partant de l'élément "query" vers le paramètre courant
             coords = (
                 current_end_coords,
                 _get_anchor_coords(param_el, translate_x, query_y_offset)[0],
             )
             sub_group.append(_create_arrow(*coords))
 
-            # =
+            # création élément (=)
             equal_el = _create_svg_element("=", COLORS.GREY)
+            # On met à jour le décalage en fonction de l'élément précédent
             translate_x = x_offset + x_step + _get_element_width(param_el)
             equal_el.set(
                 "transform",
@@ -130,8 +199,9 @@ class Token:
             )
             sub_group.append(equal_el)
 
-            # <value>
+            # création élément (value)
             value_el = _create_svg_element(value, COLORS.GREEN)
+            # On met à jour le décalage en fonction des éléments précédents
             translate_x = (
                 x_offset
                 + x_step
@@ -142,9 +212,13 @@ class Token:
                 f"translate({translate_x}, {query_y_offset})",
             )
             sub_group.append(value_el)
+            # Si il y a qu'un seul élément dans la query, on ne met pas de `&`
             if len(self.query) == 1:
                 continue
+
+            # création élément (&)
             ampersand_group = _create_svg_element("&", "rgb(224,224,224)")
+            # On met à jour le décalage en fonction des éléments précédents
             translate_x = (
                 x_offset
                 + x_step
@@ -156,17 +230,29 @@ class Token:
             )
             sub_group.append(ampersand_group)
 
+            # On décale le prochain élément de la query vers le bas
             query_y_offset += y_step * 1.33
-
+            # On ajoute le sous-groupe (param = value &) au groupe de la query
             query_sub_element.append(sub_group)
+
+        # On ajoute le groupe de la query à l'élément principal
         group.append(query_sub_element)
 
+        # Gestion des enfants du Token
+
+        # On met à jour les décalages en fonction des éléments précédents
         y_offset = query_y_offset
         current_y_offset = y_offset
+
+        # Pour chaque enfant, on crée un groupe SVG de façon récursive
         for child in self.children:
+            # On décale l'enfant vers la droite par rapport à l'élément parent
+            # Si il n'y a qu'un enfant, alors on colle l'enfant à l'élément parent
             rel_x_offset = x_offset + _get_group_width(group)
             if len(self.children) > 1:
                 rel_x_offset += x_step
+
+            # On crée le groupe SVG de l'enfant
             child_group = child.to_svg_group(
                 rel_x_offset,
                 current_y_offset,
@@ -175,10 +261,12 @@ class Token:
                 parent_coords=current_end_coords,
                 parent_children_nb=len(self.children),
             )
+            # On ajoute le groupe de l'enfant au groupe principal
             group.append(child_group)
+            # On met à jour le décalage Y en fonction de la hauteur de l'enfant
             current_y_offset += child.get_height(y_step)
 
-        # add `?` circle a:href to element
+        # Ajout du `?` si le token est une pseudo leaf ou une leaf
         if self.force_leaf or self.is_leaf():
             group.append(question_mark_group)
 
@@ -186,23 +274,32 @@ class Token:
 
 
 def _create_svg_element(text, color="rgb(230,156,190)"):
-    # Dimensions and styling
+    """
+    Fonction générale pour créer un élément SVG simple
+    (rectangle avec du texte à l'intérieur)
+
+    text : texte à afficher dans l'élément
+    color : couleur de l'élément
+    """
+
+    # Paramètres de style de l'élément
     padding = 5
     font_size = 16
     rect_height = 30
     rect_x = 10
     rect_y = 20
 
-    # Estimate the text width
+    # Estimation de la largeur du texte
     text_width = (
         len(text) * font_size * 0.6
-    )  # Estimate based on average character width
+    )  # On suppose que la largeur d'un caractère est 0.6 * font_size
+    # Largeur du rectangle = Largeur du texte + padding à gauche et à droite
     rect_width = text_width + padding * 2
 
-    # Create the SVG group element
+    # Création du groupe SVG
     group = ET.Element("g")
 
-    # Create the rectangle
+    # Création du rectangle
     ET.SubElement(
         group,
         "rect",
@@ -215,7 +312,7 @@ def _create_svg_element(text, color="rgb(230,156,190)"):
         },
     )
 
-    # Create the text element
+    # Création du texte
     text_element = ET.SubElement(
         group,
         "text",
@@ -223,47 +320,66 @@ def _create_svg_element(text, color="rgb(230,156,190)"):
             "x": str(rect_x + padding),
             "y": str(
                 rect_y + rect_height / 2 + font_size / 2.5
-            ),  # Adjust to vertically center the text
+            ),  # Ajustement pour centrer verticalement
             "font-family": "Courier New, monospace",
             "font-size": str(font_size),
             "fill": "black",
             "style": "white-space: pre;",
         },
     )
+
+    # Ajout du texte à l'élément
     text_element.text = text
 
     return group
 
 
 def _get_anchor_coords(element, x_offset, y_offset):
+    """
+    Récupération des coordonnées des points d'ancrage d'un élément SVG
+    (début et fin de l'élément pour les flèches)
+    (le milieu vertical de l'élément est utilisé pour les flèches)
+    """
     bbox = _get_bbox(element, x_offset, y_offset)
     startX = bbox["x_min"]
     endX = bbox["x_max"]
+    # Milieu vertical de l'élément
     y = bbox["y_min"] + (bbox["y_max"] - bbox["y_min"]) / 2
     return (startX, y), (endX, y)
 
 
 def _create_arrow(start_coords, end_coords):
+    """
+    Création d'une flèche entre deux points
+    """
+    # On récupère les coordonnées de début et de fin de la flèche
     start_x, start_y = start_coords
     end_x, end_y = end_coords
+    # On calcule le milieu horizontal de la flèche
     mid_x = (start_x + end_x) / 2
 
+    # On crée le chemin de la flèche
     path_data = (
         f"M {start_x},{start_y} L {mid_x},{start_y} L {mid_x},{end_y} L {end_x},{end_y}"
     )
-
+    # On crée l'élément path de la flèche
     path = ET.Element(
         "path",
         {
             "d": path_data,
             "style": "stroke:black;stroke-width:2;fill:none",
-            "marker-end": "url(#arrowhead)",
+            "marker-end": "url(#arrowhead)",  # Ajout de la flèche à la fin du path
         },
     )
     return path
 
 
 def _get_element_width(element):
+    """
+    Retourne la largueur d'un élément simple
+    L'élément simple correspond à un rectangle avec du texte à l'intérieur
+    on récupère la largueur du rectangle
+    """
     rect = element.find("rect")
     if rect is not None:
         return float(rect.get("width", 0))
@@ -271,18 +387,27 @@ def _get_element_width(element):
 
 
 def _get_group_width(group):
+    """
+    Récupère la largeur d'un groupe d'éléments
+    on fait la somme des largeurs de chaque élément du groupe
+    """
     return sum(_get_element_width(child) for child in group)
 
 
 def _create_question_mark_group(coords, href):
+    """
+    Création d'un groupe SVG contenant un cercle et un lien vers la doc de la route
+    le `?` renvoie vers la doc de la route
+    """
+    # Récupération du point d'ancrage de l'élément
     x, y = coords
-    radius = 10  # Radius of the circle
+    radius = 10  # Rayon du cercle
     y -= radius * 2
-    font_size = 17  # Font size of the question mark
+    font_size = 17  # Taille de la police
 
     group = ET.Element("g")
 
-    # Create the circle
+    # Création du cercle
     ET.SubElement(
         group,
         "circle",
@@ -296,17 +421,17 @@ def _create_question_mark_group(coords, href):
         },
     )
 
-    # Create the link element
+    # Création du lien (a) vers la doc de la route
     link = ET.Element("a", {"href": href})
 
-    # Create the text element
+    # Création du texte `?`
     text_element = ET.SubElement(
         link,
         "text",
         {
             "x": str(x + 1),
-            "y": str(y + font_size / 3),  # Adjust to vertically center the text
-            "text-anchor": "middle",  # Center the text horizontally
+            "y": str(y + font_size / 3),  # Ajustement pour centrer verticalement
+            "text-anchor": "middle",  # Centrage horizontal
             "font-family": "Arial",
             "font-size": str(font_size),
             "fill": "black",
@@ -319,23 +444,49 @@ def _create_question_mark_group(coords, href):
     return group
 
 
-def gen_api_map(app):
+def gen_api_map(app, endpoint_start="api"):
+    """
+    Fonction permettant de générer une carte SVG de l'API de ScoDoc
+    Elle récupère les routes de l'API et les transforme en un arbre de Token
+    puis génère un fichier SVG à partir de cet arbre
+    """
+    # Création du token racine
     api_map = Token("")
+
+    # Parcours de toutes les routes de l'application
     for rule in app.url_map.iter_rules():
         # On ne garde que les routes de l'API / APIWEB
-        if not rule.endpoint.lower().startswith("api"):
+        if not rule.endpoint.lower().startswith(endpoint_start.lower()):
             continue
 
+        # Transformation de la route en segments
+        # ex : /ScoDoc/api/test -> ["ScoDoc", "api", "test"]
         segments = rule.rule.strip("/").split("/")
+
+        # On positionne le token courant sur le token racine
         current_token = api_map
 
+        # Pour chaque segment de la route
         for i, segment in enumerate(segments):
-            # Check if the segment already exists in the current level
+            # On cherche si le segment est déjà un enfant du token courant
             child = current_token.find_child(segment)
+
+            # Si ce n'est pas le cas on crée un nouveau token et on l'ajoute comme enfant
             if child is None:
                 func = app.view_functions[rule.endpoint]
-                # If it's the last segment
+                # Si c'est le dernier segment, on marque le token comme une leaf
+                # On utilise force_leaf car il est possible que le token ne soit que
+                # momentanément une leaf
+                # ex :
+                #   - /ScoDoc/api/test/ -> ["ScoDoc", "api", "test"]
+                #   - /ScoDoc/api/test/1 -> ["ScoDoc", "api", "test", "1"]
+                # dans le premier cas test est une leaf, dans le deuxième cas test n'est pas une leaf
+                # force_leaf permet de forcer le token à être une leaf même s'il a des enfants
+                # permettant d'afficher le `?` renvoyant vers la doc de la route
+                # car la route peut être utilisée sans forcément la continuer.
+
                 if i == len(segments) - 1:
+                    # Un Token sera query si parse_query_doc retourne un dictionnaire non vide
                     child = Token(
                         segment,
                         leaf=True,
@@ -345,16 +496,18 @@ def gen_api_map(app):
                     child = Token(
                         segment,
                     )
+
+                # On ajoute le token comme enfant du token courant
+                # en donnant la méthode et le nom de la fonction associée
                 child.func_name = func.__name__
                 method: str = "POST" if "POST" in rule.methods else "GET"
                 child.method = method
                 current_token.add_child(child)
-            current_token = child
 
-        # Mark the last segment as a leaf node if it's not already marked
-        if not current_token.is_leaf():
-            current_token.force_leaf = True
+            # On met à jour le token courant pour le prochain segment
+            current_token = child
 
+    # On génère le SVG à partir de l'arbre de Token
     generate_svg(api_map.to_svg_group(), "/tmp/api_map.svg")
     print(
         "La carte a été générée avec succès. "
@@ -363,7 +516,12 @@ def gen_api_map(app):
 
 
 def _get_bbox(element, x_offset=0, y_offset=0):
-    # Helper function to calculate the bounding box of an SVG element
+    """
+    Récupérer les coordonnées de la boîte englobante d'un élément SVG
+    Utilisé pour calculer les coordonnées d'un élément SVG et pour avoir la taille
+    total du SVG
+    """
+    # Initialisation des coordonnées de la boîte englobante
     bbox = {
         "x_min": float("inf"),
         "y_min": float("inf"),
@@ -371,17 +529,26 @@ def _get_bbox(element, x_offset=0, y_offset=0):
         "y_max": float("-inf"),
     }
 
+    # Parcours récursif des enfants de l'élément
     for child in element:
+        # On récupère la transformation (position) de l'enfant
+        # On met les OffSet par défaut à leur valeur donnée en paramètre
         transform = child.get("transform")
         child_x_offset = x_offset
         child_y_offset = y_offset
 
+        # Si la transformation est définie, on récupère les coordonnées de translation
+        # et on les ajoute aux offsets
         if transform:
             translate = transform.replace("translate(", "").replace(")", "").split(",")
             if len(translate) == 2:
                 child_x_offset += float(translate[0])
                 child_y_offset += float(translate[1])
 
+        # On regarde ensuite la boite englobante de l'enfant
+        # On met à jour les coordonnées de la boîte englobante en fonction de l'enfant
+        # x_min, y_min, x_max, y_max.
+
         if child.tag == "rect":
             x = child_x_offset + float(child.get("x", 0))
             y = child_y_offset + float(child.get("y", 0))
@@ -403,10 +570,16 @@ def _get_bbox(element, x_offset=0, y_offset=0):
 
 
 def generate_svg(element, fname):
+    """
+    Génère un fichier SVG à partir d'un élément SVG
+    """
+    # On récupère les dimensions de l'élément racine
     bbox = _get_bbox(element)
-    width = bbox["x_max"] - bbox["x_min"] + 80  # Add some padding
-    height = bbox["y_max"] - bbox["y_min"] + 80  # Add some padding
+    # On définit la taille du SVG en fonction des dimensions de l'élément racine
+    width = bbox["x_max"] - bbox["x_min"] + 80
+    height = bbox["y_max"] - bbox["y_min"] + 80
 
+    # Création de l'élément racine du SVG
     svg = ET.Element(
         "svg",
         {
@@ -417,7 +590,8 @@ def generate_svg(element, fname):
         },
     )
 
-    # Define the marker for the arrowhead
+    # Création du motif de la flèche pour les liens
+    # (définition d'un marqueur pour les flèches)
     defs = ET.SubElement(svg, "defs")
     marker = ET.SubElement(
         defs,
@@ -433,8 +607,10 @@ def generate_svg(element, fname):
     )
     ET.SubElement(marker, "polygon", {"points": "0 0, 10 3.5, 0 7"})
 
+    # Ajout de l'élément principal à l'élément racine
     svg.append(element)
 
+    # Écriture du fichier SVG
     tree = ET.ElementTree(svg)
     tree.write(fname, encoding="utf-8", xml_declaration=True)
 
@@ -454,30 +630,39 @@ def parse_query_doc(doc):
     Dès qu'une ligne ne respecte pas ce format (voir regex dans la fonction), on arrête de parser
     Attention, la ligne ----- doit être collée contre QUERY et contre le premier paramètre
     """
-
+    # Récupérer les lignes de la doc
     lines = [line.strip() for line in doc.split("\n")]
+    # On cherche la ligne "QUERY" et on vérifie que la ligne suivante est "-----"
+    # Si ce n'est pas le cas, on renvoie un dictionnaire vide
     try:
         query_index = lines.index("QUERY")
         if lines[query_index + 1] != "-----":
             return {}
     except ValueError:
         return {}
-
+    # On récupère les lignes de la doc qui correspondent à la query (enfin on espère)
     query_lines = lines[query_index + 2 :]
 
     query = {}
     regex = re.compile(r"^(\w+):(<.+>)$")
     for line in query_lines:
+        # On verifie que la ligne respecte le format attendu
+        # Si ce n'est pas le cas, on arrête de parser
         parts = regex.match(line)
         if not parts:
             break
+        # On récupère le paramètre et son type:nom
         param, type_nom_param = parts.groups()
+        # On ajoute le paramètre au dictionnaire
         query[param] = type_nom_param
 
     return query
 
 
 if __name__ == "__main__":
+    # Exemple d'utilisation de la classe Token
+    # Exemple simple de création d'un arbre de Token
+
     root = Token("api")
     child1 = Token("assiduites", leaf=True)
     child1.func_name = "assiduites_get"