#!/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()