# Les web services TDM de l'Inist ## Web services en Python Créer un web service en Python consiste à créer un script Python capable de traiter un fichier JSON fourni via l'entrée standard (sdtin) et de produire un fichier JSON similaire dans la sortie standard (stdout) Exemple : ```python #!/usr/bin/python3 import sys import json for line in sys.stdin: data = json.loads(line) data['value'] = data['value'].upper() # YOUR STATEMENT HERE sys.stdout.write(json.dumps(data)) sys.stdout.write('\n') ``` Pour transformer un programme Python en web service, il est nécessaire de déclarer un point d’entrée (entrypoint) via la création d’un fichier .ini dans une arborescence spécifique (cf . Convention de nommage) Ce fichier contiendra la documentation au foamt OpenAPI, et une référence au fichier python a exécuter. Exemple : ```ini # OpenAPI Documentation - JSON format (dot notation) post.responses.default.description = Return all objects with enrich fields post.responses.default.content.application/json.schema.$ref = #/components/schemas/JSONStream post.summary = Enrich one field of each Object with a Python function post.requestBody.required = true post.requestBody.content.application/json.schema.$ref = #/components/schemas/JSONStream post.parameters.0.in = query post.parameters.0.in = query post.parameters.0.name = indent post.parameters.0.schema.type = boolean post.parameters.0.description = Indent or not the JSON Result [use] plugin = @ezs/local plugin = @ezs/basics plugin = @ezs/storage plugin = @ezs/analytics [JSONParse] separator = * [expand] path = value size = 100 [expand/exec] # command should be executable ! # Use absolute path command = ./v1/strings/uppercase.py [dump] indent = env('indent', false) ``` ## Développer Il est possible de tester localement (sur son poste) son webservice, dans un enviornement identique à celui de production, pour cela : ``` make daemon ./mon_repertoire ``` Ensuite le webservice est accessible à l'adresse http://localhost:31976 **WARNING:** Docker modifie le propiètaire des fichiers pour restaurer les permsisisons: ``` make reset `` ## Tester Des exemples de requêtes sont disponibles dans des fichers `examples.http`. Ceux-ci peuvent être utilisés directement dans VSCode, avec l'extension REST Client (humao.rest-client). Ils peuvent également être lancés en ligne de commande via [rest-cli](https://www.npmjs.com/package/rest-cli) ou via [dot-http](https://github.com/bayne/dot-http). Exemple 1 : lancement des exemples sans affichage ```bash $ restcli ./biblio-tools/examples.http examples:1 [1] POST https://biblio-tools.services.inist.fr/v1/unpaywall/is_oa?indent=true examples:2 [1] POST https://biblio-tools.services.inist.fr/v1/crossref/prefixes/expand?indent=true ``` Exemple 2 : lancement des exemples avec affichage ```bash $ restcli --full ./affiliations-libpostal/examples.http examples:1 [1] POST https://affiliations-libpostal.services.inist.fr/v1/parse?indent=true POST https://affiliations-libpostal.services.inist.fr/v1/parse?indent=true Content-Type: application/json [ { "value": "Barboncino 781 Franklin Ave, Crown Heights, Brooklyn, NY 11238" } ] HTTP/1.1 200 OK Access-Control-Allow-Origin: * Connection: close Content-Disposition: inline Content-Encoding: gzip Content-Type: application/octet-stream Date: Fri, 23 Jul 2021 09:00:14 GMT Server: nginx/1.15.10 Transfer-Encoding: chunked [{ "value": { "id": "Barboncino 781 Franklin Ave, Crown Heights, Brooklyn, NY 11238", "value": { "house": "barboncino", "house_number": "781", "road": "franklin ave", "suburb": "crown heights", "city_district": "brooklyn", "state": "ny", "postcode": "11238" } } }] ``` ## Développement en local - Pour les services utilisant [lodex-workers](https://github.com/Inist-CNRS/lodex-workers) : Lancement du serveur local ```bash cd loterre-resolvers ezs -v -d . ``` le webservice est accessible à cette adresse <http://localhost:31976>. ## Déclarer la documentation Swagger Le répertoire `www-home` contient le HTML de la page d'accueil <https://services.inist.fr>. Si la racine de votre service répond une documentation respectant OpenAPI 3.0 (swagger), il vous suffit de la déclarer dans `www-home/index.html` pour qu'elle soit prise en compte. ## Convention de nommage Chaque instance sur l'[ezmaster](https://github.com/Inist-CNRS/ezmaster) de la machine aura un nom en trois parties: 1. texte (domaine) 2. texte (spécialité) 3. numéro (version) La troisième partie du champ ne doit pas être communiquée à l'extérieur, c'est un numéro de version (si plusieurs instances ont les mêmes deux premiers champs, c'est la dernière version qui est exposée quand on n'utilise pas de numéro de version, ce qui sera le cas). Le numéro de version permet la mise à jour de l'image docker associée au webservice. ### Nom de l'instance Les champs textuels sont obligatoirement en minuscules, et sans accent (mais peuvent contenir des chiffres) et donc de préférence en anglais. Ils ne doivent pas contenir un nom de personne. La première partie décrit le **domaine** d'application du webservice. Exemple : `affiliation`, `text`, `classification`, `nlp`, etc. La seconde partie décrit une **spécialité** du domaine. Cette spécificité est principalement liée à une image docker différente, comme c'est le cas si les différents *web services* d'un domaine utilisent des langages différents (C++, python, nodejs, etc.) ### Nom des répertoires Chaque instance donne accès à une arborescence de webservices. Le nom de route dépend du nom des répertoires. Les noms des répertoires doivent donc être choisis dans cette optique. Il convient donc de respecter les pratiques communément admises dans la définition d'API de type REST. En utilisant des noms de répertoires en minuscules, sans accent (mais pouvant contenir des chiffres) et de préférence en anglais. Si le premier niveau caractérise obligatoirement la version, les suivants peuvent être adaptés selon le besoin. On veillera à créer un répertoire si et seulement si il propose plusieurs sous-répertoire ou fichiers. 1. Version des APIs (v1, v2, v3, etc.) 2. Nom de l'algorithme ou de la ressource utilisés ou de la langue 3. Nom de l'action ou de l'algorithme caractérisant le traitement 4. (...) Exemples : - `/v1/test/analyse` - `/v2/istex/expand` - `/v1/en/stemmer/analyse` ### Fichier d'exemple Chaque répertoire dédié à une instance contiendra au moins un fichier `examples.http` Ce fichier permet d'exécuter rapidement et simplement des exemples simples d'utilisation des webservices à travers VSCode ou restcli (en ligne de commande) Le format du fichier est celui précisé dans la documentation vscode https://github.com/Huachao/vscode-restclient#usage