feat: add light markdown candidate profile parser

This commit is contained in:
Antoine 2026-05-28 13:43:18 +02:00
parent 0ce4ca0ee5
commit 17800a5f07
4 changed files with 133 additions and 0 deletions

22
docs/profile-template.md Normal file
View File

@ -0,0 +1,22 @@
# Candidate Profile
## Summary
One short paragraph describing your target profile.
## Target Roles
- Data Engineer
## Strengths
- Python
- SQL
## Skills To Emphasize
- GCP
- BigQuery
## Constraints
- CDI only
- France only
## Notes
- Anything the CV parser might miss but future ranking should understand.

View File

@ -0,0 +1 @@
__all__ = ["profile_parser"]

View File

@ -0,0 +1,68 @@
from __future__ import annotations
from collections import defaultdict
from dataclasses import dataclass, field
@dataclass
class AuthoredProfile:
summary: str | None = None
target_roles: list[str] = field(default_factory=list)
strengths: list[str] = field(default_factory=list)
skills_to_emphasize: list[str] = field(default_factory=list)
constraints: list[str] = field(default_factory=list)
notes: list[str] = field(default_factory=list)
REQUIRED_SECTIONS = {
"summary",
"target roles",
"strengths",
"skills to emphasize",
"constraints",
"notes",
}
def parse_profile_markdown(markdown: str) -> AuthoredProfile:
sections: dict[str, list[str]] = defaultdict(list)
current_section: str | None = None
for raw_line in markdown.splitlines():
line = raw_line.strip()
if line.startswith("## "):
current_section = line[3:].strip().lower()
continue
if not line or current_section is None:
continue
sections[current_section].append(line)
missing = REQUIRED_SECTIONS - set(sections)
if missing:
missing_text = ", ".join(sorted(missing))
raise ValueError(f"Missing required markdown sections: {missing_text}")
return AuthoredProfile(
summary=" ".join(sections["summary"]),
target_roles=[
line[2:].strip()
for line in sections["target roles"]
if line.startswith("- ")
],
strengths=[
line[2:].strip()
for line in sections["strengths"]
if line.startswith("- ")
],
skills_to_emphasize=[
line[2:].strip()
for line in sections["skills to emphasize"]
if line.startswith("- ")
],
constraints=[
line[2:].strip()
for line in sections["constraints"]
if line.startswith("- ")
],
notes=[line[2:].strip() if line.startswith("- ") else line for line in sections["notes"]],
)

View File

@ -0,0 +1,42 @@
from textwrap import dedent
from job_research.profile.profile_parser import parse_profile_markdown
def test_parse_profile_markdown_reads_light_required_template() -> None:
markdown = dedent(
"""
# Candidate Profile
## Summary
Junior data engineer focused on Python and GCP.
## Target Roles
- Data Engineer
- Analytics Engineer
## Strengths
- Python
- SQL
## Skills To Emphasize
- BigQuery
- Terraform
## Constraints
- CDI only
- France only
## Notes
- Slight preference for French listings.
"""
).strip()
profile = parse_profile_markdown(markdown)
assert profile.summary == "Junior data engineer focused on Python and GCP."
assert profile.target_roles == ["Data Engineer", "Analytics Engineer"]
assert profile.strengths == ["Python", "SQL"]
assert profile.skills_to_emphasize == ["BigQuery", "Terraform"]
assert profile.constraints == ["CDI only", "France only"]
assert profile.notes == ["Slight preference for French listings."]