How AI-Job-Search Ensures PDF Quality Verification in the Apply Process
The ai-job-search framework validates every generated PDF before submission using the tools/verify_pdf.py utility, which performs file existence, page count, text extractability, and required content checks to guarantee ATS compatibility.
The ai-job-search framework automates the creation of tailored résumés and cover letters, but submitting a malformed or unscannable document can derail an application. To prevent this, the framework integrates a rigorous PDF quality verification step into the apply pipeline. This verification, implemented in tools/verify_pdf.py, runs a series of structural and content checks using external PDF tools before any document reaches a job portal.
The PDF Quality Verification Pipeline
The verification process is orchestrated by the verify_pdf function in tools/verify_pdf.py. This utility performs four distinct validation layers to guarantee that every generated document meets professional standards and ATS readability requirements.
File Existence Validation
Before any content analysis begins, the framework confirms the PDF file exists on disk. The verify_pdf function uses Path(pdf_path).is_file() to verify presence. If the file is missing, the function immediately raises a VerificationError, halting the apply process before any further steps are attempted.
Page Count Verification
Recruiters often enforce strict page limits for résumés. When the caller provides an expected page count via the --pages argument, the tool executes the external pdfinfo command through the run_tool helper. The parse_page_count function then extracts the "Pages" field from the output using the regex pattern ^Pages:\s+(\d+)$. If the actual page count deviates from the expected value, the framework raises a VerificationError and aborts the submission.
Text Layer Extraction
For a PDF to be ATS-readable, it must contain an extractable text layer rather than just scanned images. The verification script calls pdftotext -layout to extract the document's text content, then normalizes whitespace using normalize_text. The resulting string length is compared against a minimum character threshold specified by --min-chars (defaulting to 1). Documents failing this check are rejected as non-readable.
Required Content Verification
Beyond structural integrity, the framework can validate that specific phrases or sections appear in the document. Using the --contains option, callers specify required text strings that must be present in the PDF. Each phrase is normalized and searched within the extracted text layer. If any required phrase is missing, the VerificationError is raised, ensuring critical sections like "Professional Experience" or "Education" are never accidentally omitted.
Integration with the Apply Workflow
The verification step is not optional—it is embedded directly into the apply command workflow. Before uploading to any job portal, the framework invokes verify_pdf with parameters appropriate for the specific application. This integration ensures that every résumé or cover letter passes quality gates automatically, preventing submissions of corrupted, unscannable, or incomplete documents.
Error Handling and CLI Usage
All verification failures raise a VerificationError, which the CLI layer catches and handles gracefully. The error message is printed to stderr, and the process returns a non-zero exit code. This design prevents the subsequent apply step from proceeding when validation fails, maintaining the integrity of the job application pipeline. Users can also invoke the verifier manually via command line:
python -m tools.verify_pdf output/resume.pdf --pages 2 --min-chars 500 \
--contains "Professional Experience" --contains "Education"
Programmatic Verification Example
Developers integrating with the framework can invoke verification programmatically to intercept bad PDFs before they reach the apply stage:
from tools.verify_pdf import verify_pdf, VerificationError
pdf_path = "output/resume.pdf"
try:
verify_pdf(
pdf_path,
expected_pages=2, # Must be exactly 2 pages
min_chars=500, # At least 500 characters of selectable text
required_text=("Professional Experience", "Education")
)
print("PDF passes all quality checks – ready to apply.")
except VerificationError as err:
print(f"PDF validation failed: {err}")
Summary
- The ai-job-search framework validates every PDF through
tools/verify_pdf.pybefore submission. - File existence checks prevent processing of missing documents.
- Page count verification uses
pdfinfoto enforce length requirements. - Text extraction via
pdftotextensures ATS compatibility by verifying selectable text exceeds--min-chars. - Content validation confirms required phrases are present using
--contains. - All failures raise
VerificationErrorwith non-zero exit codes to halt the apply process.
Frequently Asked Questions
What happens if the PDF file does not exist during verification?
The verify_pdf function checks Path(pdf_path).is_file() immediately upon invocation. If the file is missing, it raises a VerificationError before attempting any content analysis, ensuring the apply process stops early with a clear error message.
How does the framework verify that a PDF is not just a scanned image?
The tool runs pdftotext -layout to extract text content and measures the resulting string length against the --min-chars threshold. If the extraction yields fewer characters than specified (defaulting to 1), the document is flagged as lacking an extractable text layer, making it unreadable by ATS systems.
Can I require specific sections to appear in the generated PDF?
Yes. Pass the --contains argument when calling verify_pdf to specify mandatory phrases. The tool normalizes both the extracted text and the search phrases, then verifies each required string is present. Missing content triggers a VerificationError, preventing submission of incomplete documents.
Where are the tests for the PDF verification logic?
The verification behavior is validated by unit tests in tests/test_verify_pdf.py. These tests ensure the verify_pdf function correctly handles file existence, page count parsing, text extraction failures, and required content matching across various edge cases.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →