¿Cómo escribirías una función `is_pdf (path_to_file)` en Python?

Oct 08 2020

Tengo un proyecto de Django que crea archivos PDF usando Java como tarea en segundo plano. A veces, el proceso puede tardar un tiempo, por lo que el cliente utiliza un sondeo como este:

  1. La primera solicitud inicia el proceso de construcción y regresa None.
  2. Cada solicitud posterior verifica si se ha creado el PDF.
    • Si lo ha sido, devuelve el PDF.
    • Si no es así, regresa Nonenuevamente y el cliente programa otra solicitud para verificar nuevamente en n segundos.

El problema que tengo es que no sé cómo comprobar si el PDF está terminado. El proceso de Java crea el archivo en etapas. Si solo verifico si el PDF existe, entonces el PDF que se devuelve a menudo no es válido, porque aún se está creando. Entonces, lo que necesito es una is_pdf(path_to_file)función que devuelva Truesi el archivo es un PDF válido y de lo Falsecontrario.

Me gustaría hacer esto sin una biblioteca si es posible, pero usaré una biblioteca si es necesario.

Estoy en Linux.

Aquí hay una solución que funciona con pdfminer , pero me parece una exageración.

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

Espero una solución que no implique la instalación de una gran biblioteca solo para verificar si un archivo es un PDF válido.

Respuestas

AntiqTech Oct 08 2020 at 23:30

Encontré este pypi.org/project/pdfminer.six. Produje un ejemplo simple. Vea si es útil para usted. a.pdf es un archivo vacío. No sé qué hará al intentar leer un archivo pdf que todavía está siendo procesado por otro programa.

from pdfminer.high_level import extract_text

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

--- actualización -

Alternativamente, he visto un ejemplo de PDFDocument en pdfminer github, https://github.com/pdfminer/pdfminer.six/blob/develop/tools/pdfstats.py en la línea 53.

Produje un código de ejemplo similar:

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

En mi ejemplo, dado que a.pdf está vacío; La función open () lanza la excepción. En su caso, supongo que podrá abrir el archivo, pero PDFParser o PDFDocument pueden generar una excepción. Si no se lanza ninguna excepción, el atributo PDFDocument.info puede resultar útil.

- actualización 2 -

Me he dado cuenta de que el objeto del documento tiene el atributo xrefs. hay una explicación en la clase PdfParser: "También lee XRefs al final de cada archivo PDF". Verificar el valor de document.xrefs puede resultar útil.