From c0d2f66081fa322dc7a7c1657f9efb8fd804440d Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 25 Jul 2024 10:55:30 +0200 Subject: [PATCH] Doc API: template + fix _ vs - --- app/templates/doc/ScoDoc9API.j2 | 280 ++++++++++++++++++++++++++++++++ tools/create_api_map.py | 4 +- 2 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 app/templates/doc/ScoDoc9API.j2 diff --git a/app/templates/doc/ScoDoc9API.j2 b/app/templates/doc/ScoDoc9API.j2 new file mode 100644 index 00000000..102c00e4 --- /dev/null +++ b/app/templates/doc/ScoDoc9API.j2 @@ -0,0 +1,280 @@ +{# Documentation de l'API ScoDoc 9 #} +# API pour ScoDoc 9 + +!!! warning "Attention" + *Page générée par la commande `flask gen-api-doc`. Ne pas modifier manuellement.* + + +L'API ScoDoc permet à des applications tierces d'interroger ScoDoc. Elle offre +un accès aux objets de l'application via une API REST. + +Les composants internes de ScoDoc, et notamment le schéma de la base de données, +sont susceptibles d'évoluer à tout moment sans préavis: il est vivement +déconseillé d'écrire une extension ne passant pas par l'API. Vous ne devez même +pas supposer qu'il existe une base de données SQL. + +La version ScoDoc 9 a introduit une nouvelle API avec un nouveau mécanisme d'authentification. +**Les clients de l'ancienne API ScoDoc 7 doivent être adaptés pour fonctionner avec ScoDoc 9.** + +Cette API est encore incomplète: n'hésitez pas à demander de nouveaux accès ([contacts](Contact.md)) +(et canal `#API` du Discord développeurs si vous y avez accès). + +L'API fournit des données JSON, sauf exception (bulletins PDF par exemple). + +Les objets ScoDoc manipulables sont identifiés par des id numériques. + +* `etudid` : étudiant +* `formation_id` : un programme de formation (page "programmes"); +* `ue_id` : une UE dans un programme; +* `matiere_id` : une matière dans un programme; +* `module_id` : un module dans un programme; +* `moduleimpl_id` : un module réalisé dans un semestre; +* `formsemestre_id` : un "semestre" de formation. + +(pour plus de précisions, voir le [guide développeurs](GuideDeveloppeurs.md)) + +L'URL complète est de la forme: +`https://scodoc.example.com/ScoDoc/api/`. +( à choisir dans [Référence](#reference)) + +## Configuration de ScoDoc pour utiliser l'API + +Il est nécessaire de disposer d'un compte utilisateur avec les droits adéquats. + +Les droits à accorder dépendent des fonctionnalités nécessaires. la permission +`ScoView` est généralement suffisante car elle permet toutes les consultations. +Cependant si, par l'API, on veut effectuer des opérations de modification ou +encore consulter les comptes utilisateurs, d'autres droits (`ScoChangeGroups`, +`UsersView`, `ScoSuperAdmin`, ...) peuvent être requis. La consultation du +[tableau récapitulatif](#tableau-recapitulatif-des-entrees-de-lapi) ou la ligne +`permission`de chaque entrée vous donnera la permission requise pour chaque +opération. + +En général, il est recommandé de créer un rôle, de lui attribuer les permissions +que l'on veut utiliser, puis de créer un utilisateur ayant ce rôle. + +En ligne de commande, cela peut se faire comme suit (voir détail des commandes +[sur le guide de configuration](GuideConfig.md)). + +```bash +# se connecter comme utilisateur scodoc +su - scodoc + +# Créer un rôle +flask create-role LecteurAPI +# Lui donner les droits nécessaires: ici ScoView +flask edit-role LecteurAPI -a ScoView + +# Créer un nouvel utilisateur avec ce rôle: +flask user-create lecteur_api LecteurAPI @all + +# Ou bien, si on veut utiliser un compte existant: +# associer notre rôle à un utilisateur +flask user-role lecteur_api -a LecteurAPI + + +# Au besoin, changer le mot de passe de l'utilisateur +# (on aura besoin de ce mot de passe dans la configuration du client d'API) +flask user-password lecteur_api +... +``` + +Si vous êtes intéressé par le développement, voir + +* [la section sur les tests unitaires de l'API](TestsScoDoc.md#tests-de-lapi-scodoc9); +* [la documentation développeurs](GuideDeveloppeurs.md) et sur les [vues de l'API](DevInternals.md#vues-de-lapi-et-permissions). + +!!! note + + * Si vous utilisez le CAS, pensez à laisser les comptes utilisateurs API se + connecter via ScoDoc sans CAS. Pour cela, cocher l'option + *Autorise connexion via CAS si CAS est activé* + dans leur formulaire de configuration. + + * Si l'utilisateur est associé à un département (cas des comptes créés via l'interface Web), + il ne pourra accéder à l'API que via une *route départementale*, c'est à dire une route comprenant + l'acronyme de son département, de la forme `https://...//ScoDoc/DEPARTEMENT/api/...`. + +## Essais avec HTTPie + +[HTTPie](https://httpie.io/) est un client universel livre et gratuit très commode, disponible +pour Windows, Linux, en ligne de commande ou interface graphique. + +Exemple d'utilisation en ligne de commande et interroger votre ScoDoc pour +obtenir la liste des départements: + +```bash +http -a USER:PASSWORD POST 'http://localhost:5000/ScoDoc/api/tokens' +``` + +Qui affiche: + +```text +HTTP/1.1 200 OK +Content-Length: 50 +Content-Type: application/json +Date: Thu, 05 May 2022 04:29:33 GMT + +{ + "token": "jS7iVl1234cRDzboAfO5xseE0Ain6Zyz" +} +``` + +(remplacer `USER:PASSWORD` par les identifiants de votre utilisateur et adapter +l'URL qui est ici celle d'un client local sur le serveur de test). + +Avec ce jeton (*token*), on peut interroger le serveur: + +```bash +http GET http://localhost:5000/ScoDoc/api/departements "Authorization:Bearer jS7iVlH1234cRDzboAfO5xseE0Ain6Zyz" +``` + +qui affiche par exemple: + +```text +HTTP/1.1 200 OK +Content-Length: 151 +Content-Type: application/json +Date: Thu, 05 May 2022 05:21:33 GMT + +[ + { + "acronym": "TAPI", + "date_creation": "Wed, 04 May 2022 21:09:25 GMT", + "description": null, + "id": 1, + "visible": true + } +] +``` + +## Fonctions d'API ScoDoc 9 + +La documentation ci-dessous concerne la nouvelle API, disponible à partir de la +version de ScoDoc 9.3.25. + +### Accès à l'API REST + +L'API est accessible à l'adresse: +`https://scodoc.monsite.tld/ScoDoc/api/`, et aussi via les *routes +départementales* de la forme +`https://scodoc.monsite.tld/ScoDoc//api/` pour un accès +avec des droits restreints au département indiqué. La liste des `` est +donnée ci-dessous dans [Référence](#reference). + +#### Authentification + +Lors de votre authentification (*connexion avec login et mot de passe*) à Scodoc, il +vous sera attribué un jeton (token jwt *généré automatiquement*) vous permettant +d'utiliser l'api suivant les droits correspondant à votre session. + +Pour obtenir le jeton, il faut un compte sur ScoDoc (`user_name`et `password`). +Les autorisations et rôles sont gérés exactement comme pour l'application. + +Exemple avec `curl` (un outil en ligne de commande présent sur la plupart des +systèmes, voir plus haut pour la même chose avec la commande `http`): + +```bash +curl -u user_name:password --request POST https://SERVEUR/ScoDoc/api/tokens +``` + +où `SERVEUR` est l'adresse (IP ou nom) de votre serveur. +La réponse doit ressembler à ceci: + +```json +{ + "token": "LuXXxk+i74TXYZZl8MulgbiCGmVHXXX" +} +``` + +Vous trouverez dans `/opt/scodoc/tests/api/exemple-api-basic.py` un exemple +complet en python d'interrogation de l'API. + +#### Codes HTTP + +Chaque appel à l'API donne lieu à une réponse retournant un code spécifique en +fonction du résultat obtenu. L'analyse de ce code vous permet de vous assurer +que la requête a été traitée avec succès. + +Tous les codes >= 400 indiquent que la requête n'a pas été traitée avec succès +par le serveur ScoDoc. + +* [200](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/200) : OK. +* [401](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/401) : Authentification nécessaire. (jeton non précisé ou invalide) +* [403](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/403) : Action + non autorisée pour l'utilisateur associé au jeton. +* [404](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/401) : Adresse + incorrecte, paramètre manquant ou invalide, ou objet inexistant. +* [500](https://developer.mozilla.org/fr/docs/Web/HTTP/Status/500) : Erreur + inconnue côté serveur. + +## Règles générales + +* une route s'écrit comme une suite de noms et d'identifiants; +* les noms token, département, formation, formsemestre, groupe, etudiant, + bulletin, absence, logo, programme, évaluation, résultat, décision désignent + des types d'objets; +* les noms (verbes ou groupes verbaux): set_etudiant, remove_etudiant, query, + create, delete, edit, order sont des actions; +* les noms restants (ids, courants, long, ...) sont des options, les autres noms + sont des options ou des actions; +* le dernier nom apparaissant sur une route donne le type d'objet renvoyé. Ce + nom peut apparaître au singulier ou au pluriel. + * au singulier un seul objet est renvoyé, si aucun objet n'est trouvé, retourne un 404; + * au pluriel une collection d'objets est renvoyée, si aucun objet n'est + trouvé, retourne une collection vide. +* un type d'objet au singulier est généralement suivi immédiatement de son + identifiant (unique). Exception: pour un étudiant, on peut également utiliser + le NIP ou l'INE (qui ne sont pas uniques dans la base car un étudiant de même + INE/NIP peut passer par plusieurs départements). + +## Référence + +La [carte syntaxique](#carte-syntaxique) vous permet de retrouver une entrée à +partir de sa syntaxe (le `?` amène sur la documentation associée). + +Le [tableau récapitulatif](#tableau-recapitulatif-des-entrees-de-lapi) vous +permet de rechercher une entrée à partir du résultat attendu. + +### Carte syntaxique + +
+
+ ![carte_syntaxique](img/API_Chart.svg) +
+
+ +(carte générée avec `flask gen-api-map -e "api."`) + +### Tableau récapitulatif des entrées de l'API + +{{table_api|safe}} + +(table générée avec `flask gen-api-map -e "api."`) + +#### Note sur les exemples d'utilisation + +Pour uniformiser les résultats des exemples, ceux sont soumis à quelques post-traitements non réalisés par l'API. + +- les clés sont triées (ce n'est pas toujours garanti); +- les listes de plus de 2 éléments sont tronquées à 2 éléments, la fin de la liste étant + représentée par la notation en json '...'; +- les dates (au format ISO) sont systématiquement remplacées par une date fixe et ne sont pas réalistes. + +{{doc_api|safe}} + + +--------------------------------------------------------------------------------------------------------------------- + +### En savoir plus + +Voir exemples d'utilisation de l'API en Python, dans `tests/api/`. + + +!!! note "Voir aussi" + + - [Guide configuration et ligne de commande](GuideConfig.md) + - [Guide administrateur ScoDoc](GuideAdminSys.md) + - [ServicesXml](ServicesXml.md) : anciens web services XML (obsolète) + - [FAQ](FAQ.md) + - [Contacts](Contact.md) diff --git a/tools/create_api_map.py b/tools/create_api_map.py index fdc798d8..1bd65df6 100644 --- a/tools/create_api_map.py +++ b/tools/create_api_map.py @@ -136,7 +136,7 @@ class Token: element, x_offset, y_offset ) # Préparation du lien vers la doc de la route - href = "#" + self.func_name.replace("_", "-") + href = "#" + self.func_name if self.query and not href.endswith("-query"): href += "-query" question_mark_group = _create_question_mark_group(current_end_coords, href) @@ -505,7 +505,7 @@ def analyze_api_routes(app, endpoint_start: str) -> tuple: # Gestion de doctable doctable = parse_doctable_doc(func.__doc__ or "") - href = func_name.replace("_", "-") + href = func_name if child.query and not href.endswith("-query"): href += "-query"