Dans le cadre de notre projet d’analyse de la production scientifique de Télécom ParisTech, je récupère beaucoup de fichiers PDF. Pour en analyser le contenu, j’ai notamment besoin d’en récupérer le texte brut. Par ailleurs, comme indiqué dans le billet Des services pour l’analyse bibliographique, j’ai fait le choix d’appuyer nos développements sur des web services.
Je vais montrer ici comment je développe un service REST d’extraction de texte brut à partir de PDF en Python que je déploie sur Heroku (note: je développe sous Windows 10).
Note: je suis fraîchement convertit à Python; mon code n’a rien d’exemplaire et mérite surement d’être nettoyé/amélioré, mais il m’a suffit comme preuve de faisabilité
Créer un dossier pour mon service
Créer un environnement virtuel pour le développement local avec la commande
virtualenv venv
Créer un fichier requirements.txt avec le contenu suivant
pdfminer==20140328
Flask==0.11
Flask-Login==0.2.11
Flask-RESTful==0.3.2
aniso8601==0.82
Jinja2==2.7.3
MarkupSafe==0.23
Werkzeug==0.9.6
gunicorn==19.4.5
itsdangerous==0.24
six==1.7.2
Le fichier indique le package pdfminer pour le traitement de fichiers pdf.
(voir http://spapas.github.io/2014/06/30/rest-flask-mongodb-heroku/ pour des explications génériques sur les dépendances du projet)
Dans le dossier qui contient le fichier requirements.txt, créer un dossier pdf_service. Dans ce dossier, créer deux fichiers: __init__.py and resources.py.
__init__.py initialise l’application Flask qui va être créée
import os from flask import Flask, request, jsonify from flask_restful import Resource, Api from flask import make_response app = Flask(__name__) import pdf_service.resources
Et le fichier resources.py
import json
from flask import request, abort
from flask.ext import restful
from flask.ext.restful import reqparse
from pdf_service import app
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
import urllib2
from urllib2 import Request
from StringIO import StringIO
def convert_pdf_to_txt(path):
rsrcmgr = PDFResourceManager()
retstr = StringIO()
codec = 'utf-8'
laparams = LAParams()
device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
open = urllib2.urlopen(Request(path)).read()
memoryFile = StringIO(open)
parser = PDFParser(memoryFile)
doc = PDFDocument(parser)
parser.set_document(doc)
interpreter = PDFPageInterpreter(rsrcmgr, device)
password = ""
maxpages = 0
caching = True
pagenos=set()
for page in PDFPage.get_pages(memoryFile, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
interpreter.process_page(page)
text = retstr.getvalue()
device.close()
retstr.close()
print(text)
return text
@app.route('/', methods=['GET'])
def get_root():
return "index"
@app.route('/pdftotxt/<path:url>', methods=['GET'])
def get_url(url):
return convert_pdf_to_txt(url)
Pour démarrer un serveur local
Pour les tests, j’ai créé le fichier runserver.py
from pdf_service import app app.run(debug=True)
lancé avec la commande
python runserver.py
Pour créer un dépot git vide
git init
Pour ajouter les fichiers locaux dans le git
git add .
Attention à créer un .gitignore en indiquant les fichiers et directories à ignorer pour ne pas surcharger la communication
Pour alimenter le dépot git local
Qui va servir de référence pour les échanges avec Heroku
git commit -m "mon message texte"
Pour se connecter à Heroku
heroku login
puis les informations de votre compte
Pour détruire un service sur Heroku
Par exemple, pour se faire de la place, supprimer des tests devenus inutiles…
heroku apps:destroy –app <nom du service à détruire>
Pour créer le service sur heroku
heroku create
Pour pousser le développement local vers heroku
git push heroku master
(par défaut, provoque le déploiement d’un Python 2.7 et des dépendances décrites dans requirements.txt)
Pour lancer une instance du service
heroku ps:scale web=1
Pour voir ce qui tourne
heroku ps
Renommer le service
Utilisation de la ligne de commande pour renommer le service (voir https://devcenter.heroku.com/articles/renaming-apps)
Commande pour changer le nom du service (à partir de celui généré automatiquement par les outils heroku) et du dépot git associé (à faire dans le dossier où a été créé le service)
heroku apps:rename <nouveau nom>
Ping : Des services pour l’analyse bibliographique | Objets Numériques et Sémantique
Ping : Utiliser NLTK sur Heroku avec Python | Objets Numériques et Sémantique