API doc: ameliore script sample + sample evaluation

This commit is contained in:
Emmanuel Viennet 2023-08-28 12:15:53 +02:00
parent 6483110992
commit 0eb00b0919
3 changed files with 159 additions and 143 deletions

View File

@ -20,5 +20,5 @@ ignored-classes=Permission,
# supports qualified module names, as well as Unix pattern matching. # supports qualified module names, as well as Unix pattern matching.
ignored-modules=entreprises ignored-modules=entreprises
good-names=d,e,f,i,j,k,n,nt,t,u,ue,v,x,y,z,H,F good-names=d,df,e,f,i,j,k,n,nt,t,u,ue,v,x,y,z,H,F

View File

@ -5,40 +5,51 @@
"""Construction des fichiers exemples pour la documentation. """Construction des fichiers exemples pour la documentation.
Usage: Usage:
cd /opt/scodoc/tests/api python tests/api/make_samples.py [entry_names]
python make_samples.py [entry_names] python tests/api/make_samples.py -i <filepath> [entrynames]
python make_samples.py -i <filepath> [entrynames]
si entry_names est spécifié, la génération est restreints aux exemples cités. expl: `python make_samples departements departement-formsemestres` Si entry_names est spécifié, la génération est restreinte aux exemples cités.
doit être exécutée immédiatement apres une initialisation de la base pour test API! (car dépendant des identifiants générés lors de la création des objets) Exemple:
cd /opt/scodoc/tests/api python make_samples departements departement-formsemestres
tools/create_database.sh --drop SCODOC_TEST_API && flask db upgrade &&flask sco-db-init --erase && flask init-test-database
Créer éventuellement un fichier `.env` dans /opt/scodoc/tests/api Doit être exécutée immédiatement apres une initialisation de la base pour test API!
avec la config du client API: (car dépendant des identifiants générés lors de la création des objets)
```
SCODOC_URL = "http://localhost:5000/" Modifer le /opt/scodoc/.env pour pointer sur la base test
SCODOC_DATABASE_URI="postgresql:///SCODOC_TEST_API"
puis re-créer cette base
tools/create_database.sh --drop SCODOC_TEST_API
flask db upgrade
flask sco-db-init --erase
flask init-test-database
et lancer le serveur test:
flask run --debug
``` ```
Cet utilitaire prend en donnée le fichier de nom `samples.csv` contenant la description des exemples (séparés par une tabulation (\t), une ligne par exemple) Cet utilitaire prend en argument le fichier de nom `samples.csv` contenant la description
* Le nom de l'exemple donne le nom du fichier généré (nom_exemple => nom_exemple.json.md). plusieurs lignes peuvent partager le même nom. dans ce cas le fichier contiendra chacun des exemples des exemples (séparés par une tabulation (\t), une ligne par exemple)
* Le nom de l'exemple donne le nom du fichier généré (nom_exemple => nom_exemple.json.md).
Plusieurs lignes peuvent partager le même nom. dans ce cas le fichier contiendra
chacun des exemples
* l'url utilisée * l'url utilisée
* la permission nécessaire (par défaut ScoView) * la permission nécessaire (par défaut ScoView)
* la méthode GET,POST à utiliser (si commence par #, la ligne est ignorée) * la méthode GET,POST à utiliser (si commence par #, la ligne est ignorée)
* les arguments éventuel (en cas de POST): une chaîne de caractère selon json * les arguments éventuel (en cas de POST): une chaîne de caractère selon json
Implémentation: Implémentation:
Le code complète une structure de données (Samples) qui est un dictionnaire de set (indicé par le nom des exemple. Le code complète une structure de données (Samples) qui est un dictionnaire de set
(indicé par le nom des exemples).
Chacun des éléments du set est un exemple (Sample) Chacun des éléments du set est un exemple (Sample)
Quand la structure est complète, on génére tous les fichiers textes Quand la structure est complète, on génére tous les fichiers textes
- nom de l exemple - nom de l'exemple
- un ou plusieurs exemples avec pour chaucn - un ou plusieurs exemples avec pour chacun
- l url utilisée - l'url utilisée
- les arguments éventuels - les arguments éventuels
- le résultat - le résultat
Le tout mis en forme au format markdown et rangé dans le répertoire DATA_DIR (/tmp/samples) qui est créé ou écrasé si déjà existant Le tout mis en forme au format markdown et rangé dans le répertoire DATA_DIR (/tmp/samples)
qui est créé ou écrasé si déjà existant.
""" """
import os import os
import shutil import shutil
@ -50,7 +61,7 @@ from pprint import pprint as pp
import urllib3 import urllib3
import json import json
from pandas import read_csv import pandas as pd
from setup_test_api import ( from setup_test_api import (
API_PASSWORD, API_PASSWORD,
@ -68,6 +79,10 @@ DATA_DIR = "/tmp/samples/"
SAMPLES_FILENAME = "tests/ressources/samples/samples.csv" SAMPLES_FILENAME = "tests/ressources/samples/samples.csv"
class SampleException(Exception):
pass
class Sample: class Sample:
def __init__(self, url, method="GET", permission="ScoView", content=None): def __init__(self, url, method="GET", permission="ScoView", content=None):
self.content = content self.content = content
@ -83,7 +98,7 @@ class Sample:
elif permission == "ScoUsersAdmin": elif permission == "ScoUsersAdmin":
HEADERS = get_auth_headers("admin_api", "admin_api") HEADERS = get_auth_headers("admin_api", "admin_api")
else: else:
raise Exception(f"Bad permission : {permission}") raise SampleException(f"Bad permission : {permission}")
if self.method == "GET": if self.method == "GET":
self.result = GET(self.url, HEADERS) self.result = GET(self.url, HEADERS)
elif self.method == "POST": elif self.method == "POST":
@ -94,20 +109,19 @@ class Sample:
self.result = POST_JSON(self.url, json.loads(self.content), HEADERS) self.result = POST_JSON(self.url, json.loads(self.content), HEADERS)
elif self.method[0] != "#": elif self.method[0] != "#":
error = f'Bad method : "{self.method}"' error = f'Bad method : "{self.method}"'
raise Exception(error) raise SampleException(error)
self.shorten() self.shorten()
file = open(f"sample_TEST.json.md", "tw") with open("sample_TEST.json.md", "tw", encoding="utf-8") as f:
self.dump(file) self.dump(f)
file.close()
def _shorten( def _shorten(self, item):
self, item "Abrège les longues listes: limite à 2 éléments et affiche '...' etc. à la place"
): # abrege les longues listes (limite à 2 éléments et affiche "... etc. à la place"
if isinstance(item, list): if isinstance(item, list):
return [self._shorten(child) for child in item[:2]] + ["... etc."] return [self._shorten(child) for child in item[:2] + ["..."]]
return item return item
def shorten(self): def shorten(self):
"Abrège le résultat"
self.result = self._shorten(self.result) self.result = self._shorten(self.result)
def pp(self): def pp(self):
@ -122,8 +136,8 @@ class Sample:
file.write(f"#### {self.method} {self.url}\n") file.write(f"#### {self.method} {self.url}\n")
if len(self.content) > 0: if len(self.content) > 0:
file.write(f"> `Content-Type: application/json`\n") file.write("> `Content-Type: application/json`\n")
file.write(f"> \n") file.write("> \n")
file.write(f"> `{self.content}`\n\n") file.write(f"> `{self.content}`\n\n")
file.write("```json\n") file.write("```json\n")
@ -143,7 +157,7 @@ class Samples:
"""Entry_names: la liste des entrées à reconstruire. """Entry_names: la liste des entrées à reconstruire.
si None, la totalité des lignes de samples.csv est prise en compte si None, la totalité des lignes de samples.csv est prise en compte
""" """
self.entries = defaultdict(lambda: set()) self.entries = defaultdict(set)
self.entry_names = entry_names self.entry_names = entry_names
def add_sample(self, line): def add_sample(self, line):
@ -171,35 +185,35 @@ class Samples:
def dump(self): def dump(self):
for entry, samples in self.entries.items(): for entry, samples in self.entries.items():
file = open(f"{DATA_DIR}sample_{entry}.json.md", "tw") with open(f"{DATA_DIR}sample_{entry}.json.md", "tw", encoding="utf-8") as f:
file.write(f"### {entry}\n\n") f.write(f"### {entry}\n\n")
for sample in sorted( # Trié de façon à rendre le fichier indépendant de l'ordre des résultats
samples, key=lambda s: s.url for sample in sorted(samples, key=lambda s: s.url):
): # sorted de façon à rendre le fichier résultat déterministe (i.e. indépendant de l ordre d arrivée des résultats) sample.dump(f)
sample.dump(file)
file.close()
def make_samples(samples_filename): def make_samples(samples_filename):
if len(sys.argv) == 1: "Génère les samples"
entry_names = None entry_names = None
elif len(sys.argv) >= 3 and sys.argv[1] == "-i": if len(sys.argv) >= 3 and sys.argv[1] == "-i":
samples_filename = sys.argv[2] samples_filename = sys.argv[2]
entry_names = sys.argv[3:] if len(sys.argv) > 3 else None entry_names = sys.argv[3:] if len(sys.argv) > 3 else None
else:
entry_names = sys.argv[1:]
if os.path.exists(DATA_DIR): if os.path.exists(DATA_DIR):
if not os.path.isdir(DATA_DIR): if not os.path.isdir(DATA_DIR):
raise f"{DATA_DIR} existe déjà et n'est pas un répertoire" raise SampleException(f"{DATA_DIR} existe déjà et n'est pas un répertoire")
else: # DATA_DIR existe déjà - effacer et recréer
# DATA_DIR existe déjà - effacer et recréer shutil.rmtree(DATA_DIR)
shutil.rmtree(DATA_DIR) os.mkdir(DATA_DIR)
os.mkdir(DATA_DIR)
else: else:
os.mkdir(DATA_DIR) os.mkdir(DATA_DIR)
samples = Samples(entry_names) samples = Samples(entry_names)
df = read_csv( df = pd.read_csv(
samples_filename, samples_filename,
comment="#",
sep=";", sep=";",
quotechar='"', quotechar='"',
dtype={ dtype={
@ -212,11 +226,12 @@ def make_samples(samples_filename):
keep_default_na=False, keep_default_na=False,
) )
df = df.reset_index() df = df.reset_index()
df.apply(lambda line: samples.add_sample(line), axis=1) df.apply(samples.add_sample, axis=1)
samples.dump() samples.dump()
return samples return samples
if not CHECK_CERTIFICATE: if not CHECK_CERTIFICATE:
urllib3.disable_warnings() urllib3.disable_warnings()
make_samples(SAMPLES_FILENAME) make_samples(SAMPLES_FILENAME)

View File

@ -1,119 +1,120 @@
"entry_name";"url";"permission";"method";"content" "entry_name";"url";"permission";"method";"content"
"assiduite_create";"/assiduite/1/create";"ScoView";"POST";"{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""}"
"assiduite_create";"/assiduite/1/create/batch";"ScoView";"POST";"{""batch"":[{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""},{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""retard""},{""date_debut"": ""2022-10-27T11:00"",""date_fin"": ""2022-10-27T13:00"",""etat"": ""present""}]}"
"assiduite_delete";"/assiduite/delete";"ScoView";"POST";"{""assiduite_id"": 1}"
"assiduite_delete";"/assiduite/delete/batch";"ScoView";"POST";"{""batch"":[2,2,3]}"
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"": ""retard"",""moduleimpl_id"":3}"
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"":""absent""}"
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""moduleimpl_id"":2}"
"assiduite";"/assiduite/1";"ScoView";"GET"; "assiduite";"/assiduite/1";"ScoView";"GET";
"assiduites";"/assiduites/1";"ScoView";"GET";
"assiduites";"/assiduites/1/query?etat=retard";"ScoView";"GET";
"assiduites";"/assiduites/1/query?moduleimpl_id=1";"ScoView";"GET";
"assiduites_count";"/assiduites/1/count";"ScoView";"GET"; "assiduites_count";"/assiduites/1/count";"ScoView";"GET";
"assiduites_count";"/assiduites/1/count/query?etat=retard";"ScoView";"GET";
"assiduites_count";"/assiduites/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET"; "assiduites_count";"/assiduites/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET";
"assiduites_count";"/assiduites/1/count/query?etat=retard";"ScoView";"GET";
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count";"ScoView";"GET";
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET";
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=retard";"ScoView";"GET";
"assiduites_formsemestre";"/assiduites/formsemestre/1";"ScoView";"GET"; "assiduites_formsemestre";"/assiduites/formsemestre/1";"ScoView";"GET";
"assiduites_formsemestre";"/assiduites/formsemestre/1/query?etat=retard";"ScoView";"GET"; "assiduites_formsemestre";"/assiduites/formsemestre/1/query?etat=retard";"ScoView";"GET";
"assiduites_formsemestre";"/assiduites/formsemestre/1/query?moduleimpl_id=1";"ScoView";"GET"; "assiduites_formsemestre";"/assiduites/formsemestre/1/query?moduleimpl_id=1";"ScoView";"GET";
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count";"ScoView";"GET"; "assiduites";"/assiduites/1";"ScoView";"GET";
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=retard";"ScoView";"GET"; "assiduites";"/assiduites/1/query?etat=retard";"ScoView";"GET";
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET"; "assiduites";"/assiduites/1/query?moduleimpl_id=1";"ScoView";"GET";
"assiduite_create";"/assiduite/1/create";"ScoView";"POST";"{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""}"
"assiduite_create";"/assiduite/1/create/batch";"ScoView";"POST";"{""batch"":[{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""},{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""retard""},{""date_debut"": ""2022-10-27T11:00"",""date_fin"": ""2022-10-27T13:00"",""etat"": ""present""}]}"
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"":""absent""}"
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""moduleimpl_id"":2}"
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"": ""retard"",""moduleimpl_id"":3}"
"assiduite_delete";"/assiduite/delete";"ScoView";"POST";"{""assiduite_id"": 1}"
"assiduite_delete";"/assiduite/delete/batch";"ScoView";"POST";"{""batch"":[2,2,3]}"
"departements";"/departements";"ScoView";"GET";
"departements-ids";"/departements_ids";"ScoView";"GET";
"departement";"/departement/TAPI";"ScoView";"GET";
"departement";"/departement/id/1";"ScoView";"GET";
"departement-etudiants";"/departement/TAPI/etudiants";"ScoView";"GET";
"departement-etudiants";"/departement/id/1/etudiants";"ScoView";"GET";
"departement-formsemestres_ids";"/departement/TAPI/formsemestres_ids";"ScoView";"GET";
"departement-formsemestres_ids";"/departement/id/1/formsemestres_ids";"ScoView";"GET";
"departement-formsemestres-courants";"/departement/TAPI/formsemestres_courants";"ScoView";"GET";
"departement-formsemestres-courants";"/departement/id/1/formsemestres_courants";"ScoView";"GET";
"departement-create";"/departement/create";"ScoSuperAdmin";"POST";"{""acronym"": ""NEWONE"" , ""visible"": true}" "departement-create";"/departement/create";"ScoSuperAdmin";"POST";"{""acronym"": ""NEWONE"" , ""visible"": true}"
"departement-edit";"/departement/NEWONE/edit";"ScoSuperAdmin";"POST";"{""visible"": false}"
"departement-delete";"/departement/NEWONE/delete";"ScoSuperAdmin";"POST"; "departement-delete";"/departement/NEWONE/delete";"ScoSuperAdmin";"POST";
"etudiants-courants";"/etudiants/courants?date_courante=2022-07-20";"ScoView";"GET"; "departement-edit";"/departement/NEWONE/edit";"ScoSuperAdmin";"POST";"{""visible"": false}"
"etudiants-courants";"/etudiants/courants/long?date_courante=2022-07-20";"ScoView";"GET"; "departement-etudiants";"/departement/id/1/etudiants";"ScoView";"GET";
"departement-etudiants";"/departement/TAPI/etudiants";"ScoView";"GET";
"departement-formsemestres_ids";"/departement/id/1/formsemestres_ids";"ScoView";"GET";
"departement-formsemestres_ids";"/departement/TAPI/formsemestres_ids";"ScoView";"GET";
"departement-formsemestres-courants";"/departement/id/1/formsemestres_courants";"ScoView";"GET";
"departement-formsemestres-courants";"/departement/TAPI/formsemestres_courants";"ScoView";"GET";
"departement-logo";"/departement/id/1/logo/D";"ScoSuperAdmin";"GET";
"departement-logo";"/departement/TAPI/logo/D";"ScoSuperAdmin";"GET";
"departement-logos";"/departement/id/1/logos";"ScoSuperAdmin";"GET";
"departement-logos";"/departement/TAPI/logos";"ScoSuperAdmin";"GET";
"departement";"/departement/id/1";"ScoView";"GET";
"departement";"/departement/TAPI";"ScoView";"GET";
"departements-ids";"/departements_ids";"ScoView";"GET";
"departements";"/departements";"ScoView";"GET";
"etudiant_formsemestres";"/etudiant/nip/11/formsemestres";"ScoView";"GET";
"etudiant-formsemestre-bulletin";"/etudiant/etudid/11/formsemestre/1/bulletin";"ScoView";"GET";
#"etudiant-formsemestre-bulletin";"/etudiant/ine/INE11/formsemestre/1/bulletin";"ScoView";"GET";
#"etudiant-formsemestre-bulletin";"/etudiant/nip/11/formsemestre/1/bulletin";"ScoView";"GET";
#"etudiant-formsemestre-bulletin";"/etudiant/nip/11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"etudiant-formsemestre-groups";"/etudiant/etudid/11/formsemestre/1/groups";"ScoView";"GET";
"etudiant-formsemestres";"/etudiant/etudid/11/formsemestres";"ScoView";"GET";
"etudiant-formsemestres";"/etudiant/ine/INE11/formsemestres";"ScoView";"GET";
"etudiant";"/etudiant/etudid/11";"ScoView";"GET"; "etudiant";"/etudiant/etudid/11";"ScoView";"GET";
"etudiant";"/etudiant/nip/11";"ScoView";"GET";
"etudiant";"/etudiant/ine/INE11";"ScoView";"GET"; "etudiant";"/etudiant/ine/INE11";"ScoView";"GET";
"etudiant";"/etudiant/nip/11";"ScoView";"GET";
"etudiants-clef";"/etudiants/etudid/11";"ScoView";"GET"; "etudiants-clef";"/etudiants/etudid/11";"ScoView";"GET";
"etudiants-clef";"/etudiants/ine/INE11";"ScoView";"GET"; "etudiants-clef";"/etudiants/ine/INE11";"ScoView";"GET";
"etudiants-clef";"/etudiants/nip/11";"ScoView";"GET"; "etudiants-clef";"/etudiants/nip/11";"ScoView";"GET";
"etudiant-formsemestres";"/etudiant/etudid/11/formsemestres";"ScoView";"GET"; "etudiants-courants";"/etudiants/courants?date_courante=2022-07-20";"ScoView";"GET";
"etudiant-formsemestres";"/etudiant/ine/INE11/formsemestres";"ScoView";"GET"; "etudiants-courants";"/etudiants/courants/long?date_courante=2022-07-20";"ScoView";"GET";
"etudiant_formsemestres";"/etudiant/nip/11/formsemestres";"ScoView";"GET"; "evaluation";"/evaluation/1";"ScoView";"GET";
"etudiant-formsemestre-bulletin";"/etudiant/etudid/11/formsemestre/1/bulletin";"ScoView";"GET"; "evaluation-notes";"/evaluation/1/notes";"ScoView";"GET";
"etudiant-formsemestre-bulletin";"/etudiant/ine/INE11/formsemestre/1/bulletin";"ScoView";"GET";
"etudiant-formsemestre-bulletin";"/etudiant/nip/11/formsemestre/1/bulletin";"ScoView";"GET";
"etudiant-formsemestre-bulletin";"/etudiant/nip/11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"etudiant-formsemestre-groups";"/etudiant/etudid/11/formsemestre/1/groups";"ScoView";"GET";
"formations";"/formations";"ScoView";"GET";
"formations_ids";"/formations_ids";"ScoView";"GET";
"formation";"/formation/1";"ScoView";"GET";
"formation-export";"/formation/1/export";"ScoView";"GET";
"formation-export";"/formation/1/export_with_ids";"ScoView";"GET"; "formation-export";"/formation/1/export_with_ids";"ScoView";"GET";
"formation-export";"/formation/1/export";"ScoView";"GET";
"formation-referentiel_competences";"/formation/1/referentiel_competences";"ScoView";"GET"; "formation-referentiel_competences";"/formation/1/referentiel_competences";"ScoView";"GET";
"moduleimpl";"/moduleimpl/1";"ScoView";"GET"; "formation";"/formation/1";"ScoView";"GET";
"formations_ids";"/formations_ids";"ScoView";"GET";
"formations";"/formations";"ScoView";"GET";
"formsemestre-bulletins";"/formsemestre/1/bulletins";"ScoView";"GET";
"formsemestre-decisions_jury";"/formsemestre/1/decisions_jury";"ScoView";"GET";
"formsemestre-etat_evals";"/formsemestre/1/etat_evals";"ScoView";"GET";
"formsemestre-etudiants-query";"/formsemestre/1/etudiants/query?etat=D";"ScoView";"GET";
"formsemestre-etudiants";"/formsemestre/1/etudiants";"ScoView";"GET";
"formsemestre-etudiants";"/formsemestre/1/etudiants/long";"ScoView";"GET";
"formsemestre-partition-create";"/formsemestre/1/partition/create";"ScoSuperAdmin";"POST";"{""partition_name"": ""PART""} "
"formsemestre-partitions-order";"/formsemestre/1/partitions/order";"ScoSuperAdmin";"POST";"[ 1 ]"
"formsemestre-partitions";"/formsemestre/1/partitions";"ScoView";"GET";
"formsemestre-programme";"/formsemestre/1/programme";"ScoView";"GET";
"formsemestre-resultats";"/formsemestre/1/resultats";"ScoView";"GET";
"formsemestre";"/formsemestre/1";"ScoView";"GET"; "formsemestre";"/formsemestre/1";"ScoView";"GET";
"formsemestres-query";"/formsemestres/query?annee_scolaire=2022&etape_apo=A2";"ScoView";"GET"; "formsemestres-query";"/formsemestres/query?annee_scolaire=2022&etape_apo=A2";"ScoView";"GET";
"formsemestres-query";"/formsemestres/query?nip=11";"ScoView";"GET"; "formsemestres-query";"/formsemestres/query?nip=11";"ScoView";"GET";
"formsemestre-bulletins";"/formsemestre/1/bulletins";"ScoView";"GET";
"formsemestre-programme";"/formsemestre/1/programme";"ScoView";"GET";
"formsemestre-etudiants";"/formsemestre/1/etudiants";"ScoView";"GET";
"formsemestre-etudiants";"/formsemestre/1/etudiants/long";"ScoView";"GET";
"formsemestre-etudiants-query";"/formsemestre/1/etudiants/query?etat=D";"ScoView";"GET";
"formsemestre-etat_evals";"/formsemestre/1/etat_evals";"ScoView";"GET";
"formsemestre-resultats";"/formsemestre/1/resultats";"ScoView";"GET";
"formsemestre-decisions_jury";"/formsemestre/1/decisions_jury";"ScoView";"GET";
"formsemestre-partitions";"/formsemestre/1/partitions";"ScoView";"GET";
"partition";"/partition/1";"ScoView";"GET";
"group-etudiants";"/group/1/etudiants";"ScoView";"GET";
"group-etudiants-query";"/group/1/etudiants/query?etat=D";"ScoView";"GET";
"moduleimpl-evaluations";"/moduleimpl/1/evaluations";"ScoView";"GET";
"evaluation-notes";"/evaluation/1/notes";"ScoView";"GET";
"user";"/user/1";"ScoView";"GET";
"users-query";"/users/query?starts_with=u_";"ScoView";"GET";
"permissions";"/permissions";"ScoView";"GET";
"roles";"/roles";"ScoView";"GET";
"role";"/role/Observateur";"ScoView";"GET";
"group-set_etudiant";"/group/1/set_etudiant/10";"ScoSuperAdmin";"POST";
"group-remove_etudiant";"/group/1/remove_etudiant/10";"ScoSuperAdmin";"POST";
"partition-group-create";"/partition/1/group/create";"ScoSuperAdmin";"POST";"{""group_name"": ""NEW_GROUP""}"
"group-edit";"/group/2/edit";"ScoSuperAdmin";"POST";"{""group_name"": ""NEW_GROUP2""}"
"group-delete";"/group/2/delete";"ScoSuperAdmin";"POST"; "group-delete";"/group/2/delete";"ScoSuperAdmin";"POST";
"formsemestre-partition-create";"/formsemestre/1/partition/create";"ScoSuperAdmin";"POST";"{""partition_name"": ""PART""} " "group-edit";"/group/2/edit";"ScoSuperAdmin";"POST";"{""group_name"": ""NEW_GROUP2""}"
"formsemestre-partitions-order";"/formsemestre/1/partitions/order";"ScoSuperAdmin";"POST";"[ 1 ]" "group-etudiants-query";"/group/1/etudiants/query?etat=D";"ScoView";"GET";
"partition-edit";"/partition/1/edit";"ScoSuperAdmin";"POST";"{""partition_name"":""P2BIS"", ""numero"":3,""bul_show_rank"":true,""show_in_lists"":false, ""groups_editable"":true}" "group-etudiants";"/group/1/etudiants";"ScoView";"GET";
"partition-remove_etudiant";"/partition/2/remove_etudiant/10";"ScoSuperAdmin";"POST"; "group-remove_etudiant";"/group/1/remove_etudiant/10";"ScoSuperAdmin";"POST";
"partition-groups-order";"/partition/1/groups/order";"ScoSuperAdmin";"POST";"[ 1 ]" "group-set_etudiant";"/group/1/set_etudiant/10";"ScoSuperAdmin";"POST";
"logo";"/logo/B";"ScoSuperAdmin";"GET";
"logos";"/logos";"ScoSuperAdmin";"GET";
"moduleimpl-evaluations";"/moduleimpl/1/evaluations";"ScoView";"GET";
"moduleimpl";"/moduleimpl/1";"ScoView";"GET";
"partition-delete";"/partition/2/delete";"ScoSuperAdmin";"POST"; "partition-delete";"/partition/2/delete";"ScoSuperAdmin";"POST";
"partition-edit";"/partition/1/edit";"ScoSuperAdmin";"POST";"{""partition_name"":""P2BIS"", ""numero"":3,""bul_show_rank"":true,""show_in_lists"":false, ""groups_editable"":true}"
"partition-group-create";"/partition/1/group/create";"ScoSuperAdmin";"POST";"{""group_name"": ""NEW_GROUP""}"
"partition-groups-order";"/partition/1/groups/order";"ScoSuperAdmin";"POST";"[ 1 ]"
"partition-remove_etudiant";"/partition/2/remove_etudiant/10";"ScoSuperAdmin";"POST";
"partition";"/partition/1";"ScoView";"GET";
"permissions";"/permissions";"ScoView";"GET";
"role-add_permission";"/role/customRole/add_permission/ScoUsersView";"ScoSuperAdmin";"POST";
"role-create";"/role/create/customRole";"ScoSuperAdmin";"POST";"{""permissions"": [""ScoView"", ""ScoUsersView""]}"
"role-delete";"/role/customRole/delete";"ScoSuperAdmin";"POST";
"role-edit";"/role/customRole/edit";"ScoSuperAdmin";"POST";"{ ""name"" : ""LaveurDeVitres"", ""permissions"" : [ ""ScoView"" ] }"
"role-remove_permission";"/role/customRole/remove_permission/ScoUsersView";"ScoSuperAdmin";"POST";
"role";"/role/Observateur";"ScoView";"GET";
"roles";"/roles";"ScoView";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin";"ScoView";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin/short";"ScoView";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/ine/INE11/formsemestre/1/bulletin";"ScoView";"GET";
"test-pdf";"/etudiant/ine/INE11/formsemestre/1/bulletin/short";"ScoView";"GET";
"test-pdf";"/etudiant/ine/INE11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/short";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"user-create";"/user/create";"ScoSuperAdmin";"POST";"{""user_name"": ""alain"", ""dept"": null, ""nom"": ""alain"", ""prenom"": ""bruno"", ""active"": true }" "user-create";"/user/create";"ScoSuperAdmin";"POST";"{""user_name"": ""alain"", ""dept"": null, ""nom"": ""alain"", ""prenom"": ""bruno"", ""active"": true }"
"user-edit";"/user/10/edit";"ScoSuperAdmin";"POST";"{ ""dept"": ""TAPI"", ""nom"": ""alain2"", ""prenom"": ""bruno2"", ""active"": false }" "user-edit";"/user/10/edit";"ScoSuperAdmin";"POST";"{ ""dept"": ""TAPI"", ""nom"": ""alain2"", ""prenom"": ""bruno2"", ""active"": false }"
"user-password";"/user/3/password";"ScoSuperAdmin";"POST";"{ ""password"": ""rePlaCemeNT456averylongandcomplicated"" }" "user-password";"/user/3/password";"ScoSuperAdmin";"POST";"{ ""password"": ""rePlaCemeNT456averylongandcomplicated"" }"
"user-password";"/user/3/password";"ScoSuperAdmin";"POST";"{ ""password"": ""too_simple"" }" "user-password";"/user/3/password";"ScoSuperAdmin";"POST";"{ ""password"": ""too_simple"" }"
"user-role-add";"/user/10/role/Observateur/add";"ScoSuperAdmin";"POST"; "user-role-add";"/user/10/role/Observateur/add";"ScoSuperAdmin";"POST";
"user-role-remove";"/user/10/role/Observateur/remove";"ScoSuperAdmin";"POST"; "user-role-remove";"/user/10/role/Observateur/remove";"ScoSuperAdmin";"POST";
"role-create";"/role/create/customRole";"ScoSuperAdmin";"POST";"{""permissions"": [""ScoView"", ""ScoUsersView""]}" "user";"/user/1";"ScoView";"GET";
"role-remove_permission";"/role/customRole/remove_permission/ScoUsersView";"ScoSuperAdmin";"POST"; "users-query";"/users/query?starts_with=u_";"ScoView";"GET";
"role-add_permission";"/role/customRole/add_permission/ScoUsersView";"ScoSuperAdmin";"POST";
"role-edit";"/role/customRole/edit";"ScoSuperAdmin";"POST";"{ ""name"" : ""LaveurDeVitres"", ""permissions"" : [ ""ScoView"" ] }"
"role-delete";"/role/customRole/delete";"ScoSuperAdmin";"POST";
"logos";"/logos";"ScoSuperAdmin";"GET";
"logo";"/logo/B";"ScoSuperAdmin";"GET";
"departement-logos";"/departement/TAPI/logos";"ScoSuperAdmin";"GET";
"departement-logos";"/departement/id/1/logos";"ScoSuperAdmin";"GET";
"departement-logo";"/departement/TAPI/logo/D";"ScoSuperAdmin";"GET";
"departement-logo";"/departement/id/1/logo/D";"ScoSuperAdmin";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/ine/INE11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin/short";"ScoView";"GET";
"test-pdf";"/etudiant/ine/INE11/formsemestre/1/bulletin/short";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/short";"ScoView";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin";"ScoView";"GET";
"test-pdf";"/etudiant/ine/INE11/formsemestre/1/bulletin";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin";"ScoView";"GET";

Can't render this file because it contains an unexpected character in line 41 and column 2.