-
Notifications
You must be signed in to change notification settings - Fork 0
Resume Parsing
How reveilio extracts text from resumes and what formats are supported.
| 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. |
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.
resume = reveilio.Resume.from_file("resumes/alice.pdf")
print(resume.filename) # "alice.pdf"
print(resume.text[:200]) # extracted plain textresume = reveilio.Resume.from_text(
"Alice Example, Senior Python Engineer, 6 years experience...",
filename="alice.txt", # optional, used in output reports
)resume = reveilio.Resume.from_bytes(
uploaded_file.read(),
filename="alice.pdf", # extension determines the parser
)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. |
The .doc format is a legacy binary format from Word 97–2003. Reveilio handles it using a multi-step fallback strategy:
-
RTF detection. Some tools save RTF files with a
.docextension. Detected by the{\rtfheader and parsed as RTF. -
OOXML detection. Some tools save DOCX (ZIP-based) files with a
.docextension. Detected by thePKheader and parsed as DOCX. -
Antiword. If the file is truly binary Word, reveilio tries the
antiwordcommand-line tool. Install it withsudo apt-get install antiwordon Linux. - UTF-16LE extraction. Word binary files store body text as UTF-16LE runs. Reveilio extracts these directly.
- Printable ASCII runs. As a last resort, reveilio scans for sequences of printable ASCII characters in the raw binary.
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 bytesYou 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.
v0.1.1 · docs
Getting started
Core features
- Configuration & providers
- Job descriptions
- Resume parsing
- Scoring & analysis
- PDF reports
- Database storage
Using reveilio
Deployment
Deep dive