-
Notifications
You must be signed in to change notification settings - Fork 0
Job Descriptions
How reveilio loads, parses, and structures a job description.
A JobDescription holds the raw text of a JD and a lazily-computed structured parse. The LLM is only called the first time you access .parsed. After that, the result is cached on the object.
Each instance is fully independent. You can create multiple JobDescription objects for different open roles and reuse them across any number of resumes.
Supports .pdf, .docx, .doc, and .txt files.
jd = reveilio.JobDescription.from_file("roles/senior_python.pdf")Reveilio extracts the plain text from the file, stores it in jd.text, and sets jd.source to the file path.
Paste a JD directly from an email, database row, or API response.
jd = reveilio.JobDescription.from_text("""
Senior Python Engineer, 5+ years experience.
Must know FastAPI, PostgreSQL, and AWS.
Experience with CI/CD pipelines required.
""")Useful when integrating with web frameworks where uploaded files arrive as bytes.
jd = reveilio.JobDescription.from_bytes(
uploaded_file.read(),
filename="senior_python.pdf", # extension determines the parser
)When you access jd.parsed, the LLM extracts a structured dictionary containing:
| Field | Description |
|---|---|
position_title |
The role title (e.g. "Senior Full Stack Developer"). |
company |
The hiring company name. |
location |
Work location. |
work_mode |
Remote, hybrid, or on-site. |
required_skills |
List of must-have technical skills. |
preferred_skills |
List of nice-to-have skills. |
soft_skills |
Communication, leadership, etc. |
required_experience |
Minimum years of experience. |
preferred_experience |
Preferred years of experience. |
education_requirements |
List of required degrees. |
certifications |
Required or preferred certifications. |
tools_and_technologies |
Specific tools mentioned. |
programming_languages |
Languages required. |
frameworks |
Frameworks required (React, Django, etc.). |
databases |
Database systems mentioned. |
cloud_platforms |
AWS, Azure, GCP, etc. |
methodologies |
Agile, Scrum, etc. |
responsibilities |
List of job responsibilities. |
The structured parse is computed only on first access to jd.parsed. Creating a JobDescription object is instant. The LLM call only happens when you actually need the parsed data — typically when you call analyze_resume().
Once computed, the result is cached. If you score 500 resumes against the same JD, the JD parsing LLM call happens exactly once.
jd = reveilio.JobDescription.from_file("jd.pdf") # no LLM call yet
print(jd.parsed["position_title"]) # LLM call happens here
print(jd.parsed["required_skills"]) # cached, no second callEach JobDescription is an independent object with its own cache. Keep a dictionary of them for multi-role screening:
roles = {
"backend": reveilio.JobDescription.from_file("roles/backend.pdf"),
"frontend": reveilio.JobDescription.from_file("roles/frontend.txt"),
"devops": reveilio.JobDescription.from_text(devops_jd_text),
}
# Score one candidate against all open roles
for role_name, jd in roles.items():
result = reveilio.analyze_resume("resumes/alice.pdf", jd)
print(f"{role_name}: {result.overall_score}%")Extracted text is always available via jd.text. Useful for debugging or feeding into your own pipeline.
print(jd.text[:500]) # first 500 chars of extracted text
print(jd.source) # file path or "text"📝 Note: if the LLM cannot parse the JD (e.g. text is too garbled),
jd.parsedreturns a safe fallback dictionary with"position_title": "N/A"and empty lists for skills and requirements.
Continue to Resume parsing.
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