diff --git a/Makefile b/Makefile index 2b8d32f..7fdac92 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,25 @@ .PHONY: help .DEFAULT_GOAL := help +USER_ID = $(shell id -u) +GROUP_ID = $(shell id -g) + +export UID = $(USER_ID) +export GID = $(GROUP_ID) + help: @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + shell: ## Open dockerized Bash terminal @docker-compose run --no-deps --rm shell + python: ## Open dockerized python command line interface - @docker-compose run --no-deps --rm shell python3 + @docker-compose run --no-deps --rm shell python3 + +daemon: ## Launch daemon for one directory, eg make daemon ./domains-classifier + WORKING_DIR="$(filter-out $@,$(MAKECMDGOALS))" docker-compose up --no-deps --force-recreate daemon + +reset: ## Reset files permissions for all directory + @docker-compose run --no-deps --rm shell bash -c "find /app -user daemon -exec chown ${UID}:${GID} {} \;" + + diff --git a/README.md b/README.md index 5b28028..10bb1d4 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,91 @@ # 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). +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). @@ -100,25 +181,25 @@ 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. +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. +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. +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. +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. +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.) diff --git a/docker-compose.yml b/docker-compose.yml index 0de8b08..ef22234 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,3 +8,13 @@ volumes: - .:/app command: bash + daemon: + image: inistcnrs/lodex-workers-python:3.0.6 + environment: + - http_proxy + - https_proxy + ports: + - 31976:31976 + volumes: + - ./${WORKING_DIR}:/app/public +