How would you write an `is_pdf(path_to_file)` function in Python?

Viewed 400

I have a Django project that creates PDFs using Java as a background task. Sometimes the process can take awhile, so the client uses polling like this:

  1. The first request starts the build process and returns None.
  2. Each subsequent request checks to see if the PDF has been built.
    • If it has been, it returns the PDF.
    • If it hasn't, it returns None again and the client schedules another request to check again in n seconds.

The problem I have is that I don't know how to check if the PDF is finished building. The Java process creates the file in stages. If I just check if the PDF exists, then the PDF that gets returned is often invalid, because it is still being built. So, what I need is an is_pdf(path_to_file) function that returns True if the file is a valid PDF and False otherwise.

I'd like to do this without a library if possible, but will use a library if necessary.

I'm on Linux.

Here is a solution that works using pdfminer, but it seems like overkill to me.

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

I'm hoping for a solution that doesn't involve installing a large library just to check if a file is a valid PDF.

2 Answers

I've found this pypi.org/project/pdfminer.six . I produced a simple example. See if it is useful to you. a.pdf is an empty file. I don't know what it will do when trying to read a pdf file which is still being processed by another program.

from pdfminer.high_level import extract_text

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

--- update --

Alternatively, I have seen an example of PDFDocument on pdfminer github, https://github.com/pdfminer/pdfminer.six/blob/develop/tools/pdfstats.py on line 53.

I produced a similar example code:

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

In my example, since a.pdf is empty; open() function throws the exception. In your case, I'm guessing it will be able to open the file but PDFParser or PDFDocument may throw an exception. If no exception is thrown, PDFDocument.info attribute might be useful.

-- update 2 --

I've realized that document object has xrefs attribute. there is an explanation in PdfParser class : "It also reads XRefs at the end of every PDF file." Checking the value of document.xrefs might be useful.

I suspect you could just write a script to email yourself or team distribution and simply list all the files in the directory. However, if you're only asking how to natively search a directory without installing modules. I would import os and re.

# ***** Search File *****
files = os.listdir(r"C:\Users\PATH")
print(files)
Related