Compare commits

...

2 Commits

Author SHA1 Message Date
Iziram
c12bc778bb Maj Markdown docstring assiduites + justificatifs 2024-07-24 11:07:57 +02:00
Iziram
17233fb8c1 APIDoc utilisation template jinja + lien samples 2024-07-24 10:38:56 +02:00
4 changed files with 195 additions and 205 deletions

View File

@ -58,9 +58,9 @@ def assiduite(assiduite_id: int = None):
"date_fin": "2022-10-31T10:00+01:00",
"etat": "retard",
"desc": "une description",
"user_id: 1 or null,
"user_name" : login scodoc or null
"user_nom_complet": "Marie Dupont"
"user_id": 1 or null,
"user_name" : login scodoc or null,
"user_nom_complet": "Marie Dupont",
"est_just": False or True,
}
```
@ -132,42 +132,6 @@ def assiduites_count(
"""
Retourne le nombre d'assiduités d'un étudiant.
Un filtrage peut être donné avec une `query`.
Les différents filtres :
- Type (type de comptage -> journee, demi, heure, nombre d'assiduite):
query?type=(journee, demi, heure) -> une seule valeur parmis les trois
ex: .../query?type=heure
Comportement par défaut : compte le nombre d'assiduité enregistrée
- Etat (etat de l'étudiant -> absent, present ou retard):
`query?etat=[- liste des états séparé par une virgule -]`
ex: .../query?etat=present,retard
- Date debut
(date de début de l'assiduité, sont affichés les assiduités
dont la date de début est supérieur ou égale à la valeur donnée):
query?date_debut=[- date au format iso -]
ex: query?date_debut=2022-11-03T08:00+01:00
Date fin
(date de fin de l'assiduité, sont affichés les assiduités
dont la date de fin est inférieure ou égale à la valeur donnée):
query?date_fin=[- date au format iso -]
ex: query?date_fin=2022-11-03T10:00+01:00
Moduleimpl_id (l'id du module concerné par l'assiduité):
query?moduleimpl_id=[- int ou vide -]
ex: query?moduleimpl_id=1234
query?moduleimpl_od=
Formsemstre_id (l'id du formsemestre concerné par l'assiduité)
query?formsemestre_id=[int]
ex query?formsemestre_id=3
user_id (l'id de l'auteur de l'assiduité)
query?user_id=[int]
ex query?user_id=3
est_just (si l'assiduité est justifié (fait aussi filtre par abs/retard))
query?est_just=[bool]
query?est_just=f
query?est_just=t
QUERY
-----
user_id:<int:user_id>
@ -180,6 +144,18 @@ def assiduites_count(
metric:<array[string]:metric>
split:<bool:split>
PARAMS
-----
user_id:l'id de l'auteur de l'assiduité
est_just:si l'assiduité est justifiée (fait aussi filtre abs/retard)
moduleimpl_id:l'id du module concerné par l'assiduité
date_debut:date de début de l'assiduité (supérieur ou égal)
date_fin:date de fin de l'assiduité (inférieur ou égal)
etat:etat de l'étudiant &rightarrow; absent, present ou retard
formsemestre_id:l'identifiant du formsemestre concerné par l'assiduité
metric: la/les métriques de comptage (journee, demi, heure, compte)
split: divise le comptage par état
"""
# Récupération de l'étudiant
@ -235,39 +211,6 @@ def assiduites_count(
def assiduites(etudid: int = None, nip=None, ine=None, with_query: bool = False):
"""
Retourne toutes les assiduités d'un étudiant
chemin : /assiduites/<int:etudid>
Un filtrage peut être donné avec une query
chemin : /assiduites/<int:etudid>/query?
Les différents filtres :
Etat (etat de l'étudiant -> absent, present ou retard):
query?etat=[- liste des états séparé par une virgule -]
ex: .../query?etat=present,retard
Date debut
(date de début de l'assiduité, sont affichés les assiduités
dont la date de début est supérieur ou égale à la valeur donnée):
query?date_debut=[- date au format iso -]
ex: query?date_debut=2022-11-03T08:00+01:00
Date fin
(date de fin de l'assiduité, sont affichés les assiduités
dont la date de fin est inférieure ou égale à la valeur donnée):
query?date_fin=[- date au format iso -]
ex: query?date_fin=2022-11-03T10:00+01:00
Moduleimpl_id (l'id du module concerné par l'assiduité):
query?moduleimpl_id=[- int ou vide -]
ex: query?moduleimpl_id=1234
query?moduleimpl_od=
Formsemstre_id (l'id du formsemestre concerné par l'assiduité)
query?formsemstre_id=[int]
ex query?formsemestre_id=3
user_id (l'id de l'auteur de l'assiduité)
query?user_id=[int]
ex query?user_id=3
est_just (si l'assiduité est justifié (fait aussi filtre par abs/retard))
query?est_just=[bool]
query?est_just=f
query?est_just=t
QUERY
-----
@ -279,6 +222,16 @@ def assiduites(etudid: int = None, nip=None, ine=None, with_query: bool = False)
etat:<array[string]:etat>
formsemestre_id:<int:formsemestre_id>
PARAMS
-----
user_id:l'id de l'auteur de l'assiduité
est_just:si l'assiduité est justifiée (fait aussi filtre abs/retard)
moduleimpl_id:l'id du module concerné par l'assiduité
date_debut:date de début de l'assiduité (supérieur ou égal)
date_fin:date de fin de l'assiduité (inférieur ou égal)
etat:etat de l'étudiant &rightarrow; absent, present ou retard
formsemestre_id:l'identifiant du formsemestre concerné par l'assiduité
"""
# Récupération de l'étudiant
@ -333,7 +286,9 @@ def assiduites_evaluations(etudid: int = None, nip=None, ine=None):
Pour chaque évaluation, retourne la liste des objets assiduités
sur la plage de l'évaluation
Présentation du retour :
Exemple de résultat:
```json
[
{
"evaluation_id": 1234,
@ -345,6 +300,7 @@ def assiduites_evaluations(etudid: int = None, nip=None, ine=None):
]
}
]
```
"""
# Récupération de l'étudiant
@ -372,7 +328,10 @@ def assiduites_evaluations(etudid: int = None, nip=None, ine=None):
def evaluation_assiduites(evaluation_id):
"""
Retourne les objets assiduités de chaque étudiant sur la plage de l'évaluation
Présentation du retour :
Exemple de résultat:
```json
{
"<etudid>" : [
{
@ -381,6 +340,7 @@ def evaluation_assiduites(evaluation_id):
},
]
}
```
"""
# Récupération de l'évaluation
try:
@ -409,37 +369,6 @@ def assiduites_group(with_query: bool = False):
Retourne toutes les assiduités d'un groupe d'étudiants
chemin : /assiduites/group/query?etudids=1,2,3
Un filtrage peut être donné avec une query
chemin : /assiduites/group/query?etudids=1,2,3
Les différents filtres :
Etat (etat de l'étudiant -> absent, present ou retard):
query?etat=[- liste des états séparé par une virgule -]
ex: .../query?etat=present,retard
Date debut
(date de début de l'assiduité, sont affichés les assiduités
dont la date de début est supérieur ou égale à la valeur donnée):
query?date_debut=[- date au format iso -]
ex: query?date_debut=2022-11-03T08:00+01:00
Date fin
(date de fin de l'assiduité, sont affichés les assiduités
dont la date de fin est inférieure ou égale à la valeur donnée):
query?date_fin=[- date au format iso -]
ex: query?date_fin=2022-11-03T10:00+01:00
Moduleimpl_id (l'id du module concerné par l'assiduité):
query?moduleimpl_id=[- int ou vide -]
ex: query?moduleimpl_id=1234
query?moduleimpl_od=
Formsemstre_id (l'id du formsemestre concerné par l'assiduité)
query?formsemstre_id=[int]
ex query?formsemestre_id=3
user_id (l'id de l'auteur de l'assiduité)
query?user_id=[int]
ex query?user_id=3
est_just (si l'assiduité est justifié (fait aussi filtre par abs/retard))
query?est_just=[bool]
query?est_just=f
query?est_just=t
QUERY
-----
@ -449,9 +378,20 @@ def assiduites_group(with_query: bool = False):
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
etudids:<array[int]:etudids
etudids:<array[int]:etudids>
formsemestre_id:<int:formsemestre_id>
PARAMS
-----
user_id:l'id de l'auteur de l'assiduité
est_just:si l'assiduité est justifiée (fait aussi filtre abs/retard)
moduleimpl_id:l'id du module concerné par l'assiduité
date_debut:date de début de l'assiduité (supérieur ou égal)
date_fin:date de fin de l'assiduité (inférieur ou égal)
etat:etat de l'étudiant &rightarrow; absent, present ou retard
etudids:liste des ids des étudiants concernés par la recherche
formsemestre_id:l'identifiant du formsemestre concerné par l'assiduité
"""
# Récupération des étudiants dans la requête
@ -511,6 +451,7 @@ def assiduites_group(with_query: bool = False):
@permission_required(Permission.ScoView)
def assiduites_formsemestre(formsemestre_id: int, with_query: bool = False):
"""Retourne toutes les assiduités du formsemestre
QUERY
-----
user_id:<int:user_id>
@ -519,6 +460,16 @@ def assiduites_formsemestre(formsemestre_id: int, with_query: bool = False):
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
PARAMS
-----
user_id:l'id de l'auteur de l'assiduité
est_just:si l'assiduité est justifiée (fait aussi filtre abs/retard)
moduleimpl_id:l'id du module concerné par l'assiduité
date_debut:date de début de l'assiduité (supérieur ou égal)
date_fin:date de fin de l'assiduité (inférieur ou égal)
etat:etat de l'étudiant &rightarrow; absent, present ou retard
formsemestre_id:l'identifiant du formsemestre concerné par l'assiduité
"""
# Récupération du formsemestre à partir du formsemestre_id
@ -582,6 +533,18 @@ def assiduites_formsemestre_count(
formsemestre_id:<int:formsemestre_id>
metric:<array[string]:metric>
split:<bool:split>
PARAMS
-----
user_id:l'id de l'auteur de l'assiduité
est_just:si l'assiduité est justifiée (fait aussi filtre abs/retard)
moduleimpl_id:l'id du module concerné par l'assiduité
date_debut:date de début de l'assiduité (supérieur ou égal)
date_fin:date de fin de l'assiduité (inférieur ou égal)
etat:etat de l'étudiant &rightarrow; absent, present ou retard
formsemestre_id:l'identifiant du formsemestre concerné par l'assiduité
metric: la/les métriques de comptage (journee, demi, heure, compte)
split: divise le comptage par état
"""
# Récupération du formsemestre à partir du formsemestre_id
@ -633,7 +596,10 @@ def assiduites_formsemestre_count(
def assiduite_create(etudid: int = None, nip=None, ine=None):
"""
Enregistrement d'assiduités pour un étudiant (etudid)
La requête doit avoir un content type "application/json":
DATA
----
```json
[
{
"date_debut": str,
@ -649,6 +615,7 @@ def assiduite_create(etudid: int = None, nip=None, ine=None):
}
...
]
```
"""
# Récupération de l'étudiant
@ -702,7 +669,10 @@ def assiduite_create(etudid: int = None, nip=None, ine=None):
def assiduites_create():
"""
Création d'une assiduité ou plusieurs assiduites
La requête doit avoir un content type "application/json":
DATA
----
```json
[
{
"date_debut": str,
@ -715,12 +685,12 @@ def assiduites_create():
"date_fin": str,
"etat": str,
"etudid":int,
"moduleimpl_id": int,
"desc":str,
}
...
]
```
"""
@ -891,13 +861,14 @@ def assiduite_delete():
"""
Suppression d'une assiduité à partir de son id
Forme des données envoyées :
DATA
----
```json
[
<assiduite_id:int>,
...
]
```
"""
# Récupération des ids envoyés dans la liste
@ -972,13 +943,17 @@ def _delete_one(assiduite_id: int) -> tuple[int, str]:
def assiduite_edit(assiduite_id: int):
"""
Edition d'une assiduité à partir de son id
La requête doit avoir un content type "application/json":
DATA
----
```json
{
"etat"?: str,
"moduleimpl_id"?: int
"desc"?: str
"est_just"?: bool
}
```
"""
# Récupération de l'assiduité à modifier
@ -1020,7 +995,10 @@ def assiduite_edit(assiduite_id: int):
def assiduites_edit():
"""
Edition de plusieurs assiduités
La requête doit avoir un content type "application/json":
DATA
----
```json
[
{
"assiduite_id" : int,
@ -1030,6 +1008,7 @@ def assiduites_edit():
"est_just"?: bool
}
]
```
"""
edit_list: list[object] = request.get_json(force=True)

View File

@ -92,38 +92,26 @@ def justificatif(justif_id: int = None):
def justificatifs(etudid: int = None, nip=None, ine=None, with_query: bool = False):
"""
Retourne toutes les assiduités d'un étudiant
chemin : /justificatifs/<int:etudid>
Un filtrage peut être donné avec une query
chemin : /justificatifs/<int:etudid>/query?
Les différents filtres :
Etat (etat du justificatif -> validé, non validé, modifé, en attente):
query?etat=[- liste des états séparé par une virgule -]
ex: .../query?etat=validé,modifié
Date debut
(date de début du justificatif, sont affichés les justificatifs
dont la date de début est supérieur ou égale à la valeur donnée):
query?date_debut=[- date au format iso -]
ex: query?date_debut=2022-11-03T08:00+01:00
Date fin
(date de fin du justificatif, sont affichés les justificatifs
dont la date de fin est inférieure ou égale à la valeur donnée):
query?date_fin=[- date au format iso -]
ex: query?date_fin=2022-11-03T10:00+01:00
user_id (l'id de l'auteur du justificatif)
query?user_id=[int]
ex query?user_id=3
QUERY
-----
user_id:<int:user_id>
est_just:<bool:est_just>
date_debut:<string:date_debut_iso>
date_fin:<string:date_fin_iso>
etat:<array[string]:etat>
order:<bool:order>
courant:<bool:courant>
group_id:<int:group_id>
PARAMS
-----
user_id:l'id de l'auteur du justificatif
date_debut:date de début du justificatif (supérieur ou égal)
date_fin:date de fin du justificatif (inférieur ou égal)
etat:etat du justificatif &rightarrow; valide, non_valide, attente, modifie
order:retourne les justificatifs dans l'ordre décroissant (non vide = True)
courant:retourne les justificatifs de l'année courante (bool : v/t ou f)
group_id:<int:group_id>
"""
# Récupération de l'étudiant
etud: Identite = tools.get_etud(etudid, nip, ine)
@ -176,6 +164,16 @@ def justificatifs_dept(dept_id: int = None, with_query: bool = False):
order:<bool:order>
courant:<bool:courant>
group_id:<int:group_id>
PARAMS
-----
user_id:l'id de l'auteur du justificatif
date_debut:date de début du justificatif (supérieur ou égal)
date_fin:date de fin du justificatif (inférieur ou égal)
etat:etat du justificatif &rightarrow; valide, non_valide, attente, modifie
order:retourne les justificatifs dans l'ordre décroissant (non vide = True)
courant:retourne les justificatifs de l'année courante (bool : v/t ou f)
group_id:<int:group_id>
"""
# Récupération du département et des étudiants du département
@ -259,6 +257,16 @@ def justificatifs_formsemestre(formsemestre_id: int, with_query: bool = False):
order:<bool:order>
courant:<bool:courant>
group_id:<int:group_id>
PARAMS
-----
user_id:l'id de l'auteur du justificatif
date_debut:date de début du justificatif (supérieur ou égal)
date_fin:date de fin du justificatif (inférieur ou égal)
etat:etat du justificatif &rightarrow; valide, non_valide, attente, modifie
order:retourne les justificatifs dans l'ordre décroissant (non vide = True)
courant:retourne les justificatifs de l'année courante (bool : v/t ou f)
group_id:<int:group_id>
"""
# Récupération du formsemestre
@ -307,7 +315,10 @@ def justificatifs_formsemestre(formsemestre_id: int, with_query: bool = False):
def justif_create(etudid: int = None, nip=None, ine=None):
"""
Création d'un justificatif pour l'étudiant (etudid)
La requête doit avoir un content type "application/json":
DATA
----
```json
[
{
"date_debut": str,
@ -322,6 +333,7 @@ def justif_create(etudid: int = None, nip=None, ine=None):
}
...
]
```
"""
@ -452,14 +464,17 @@ def _create_one(
def justif_edit(justif_id: int):
"""
Edition d'un justificatif à partir de son id
La requête doit avoir un content type "application/json":
DATA
----
```json
{
"etat"?: str,
"raison"?: str
"date_debut"?: str
"date_fin"?: str
}
```
"""
# Récupération du justificatif à modifier
@ -566,14 +581,14 @@ def justif_delete():
"""
Suppression d'un justificatif à partir de son id
Forme des données envoyées :
DATA
----
```json
[
<justif_id:int>,
...
]
```
"""
# Récupération des justif_ids
@ -648,6 +663,8 @@ def _delete_one(justif_id: int) -> tuple[int, str]:
def justif_import(justif_id: int = None):
"""
Importation d'un fichier (création d'archive)
> Procédure d'importation de fichier : [importer un justificatif](FichiersJustificatifs.md#importer-un-fichier)
"""
# On vérifie qu'un fichier a bien été envoyé
@ -699,6 +716,8 @@ def justif_export(justif_id: int | None = None, filename: str | None = None):
"""
Retourne un fichier d'une archive d'un justificatif.
La permission est ScoView + (AbsJustifView ou être l'auteur du justifcatif)
> Procédure de téléchargement de fichier : [télécharger un justificatif](FichiersJustificatifs.md#télécharger-un-fichier)
"""
# On récupère le justificatif concerné
justificatif_unique = Justificatif.get_justificatif(justif_id)
@ -736,14 +755,20 @@ def justif_export(justif_id: int | None = None, filename: str | None = None):
def justif_remove(justif_id: int = None):
"""
Supression d'un fichier ou d'une archive
{
"remove": <"all"/"list">
> Procédure de suppression de fichier : [supprimer un justificatif](FichiersJustificatifs.md#supprimer-un-fichier)
DATA
----
```json
{
"remove": <"all"/"list">,
"filenames"?: [
<filename:str>,
...
]
}
```
"""
# On récupère le dictionnaire

31
app/templates/apidoc.j2 Normal file
View File

@ -0,0 +1,31 @@
#### **`{{doc.nom}}`**
{% if doc.routes %}
{% if doc.routes|length == 1 %}
* **Route:** `{{doc.routes[0]|safe}}`
{% else %}
* **Routes:**
{% for route in doc.routes %}
* `{{route|safe}}`
{% endfor %}
{% endif %}
{% endif %}
* **Méthode:** `{{doc.method}}`
* **Permission:** `{{doc.permission}}`
{% if doc.params %}
* **Paramètres:**
{% for param in doc.params %}
* `{{param.nom|safe}}` : {{param.description|safe}}
{% endfor %}
{% endif %}
{% if doc.description %}
* **Description:** {{doc.description|safe}}
{% endif %}
{% if doc.data %}
* **Data:** {{doc.data|safe}}
{% endif %}
{% if doc.sample %}
* **Exemple de résultat:** [{{doc.sample.nom}}](./samples/sample_{{doc.sample.href}})
{% else %}
{% endif %}

View File

@ -8,6 +8,7 @@ import xml.etree.ElementTree as ET
import re
from app.auth.models import Permission
from flask import render_template
class COLORS:
@ -870,79 +871,33 @@ def _write_gen_table(table: str, filename: str = "/tmp/api_table.md"):
)
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"
# child2 = Token("count")
# child22 = Token("all")
# child23 = Token(
# "query",
# query={
# "etat": "<string:etat>",
# "moduleimpl_id": "<int:moduleimpl_id>",
# "count": "<int:count>",
# "formsemestre_id": "<int:formsemestre_id>",
# },
# )
# child3 = Token("justificatifs", "POST")
# child3.func_name = "justificatifs_post"
# root.add_child(child1)
# child1.add_child(child2)
# child2.add_child(child22)
# child2.add_child(child23)
# root.add_child(child3)
# group_element = root.to_svg_group()
# generate_svg(group_element, "/tmp/api_map.svg")
dt: dict = parse_doctable_doc(parse_doctable_doc.__doc__)
md: str = "POST"
hf: str = "assiduites-query"
doc: dict = {
"doctable": dt,
"method": md,
"href": hf,
}
print(_gen_table([doc]))
def doc_route(doctable: dict) -> str:
"""Generate markdown doc for a route"""
doc = f"""
#### **`{doctable['nom']}`**
jinja_obj: dict = {}
jinja_obj.update(doctable)
jinja_obj["nom"] = doctable["nom"].strip() # on retire les caractères blancs
"""
if doctable.get("routes"):
if len(doctable["routes"]) == 1:
doc += f"""* ** Route :** `{doctable["routes"][0]}`\n"""
else:
doc += "* ** Routes :**\n"
for route in doctable["routes"]:
doc += f""" * `{route}`\n"""
doc += f"""* **Méthode: {doctable['method']}**
* **Permission: `{doctable.get('permission', '')}`**
"""
if doctable.get("params"):
jinja_obj["params"] = []
for param in doctable["params"]:
frags = param.split(":", maxsplit=1)
if len(frags) == 2:
name, descr = frags
jinja_obj["params"].append(
{"nom": name.strip(), "description": descr.strip()}
)
else:
print(f"Warning: {doctable['nom']} : invalid PARAMS {param}")
name, descr = param, ""
doc += f""" * `{name}`: {descr}\n"""
if doctable.get("data"):
doc += f"""* **Data:** {doctable['data']}\n"""
if doctable.get("description"):
descr = "\n".join(s for s in doctable["description"])
doc += f"""* **Description:** {descr}\n"""
return doc
jinja_obj["description"] = descr.strip()
jinja_obj["sample"] = {
"nom": f"{jinja_obj['nom']}.json",
"href": f"{jinja_obj['nom'].replace('_', '-')}.json.md",
}
return render_template("apidoc.j2", doc=jinja_obj)
def gen_api_doc(app, endpoint_start="api."):