ajout utilitaire make_samples

This commit is contained in:
Jean-Marie PLACE 2022-08-14 11:36:24 +02:00
parent e899cd0d16
commit 4182134547
2 changed files with 254 additions and 0 deletions

177
tests/api/make_samples.py Normal file
View File

@ -0,0 +1,177 @@
#!/usr/bin/env python3
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""Construction des fichiers exemples pour la documentation.
Usage:
cd /opt/scodoc/tests/api
python make_samples.py
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)
cd /opt/scodoc/tests/api
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
avec la config du client API:
```
SCODOC_URL = "http://localhost:5000/"
```
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)
* 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
* la permission nécessaire (par défaut ScoView)
* 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
Implémentation:
Le code complète une structure de données (Samples) qui est un dictionnaire de set (indicé par le nom des exemple.
Chacun des éléments du set est un exemple (Sample)
Quand la structure est complète, on génére tous les fichiers textes
- nom de l exemple
- un ou plusieurs exemples avec pour chaucn
- l url utilisée
- les arguments éventuels
- 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
TODO: ajouter un argument au script permettant de ne générer qu'un seul fichier (exemple: `python make_samples.py nom_exemple`)
"""
import os
import shutil
from collections import defaultdict
from pprint import pprint as pp
from pprint import pformat as pf
import urllib3
import json
from setup_test_api import (
API_PASSWORD,
API_URL,
API_USER,
APIError,
CHECK_CERTIFICATE,
get_auth_headers,
GET,
POST_JSON,
SCODOC_URL,
)
DATA_DIR = "/tmp/samples/"
class Sample:
def __init__(self, url, method="GET", permission="ScoView", content=None):
self.content = content
self.permission = permission
self.url = url
self.method = method
self.result = None
if permission == "ScoView":
HEADERS = get_auth_headers("test", "test")
elif permission == "ScoSuperAdmin":
HEADERS = get_auth_headers("admin_api", "admin_api")
elif permission == "ScoUsersAdmin":
HEADERS = get_auth_headers("admin_api", "admin_api")
else:
raise Exception(f"Bad permission : {permission}")
if self.method == "GET":
self.result = GET(self.url, HEADERS)
elif self.method == "POST":
if self.content == "":
self.result = POST_JSON(self.url, headers=HEADERS)
else:
HEADERS["Content-Type"] = "application/json ; charset=utf-8"
self.result = POST_JSON(self.url, json.loads(self.content), HEADERS)
elif self.method[0] != "#":
raise Exception(f"Bad method : {self.method}")
else: # method begin with # => comment
print(" pass")
self.shorten()
file = open(f"sample_TEST.json.md", "tw")
self.dump(file)
file.close()
def _shorten(self, item):
if isinstance(item, list):
return [self._shorten(child) for child in item[:2]]
return item
def shorten(self):
self.result = self._shorten(self.result)
def pp(self):
print(f"------ url: {self.url}")
print(f"method: {self.method}")
print(f"content: {self.content}")
print(f"permission: {self.permission}")
pp(self.result, indent=4)
def dump(self, file):
file.write(f"#### {self.method} {self.url}\n")
if len(self.content) > 0:
file.write(f"> `Content-Type: application/json`\n")
file.write(f"> \n")
file.write(f"> `{self.content}`\n\n")
file.write("```json\n")
file.write(json.dumps(self.result, indent=4))
file.write("\n```\n\n")
class Samples:
def __init__(self):
self.entries = defaultdict(lambda: set())
def add_sample(self, entry, url, method="GET", permission="ScoView", content=None):
show_content = "" if content == "" else f": '{content}'"
print(f"{entry:50} {method:5} {url:50} {show_content}")
sample = Sample(url, method, permission, content)
self.entries[entry].add(sample)
def pp(self):
for entry, samples in self.entries.items():
print(f"=== {entry}")
for sample in samples:
sample.pp()
def dump(self):
for entry, samples in self.entries.items():
file = open(f"{DATA_DIR}sample_{entry}.json.md", "tw")
file.write(f"### {entry}\n\n")
for sample in samples:
sample.dump(file)
file.close()
def make_samples():
if os.path.exists(DATA_DIR):
if not os.path.isdir(DATA_DIR):
raise f"{DATA_DIR} existe déjà et n'est pas un répertoire"
else:
# DATA_DIR existe déjà - effacer et recréer
shutil.rmtree(DATA_DIR)
os.mkdir(DATA_DIR)
else:
os.mkdir("/tmp/samples")
samples = Samples()
# samples.pp()
with open("samples.csv") as f:
L = [x[:-1].split("\t") for x in f]
for line in L[1:]:
entry_name = line[0]
url = line[1]
permission = line[2] if line[2] != "" else "ScoView"
method = line[3] if line[3] != "" else "GET"
content = line[4]
samples.add_sample(entry_name, url, method, permission, content)
samples.dump()
return samples
if not CHECK_CERTIFICATE:
urllib3.disable_warnings()
make_samples()

77
tests/api/samples.csv Normal file
View File

@ -0,0 +1,77 @@
reference url permission method content
departements /departements GET
departements-ids /departements_ids GET
departement /departement/TAPI GET
departement /departement/id/1 GET
departement-etudiants /departement/TAPI/etudiants GET
departement-etudiants /departement/id/1/etudiants GET
departement-formsemestres_ids /departement/TAPI/formsemestres_ids GET
departement-formsemestres_ids /departement/id/1/formsemestres_ids GET
departement-formsemestres-courants /departement/TAPI/formsemestres_courants GET
departement-formsemestres-courants /departement/id/1/formsemestres_courants GET
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
etudiants-courants /etudiants/courants GET
etudiants-courants /etudiants/courants/long GET
etudiant /etudiant/etudid/11 GET
etudiant /etudiant/nip/11 GET
etudiant /etudiant/ine/INE11 GET
etudiants-clef /etudiants/etudid/11 GET
etudiants-clef /etudiants/ine/INE11 GET
etudiants-clef /etudiants/nip/11 GET
etudiant-formsemestres /etudiant/etudid/11/formsemestres GET
etudiant-formsemestres /etudiant/ine/INE11/formsemestres GET
etudiant_formsemestres /etudiant/nip/11/formsemestres GET
etudiant-formsemestre-bulletin /etudiant/etudid/11/formsemestre/1/bulletin GET
etudiant-formsemestre-bulletin /etudiant/ine/INE11/formsemestre/1/bulletin GET
etudiant-formsemestre-bulletin /etudiant/nip/11/formsemestre/1/bulletin GET
etudiant-formsemestre-groups /etudiant/etudid/11/formsemestre/1/groups GET
formations /formations GET
formations_ids /formations_ids GET
formation /formation/1 GET
formation-export /formation/1/export GET
formation-export /formation/1/export_with_ids GET
formation-referentiel_competences /formation/1/referentiel_competences GET
moduleimpl /moduleimpl/1 GET
formsemestre /formsemestre/1 GET
formsemestres-query /formsemestres/query?annee_scolaire=2022&etape_apo=A2 GET
formsemestre-bulletins /formsemestre/1/bulletins GET
formsemestre-programme /formsemestre/1/programme GET
formsemestre-etudiants /formsemestre/1/etudiants GET
formsemestre-etudiants-query /formsemestre/1/etudiants/query?etat=D GET
formsemestre-etat_evals /formsemestre/1/etat_evals GET
formsemestre-resultats /formsemestre/1/resultats GET
formsemestre-decisions_jury /formsemestre/1/decisions_jury GET
formsemestre-partitions /formsemestre/1/partitions GET
partition /partition/1 GET
group-etudiants /group/1/etudiants GET
group-etudiants-query /group/1/etudiants/query?etat=D GET
moduleimpl-evaluations /moduleimpl/1/evaluations GET
evaluation-notes /evaluation/1/notes GET
user /user/1 GET
users-query /users/query?starts_with=u_ GET
permissions /permissions GET
roles /roles GET
role /role/Observateur 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
formsemestre-partition-create /formsemestre/1/partition/create ScoSuperAdmin POST {"partition_name": "PART"}
formsemestre-partitions-order /formsemestre/1/partitions/order ScoSuperAdmin POST [ 1 ]
partition-edit /partition/1/edit ScoSuperAdmin POST {"partition_name":"P2BIS", "numero":3,"bul_show_rank":true,"show_in_lists":false, "groups_editable":true}
partition-remove_etudiant /partition/2/remove_etudiant/10 ScoSuperAdmin POST
partition-groups-order /partition/1/groups/order ScoSuperAdmin POST [ 1 ]
partition-delete /partition/2/delete ScoSuperAdmin POST
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-role-add /user/10/role/Observateur/add ScoSuperAdmin POST
user-role-remove /user/10/role/Observateur/remove ScoSuperAdmin POST
role-create /role/create/customRole ScoSuperAdmin POST {"permissions": ["ScoView", "ScoUsersView"]}
role-remove_permission /role/customRole/remove_permission/ScoUsersView ScoSuperAdmin POST
role-add_permission /role/customRole/add_permission/ScoUsersView ScoSuperAdmin POST
role-edit /role/customRole/edit ScoSuperAdmin POST { "name" : "LaveurDeVitres", "permissions" : [ "ScoView", "APIView" ] }
role-edit /role/customRole/edit ScoSuperAdmin POST { "name" : "LaveurDeVitres", "permissions" : [ "ScoView", "APIView" ] }
role-delete /role/customRole/delete ScoSuperAdmin POST
Can't render this file because it contains an unexpected character in line 12 and column 60.