Comment écririez-vous une fonction `is_pdf (path_to_file)` en Python?

Oct 08 2020

J'ai un projet Django qui crée des PDF en utilisant Java comme tâche d'arrière-plan. Parfois, le processus peut prendre un certain temps, donc le client utilise une interrogation comme celle-ci:

  1. La première requête démarre le processus de génération et retourne None.
  2. Chaque demande ultérieure vérifie si le PDF a été créé.
    • Si tel est le cas, il renvoie le PDF.
    • Si ce n'est pas le cas, il revient à Nonenouveau et le client planifie une autre demande pour vérifier à nouveau dans n secondes.

Le problème que j'ai est que je ne sais pas comment vérifier si le PDF est terminé. Le processus Java crée le fichier par étapes. Si je vérifie simplement si le PDF existe, le PDF renvoyé est souvent invalide, car il est toujours en cours de construction. Donc, ce dont j'ai besoin est une is_pdf(path_to_file)fonction qui renvoie Truesi le fichier est un PDF valide et Falseautrement.

J'aimerais faire cela sans bibliothèque si possible, mais j'utiliserai une bibliothèque si nécessaire.

Je suis sous Linux.

Voici une solution qui fonctionne avec pdfminer , mais cela me semble excessif.

from pdfminer.high_level import extract_text

def is_pdf(path_to_file):
    """Return True if path_to_file is a readable PDF"""
    try:
        extract_text(path_to_file, maxpages=1)
        return True
    except:
        return False

J'espère une solution qui n'implique pas l'installation d'une grande bibliothèque juste pour vérifier si un fichier est un PDF valide.

Réponses

AntiqTech Oct 08 2020 at 23:30

J'ai trouvé ce pypi.org/project/pdfminer.six. J'ai produit un exemple simple. Voyez si cela vous est utile. a.pdf est un fichier vide. Je ne sais pas ce qu'il fera en essayant de lire un fichier pdf qui est toujours en cours de traitement par un autre programme.

from pdfminer.high_level import extract_text

try:
 text = extract_text("D:\\a.pdf")
 print(text)
except :
 print("invalid PDF file")
else:
 pass

--- mettre à jour --

Alternativement, j'ai vu un exemple de PDFDocument sur pdfminer github, https://github.com/pdfminer/pdfminer.six/blob/develop/tools/pdfstats.py à la ligne 53.

J'ai produit un exemple de code similaire:

from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfparser import PDFParser

try:
 pdf_file = open("D:\\a.pdf", 'rb')
 parser = PDFParser(pdf_file)
 password = ''
 document = PDFDocument(parser, password)
 print(document.info)
 print(document.xrefs)
except :
 print("invalid PDF file")
else:
 pass

Dans mon exemple, puisque a.pdf est vide; La fonction open () lève l'exception. Dans votre cas, j'imagine qu'il pourra ouvrir le fichier, mais PDFParser ou PDFDocument peut lever une exception. Si aucune exception n'est levée, l'attribut PDFDocument.info peut être utile.

- mise à jour 2 -

J'ai réalisé que l'objet document a un attribut xréfs. il y a une explication dans la classe PdfParser: "Il lit également les XRef à la fin de chaque fichier PDF." La vérification de la valeur de document.xrefs peut être utile.