Skip to content

[2023-01] A python Flask API to extrat metadata and text from PDF files. Asynchronous tasks executed with a Celery queue and Redis workers. A SQLite storage managed by SqlAlchemy. Clean code with Flake8 and Isort. Coverage tested with Pytest-cov. See the documentation in the Readme.md and check the API contract with Swagger.

License

Notifications You must be signed in to change notification settings

BossaMuffin/API-PDFdataExtractionAndStorage

Repository files navigation

[2023-01] API-PDFdataExtractionAndStorage > Balthapp + Baltclient + Balthworker

Préambule

  1. Ce document est rédigé par anticipation. Il peut avoir quelques différences avec les versions commitées.
  2. Le programme présenté et la documentation associée ne sont pas destinés à un environnement de production.

Introduction

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.

Description

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.

Compléments:

  • 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.

Project structure

Architecture

Prérequis

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).

Stack

Main libraries

Installation (pour un mode local)

  1. Téléchargez ou clonez le dépôt sur votre ordinateur : https://github.com/BossaMuffin/API-PDFdataExtractionAndStorage.git
  2. 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
  3. Lancer le serveur Redis :
    $ sudo redis-server
  4. Ouvrir trois terminaux dans le dossier API-PDFdataExtractionAndStorage :
  5. 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
  6. Installez les bibliothèques nécessaires, depuis le dossier API-PDFdataExtractionAndStorage :
    $ pip install -r requirements.txt
  7. 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
  8. 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
  9. Le troisème terminal servira à l'exécution du client depuis 'balthclient'. $ cd API-PDFdataExtractionAndStorage/balthclient

Utilisation

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)

    1. upload : -pf (--postfile) pdffilepath.pdf
    2. metadata : -gm (--getmetadata) pdf_uid
    3. text : -gt (--gettext) pdf_uid
  • 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.

Limites d'utilisation

  1. 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.
  2. Taille des fichiers Par défault, la taille maximale des fichiers PDF tolérés à l'upload est fixée à 10Mo.

Exemples d'utilisation

  1. A l'aide d'un nouveau terminal, activez l'environnement virtuel de 'API-PDFdataExtractionAndStorage' et placez-vous dans le dossier balthclient.
  2. 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)
      
  3. 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)
      
  4. 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)
      

NB : en cas d'erreur la réponse est de la forme ({"error": "No pdf file provided."}, 400)

Status codes retournés au client

fonction Upload

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
Rappel :
  • 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.

Arrêt du programme

  1. Pour chacun des terminaux ouverts précédemment à la section 'Installation' (Redis, Celery et Flask) : CTRL + C.
  2. Vérifier le contenu des dossiers balthapp/storage/temp, balthapp/storage/db et balthapp/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).
  3. Décerner la note maximale à l'élève.

Licence

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.

Auteur

Balth Mehus, Bossa Muffin, MS SIO CentraleSupélec :

About

[2023-01] A python Flask API to extrat metadata and text from PDF files. Asynchronous tasks executed with a Celery queue and Redis workers. A SQLite storage managed by SqlAlchemy. Clean code with Flake8 and Isort. Coverage tested with Pytest-cov. See the documentation in the Readme.md and check the API contract with Swagger.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages