- Ce document est rédigé par anticipation. Il peut avoir quelques différences avec les versions commitées.
- Le programme présenté et la documentation associée ne sont pas destinés à un environnement de production.
Ce programme a été développé par Balthazar Méhus, dans le cadre d'un projet scolaire. Il est le résultat du cours 'Python for intensive data' du Mastère spécialisé "ingénierie des systèmes informatiques ouverts (SIO) de CentraleSupélec, promotion 2022-2023. Il a pour but de réaliser une tâche spécifique en utilisant les bibliothèques et les outils décrits ci-dessous. Il a été développé en utilisant le langage de programmation Python 3.10. Il utilise également des outils annexes et des bibliothèques externes (cf. § 'Prérequis'). Le code de ce programme respecte, particulièrement, le PEP8 et, globabelement, la philosophie 'clean code'. Cette volonté a été soutenue par les capacités de l'IDE PyCharm, ainsi que les outils Flake8 et Isort.
Ce programme est une API Python Flask, nommée 'Balthapp'. L'API est destinée à extraire les métadonnées et le texte de fichiers PDF fournis par le client, nommé balthclient
. Le PDF uploadé est stocké temporairement dans le système de fichiers (balthapp/storage/temp
).
Les tâches d'extraction sont réalisées de manière asynchrone dans balthworker
, grâce à une file d'attente Celery et à des workers en écoute sur Redis. Le stockage des metadonnées extraites est réalisé dans une base de données SQLite gérée par SqlAlchemy (balthapp/storage/db
). Le texte extrait est stocké dans le système de fichiers (balthapp/storage/files
). Le tout est regroupé dans un projet dont le dossier est intitulé API-PDFdataExtractionAndStorage
.
- Par défaut, Flask-Limiter limite les requêtes pour les adresses IP uniques à 200 par jour et 50 par heure. Chaque endpoint est indépendemment configuré pour imposer une limite spécifique au nombre de réqête admises par minute et par seconde.
- Magic est utilisé pour vérifier le type MIME des fichiers téléchargés.
- La taille des fichiers uploadés est limité à 10Mo
- La bonne couverture des tests unitaires est vérifiée à l'aide de Pytest-cov.
- Le contrat d'API est au standard openapi et il disponible au format yaml.
NB : le client Balthclient n'est pas exlusif (pas de système de token, de mot de passe, d'ip filtrée...). N'importe quelles requêtes pourraient obtenir une réponse de Balthapp.
Pour utiliser ce code, vous devez avoir installé les éléments suivants :
* Python 3.10
* Flask
* Redis
* toutes les dépendances listées dans le fichier requirements.txt
.
NB :
* Pour plus de simplicité, un seul fichier requirements.txt est fourni pour tous les sous-ensembles du projet (balthapp
, balthclient
et balthworker
).
* En l'absence de conteneur Dockers (non fournis dans cette version), il est conseillé d'utiliser un environement virtuel (type venv
).
- Téléchargez ou clonez le dépôt sur votre ordinateur : https://github.com/BossaMuffin/API-PDFdataExtractionAndStorage.git
- Installez et configurez le serveur Redis:
- Dans un conteneur Docker :
docker run - d - p 6379:6379 redis
- Ou sur votre machine (Unix) :
$ sudo apt install lsb-release $ curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg $ echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list $ sudo apt-get update $ sudo apt-get install redis
- Dans un conteneur Docker :
- Lancer le serveur Redis :
$ sudo redis-server
- Ouvrir trois terminaux dans le dossier
API-PDFdataExtractionAndStorage
: - Créer un venv et l'activer pour exécuter le programme sans affecter le reste de votre environnement.
$ cd API-PDFdataExtractionAndStorage
- Sous Windows :
$ .venv\Scripts\activate.bat
- Sous Unix :
$ source .venv/bin/activate
- Sous Windows :
- Installez les bibliothèques nécessaires, depuis le dossier
API-PDFdataExtractionAndStorage
:$ pip install -r requirements.txt
- Dans le premier terminal, allez dans le dossier 'balthapp' : lancer l'application Flask (installé avec requirements.txt) ;
$ cd API-PDFdataExtractionAndStorage/balthapp $ FLASK_APP=balthapp.py flask --debug run
- Dans le deuxième terminal, allez dans le dossier 'balthworker', lancer la file d'attente Celery (Task Queue) :
$ cd API-PDFdataExtractionAndStorage/balthworker $ celery -A tasks worker --loglevel=INFO
- Le troisème terminal servira à l'exécution du client depuis 'balthclient'.
$ cd API-PDFdataExtractionAndStorage/balthclient
Une fois l'installation effectuée et les différents éléments lancés, le programme est prêt à l'emploi.
-
Mode easy client : Il suffit d'utiliser le client 'balthclient' conformément au guide d'utilisation suivant (voir exemples ci-dessous). Il existe 3 options distinctes à passer en ligne de commande : 0) help :
-h (--help)
- upload :
-pf (--postfile) pdffilepath.pdf
- metadata :
-gm (--getmetadata) pdf_uid
- text :
-gt (--gettext) pdf_uid
- upload :
-
Fromscratch : Ils existes 6 routes pour communiquer avec l'API 'balthapp' sur
127.0.0.1:5000
:0)
'/'
: l'accueil qui renvoie simplement un message de bienvenue ; 1)'/contract'
: renvoie le contrat openapi au format yaml ; 2)POST '/documents' pdf_file='pdffilepath.pdf'
: gère l'upload des fichiers PDF et renvoie un uid ; 3)GET '/metadata/<uid>'
: renvoie les métadonnées une fois extraites ; 4)GET '/text/<uid>'
: renvoie le text une fois extrait ; 5)GET '/storage/files/<pdf_name>'
: donne accès au fochier text enregistré sur le serveur.
-
Nombre de solicitations : Par défault la limite de requêtes successives acceptées pour un utilisateur unique (ip) est fixée à :
- 200 par jour,
- 50 par heure. Des limites particulières supplémentaires sont fixées comme suit :
- post pdf : 10/minute et 1/seconde,
- get metadata : 20/minute et 1/seconde,
- get text : 20/minute et 1/seconde,
- get contract : 2/minute et 1/seconde.
-
Taille des fichiers Par défault, la taille maximale des fichiers PDF tolérés à l'upload est fixée à 10Mo.
- A l'aide d'un nouveau terminal, activez l'environnement virtuel de 'API-PDFdataExtractionAndStorage' et placez-vous dans le dossier
balthclient
. - Uploader un fichier pdf en vue de récupérer ses métadonnées et son texte :
- Commande :
$ python client.py -pf le/chemin/vers/mon/fichier.pdf
- Réponse :
({ '_id': '76310ab9-01d9-49c3-927c-1bafaa0a52a8' }, 201)
- Commande :
- Récupérer les métadonnées du fichier pdf :
- Commande :
$ python client.py -gm 76310ab9-01d9-49c3-927c-1bafaa0a52a8
- Réponse :
({ '_id': '6553e8d7-a286-40b9-b7d3-a1558928b22c', 'created_at': '2023-01-30 01:17:42', 'data': { '/CreationDate': "(D:20210813100532Z00'00')", '/Creator': '(Word)', '/ModDate': "(D:20210813100532Z00'00')", '/Producer': '(macOS Version 11.5.1 \\(Build 20G80\\) Quartz PDFContext)', '/Title': '(Microsoft Word - Software_design_guide.docx)' }, 'link': 'http://127.0.0.1:5000/storage/files/6553e8d7-a286-40b9-b7d3-a1558928b22c.txt', 'name': 'test-text.pdf', 'task_state': 'SUCCESS', 'updated_at': 'None' }, 200)
- Commande :
- Récupérer le texte du fichier pdf :
- Commande :
$ python client.py -gt 76310ab9-01d9-49c3-927c-1bafaa0a52a8
- Réponse :
(b'2021 \n\nSoftware Design Guide \n\nA 7 STEP-GUIDE TO DESIGNING GREAT SOFTWARE \n\xc2\xa9 ARJANCODES 2021 ... \n\x0c', 200)
- Commande :
NB : en cas d'erreur la réponse est de la forme ({"error": "No pdf file provided."}, 400)
Retourne un tuple contenant :
- [0] réponse dict type json (_id, ou error) ;
- [1] le code de status de la réponse Liste des HTTP status code :
- 200, 201, 202 : la requête a réussi. la clé "_id" donne l'id unique créé lors de l'upload du document PDF.
- 400, 413, 415, 422 : la requête a été correctement envoyée à l'API, mais elle n'a pas abouti ; la clé "error" donne une explication sur l'erreur qui a été managée.
- 0 : la requête à l'API n'a pas pu être envoyée, mais elle n'a pas abouti, car il y a un problème côté client ; NB: La clé "error" donne une explication sur l'erreur qui a été managée
- 200 : « Everything is OK ». Il s’agit du code qui est délivré lorsqu’une page web ou une ressource se comporte exactement comme prévu.
- 201 : « Created ». Le serveur a répondu à la requête du navigateur et a donc créé une nouvelle ressource.
- 202 : « Accepted ». Le serveur a accepté la requête de votre navigateur mais la traite encore. La demande peut finalement aboutir ou non à une réponse complète.
- Pour chacun des terminaux ouverts précédemment à la section 'Installation' (Redis, Celery et Flask) :
CTRL + C
. - Vérifier le contenu des dossiers
balthapp/storage/temp
,balthapp/storage/db
etbalthapp/storage/files
. Au besoin, les nettoyer (suppression de la base de donnée, des fichiers textes sauvegardé et des pdf uploadés conservés par erreur). - Décerner la note maximale à l'élève.
Ce programme est un projet scolaire qui n'a pas vocation à être distribué. Pour plus d'informations, veuillez vous référer au fichier LICENSE.md.
Balth Mehus, Bossa Muffin, MS SIO CentraleSupélec :