Skip to content
ahsan876 edited this page Apr 17, 2026 · 1 revision

Resume parsing

How reveilio extracts text from resumes and what formats are supported.


Supported file formats

Extension Method Notes
.pdf PyPDF2 Works with text-based PDFs. Scanned/image PDFs require OCR (not built in).
.docx python-docx Full support for modern Word files (Office 2007+).
.doc antiword / heuristic Legacy Word binary format. Best results with antiword installed. Falls back to UTF-16LE extraction and ASCII runs.
.txt UTF-8 decode Plain text with graceful handling of encoding errors.
Free text Direct string Pass text directly without any file. Useful for database rows or API responses.

The Resume class

A Resume is a lightweight wrapper that holds the extracted plain text and a filename. Unlike JobDescription, the Resume class does not call the LLM on its own. Structured extraction happens inside analyze_resume() as part of a single combined LLM call.

From a file

resume = reveilio.Resume.from_file("resumes/alice.pdf")
print(resume.filename)   # "alice.pdf"
print(resume.text[:200]) # extracted plain text

From free text

resume = reveilio.Resume.from_text(
    "Alice Example, Senior Python Engineer, 6 years experience...",
    filename="alice.txt",  # optional, used in output reports
)

From bytes

resume = reveilio.Resume.from_bytes(
    uploaded_file.read(),
    filename="alice.pdf",  # extension determines the parser
)

What gets extracted during analysis

When you call reveilio.analyze_resume(resume, jd), the scorer extracts the following structured data from the resume in a single LLM call:

Field Type Description
name string Candidate full name.
email string Email address.
phone string Phone number.
linkedin string LinkedIn profile URL if present on the resume.
skills list All technical and non-technical skills found.
experience list Each position with title, company, duration, description, and location.
education list Each degree with institution, year, and location.
certifications list Professional certifications.
total_experience float Calculated total years of experience.
top_keywords list Most relevant keywords from the resume.
career_gaps list Detected gaps in employment history.

Handling .doc files (legacy Word binary)

The .doc format is a legacy binary format from Word 97–2003. Reveilio handles it using a multi-step fallback strategy:

  1. RTF detection. Some tools save RTF files with a .doc extension. Detected by the {\rtf header and parsed as RTF.
  2. OOXML detection. Some tools save DOCX (ZIP-based) files with a .doc extension. Detected by the PK header and parsed as DOCX.
  3. Antiword. If the file is truly binary Word, reveilio tries the antiword command-line tool. Install it with sudo apt-get install antiword on Linux.
  4. UTF-16LE extraction. Word binary files store body text as UTF-16LE runs. Reveilio extracts these directly.
  5. Printable ASCII runs. As a last resort, reveilio scans for sequences of printable ASCII characters in the raw binary.

Using the text extractor directly

The text extraction logic is available as a standalone utility:

from reveilio.parsing.text_extract import extract_text

text = extract_text("document.pdf")                    # from file path
text = extract_text(raw_bytes, filename="doc.docx")    # from bytes

Convenience: skip the Resume class

You do not have to create a Resume object manually. analyze_resume() accepts file paths and free text directly:

# All three are equivalent
reveilio.analyze_resume("resumes/alice.pdf", jd)
reveilio.analyze_resume(reveilio.Resume.from_file("resumes/alice.pdf"), jd)

# Free text works too
reveilio.analyze_resume("Alice, 6 years Python, FastAPI, AWS", jd)

Continue to Scoring & analysis.

Clone this wiki locally