hired

Public API for the hired package. Import the main user-facing functions and classes.

class hired.ATSChecker[source]

Check resume for ATS compatibility.

Examples

>>> from hired.ats_checker import ATSChecker
>>>
>>> checker = ATSChecker()
>>> report = checker.check_resume(resume_dict)
>>> print(report.get_summary())
>>>
>>> # Check against specific job
>>> report = checker.check_resume(resume_dict, job_result)
check_resume(resume_content: Dict[str, Any], job: JobResult | None = None) ATSReport[source]

Check resume for ATS compatibility.

Parameters:
  • resume_content – Resume content as dictionary (JSON Resume format)

  • job – Optional JobResult to check keyword matching

Returns:

ATSReport with compatibility score and issues

class hired.ATSReport(overall_score: float, issues: List[ATSIssue] = <factory>, keyword_match_score: float = 0.0, matched_keywords: Set[str] = <factory>, missing_keywords: Set[str] = <factory>)[source]

Report from ATS compatibility check.

get_critical_issues() List[ATSIssue][source]

Get critical issues.

get_issues_by_category(category: str) List[ATSIssue][source]

Get issues filtered by category.

get_summary() str[source]

Get human-readable summary.

get_warnings() List[ATSIssue][source]

Get warnings.

to_dict() Dict[str, Any][source]

Convert to dictionary.

class hired.AlignmentReport(*, job_id: str, job_title: str = '', company: str = '', created_at: str = '', verdict: Verdict, score_summary: ScoreSummary = <factory>, requirements: list[RequirementRecord] = <factory>, blocking_gaps: list[RequirementRecord] = <factory>, next_actions: list[NextAction] = <factory>, interview_prep: InterviewPrep = <factory>, clarifications: list[Clarification] = <factory>)[source]

A complete, verdict-first alignment analysis for one JD.

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class hired.Application(job_title: str, company: str, id: int | None = None, job_url: str | None = None, location: str | None = None, salary_range: str | None = None, resume_path: str | None = None, cover_letter_path: str | None = None, status: str = 'draft', applied_date: str | None = None, created_at: str | None = None, updated_at: str | None = None, follow_up_date: str | None = None, last_contact_date: str | None = None, notes: str = '', contacts: str = '', interview_dates: str = '', match_score: float | None = None, source: str | None = None, source_data: str = '')[source]

Represents a job application.

classmethod from_job_result(job: JobResult, **kwargs) Application[source]

Create an Application from a JobResult.

Parameters:
  • job – JobResult object

  • **kwargs – Additional fields to set

Returns:

Application object

to_dict() Dict[str, Any][source]

Convert to dictionary.

class hired.ApplicationTracker(db_path: Path | None = None)[source]

Track job applications in a SQLite database.

Examples

>>> tracker = ApplicationTracker()
>>>
>>> # Add application from job search
>>> app_id = tracker.add_application(
...     job=job_result,
...     resume_path="resume.pdf",
...     status="applied"
... )
>>>
>>> # Update status
>>> tracker.update_status(app_id, "interview")
>>>
>>> # Get all applications in interview stage
>>> interviews = tracker.get_applications(status="interview")
>>>
>>> # Get statistics
>>> stats = tracker.get_statistics()
add_application(job: JobResult | None = None, **kwargs) int[source]

Add a new application.

Parameters:
  • job – Optional JobResult to create application from

  • **kwargs – Additional fields (or all fields if job not provided)

Returns:

ID of created application

Examples

>>> # From JobResult
>>> app_id = tracker.add_application(
...     job=job_result,
...     resume_path="resume.pdf",
...     status="applied"
... )
>>>
>>> # Manual entry
>>> app_id = tracker.add_application(
...     job_title="Software Engineer",
...     company="TechCorp",
...     status="applied"
... )
delete_application(app_id: int) bool[source]

Delete an application.

Parameters:

app_id – Application ID

Returns:

True if deleted, False if not found

export_to_csv(output_path: str)[source]

Export applications to CSV file.

Parameters:

output_path – Path to output CSV file

get_application(app_id: int) Application | None[source]

Get application by ID.

Parameters:

app_id – Application ID

Returns:

Application object or None if not found

get_applications(status: str | None = None, company: str | None = None, limit: int | None = None) List[Application][source]

Get applications with optional filtering.

Parameters:
  • status – Filter by status

  • company – Filter by company name

  • limit – Maximum number of results

Returns:

List of Application objects

get_follow_ups_due(days: int = 7) List[Application][source]

Get applications that need follow-up.

Parameters:

days – Number of days to look ahead

Returns:

List of Application objects needing follow-up

get_statistics() Dict[str, Any][source]

Get application statistics.

Returns:

Dictionary with statistics

update_application(app_id: int, **kwargs) bool[source]

Update application fields.

Parameters:
  • app_id – Application ID

  • **kwargs – Fields to update

Returns:

True if updated, False if not found

update_status(app_id: int, status: str, notes: str | None = None) bool[source]

Update application status.

Parameters:
  • app_id – Application ID

  • status – New status

  • notes – Optional notes to append

Returns:

True if updated, False if not found

class hired.CandidateKnowledgeBase(user: str = 'me', *, store: UserStore | None = None)[source]

Accumulated, open-world knowledge about a single candidate (user-level).

>>> import tempfile, os
>>> os.environ['HIRED_DATA_DIR'] = tempfile.mkdtemp()
>>> kb = CandidateKnowledgeBase()                 # default candidate "me"
>>> from hired.candidate.base import Fact, FactCategory
>>> _ = kb.add_fact(Fact(statement='Built ML pipelines in Python',
...                       category=FactCategory.SKILL, tags=['python', 'ml']))
>>> [f.statement for f in kb.facts(category=FactCategory.SKILL)]
['Built ML pipelines in Python']
>>> [f.statement for f in kb.facts(tags=['ml'])]
['Built ML pipelines in Python']
add_fact(fact: Fact) str[source]

Persist a fact, returning its id.

add_note(subject: str, text: str | None = None, *, files: dict | None = None) TopicDossier[source]

Record volunteered info about a subject into its dossier.

text is appended to the dossier’s overview.md; files (a {name: bytes} mapping) are attached as detail/media. Returns the dossier. This is the “by the way, I also did X” entry point — a single sentence or a whole folder both land here.

add_source(src: str | Path | bytes, *, name: str | None = None) str[source]

Store a raw source (file path or bytes) and record its content digest.

Returns the source key (its name in the raw store). The digest (in state.json) lets a later refresh detect new/changed sources without re-reading everything. Facts extracted from a source cite it by this key.

facts(*, category: FactCategory | None = None, tags: list[str] | None = None, status: FactStatus | None = FactStatus.ASSERTED, include_negations: bool = True) Iterator[Fact][source]

Iterate facts, optionally filtered by category/tags/status.

By default only ASSERTED facts are returned (superseded ones are hidden). tags matches facts containing any of the given tags.

jd(jd_id: str, *, company: str | None = None, label: str | None = None) JDWorkspace[source]

Get-or-create the workspace for an engagement (1+ JDs of one company).

company / label are recorded in the engagement’s meta when given.

jds() list[str][source]

Ids of all engagements for this candidate.

needs_refresh() bool[source]

True when uningested source/Q&A material exists (refresh warranted).

pending_qa() list[QAEntry][source]

Q&A entries not yet distilled into facts.

pending_sources() list[str][source]

Raw sources new, changed, or not yet distilled into facts.

record_qa(entry: QAEntry, *, derived_facts: list[dict] | None = None) str[source]

Append a clarifying Q&A exchange; optionally distill it into facts.

When derived_facts (atomic fact records extracted from the answer) are given, they are ingested with SourceKind.QA provenance (source_id = the Q&A id, quotes verified against the answer) and back-linked via the entry’s derived_fact_ids — so a Q&A answer becomes reusable, discoverable knowledge rather than being buried in the history.

refresh(mode: str = 'soft', *, ingest_fn=None, apply: bool = True) RefreshReport[source]

Refresh info from changed sources + undistilled Q&A.

ingest_fn(item) supplies extraction (intelligence is external); with apply=False the result is a non-destructive preview. See hired.candidate.refresh.

regenerate_synopsis() str[source]

Rebuild and persist a human-readable synopsis from current facts.

This is a projection — always derived from the fact store, never hand-edited — so it can be regenerated at any time without loss.

save_upload(name: str, data: bytes) None[source]

Store a raw uploaded document by filename (see add_source()).

sources() list[str][source]

Keys of all raw sources the candidate has provided.

supersede(old_fact_id: str, new_fact: Fact) str[source]

Replace old_fact_id with new_fact (invalidate, don’t delete).

property synopsis: str

The last persisted synopsis, regenerating it if absent.

topic(name: str) TopicDossier[source]

Get-or-create the dossier for a subject (overview + optional files).

topics() list[str][source]

Slugs of all topic dossiers.

class hired.CoverLetterData(applicant_name: str, applicant_email: str, company_name: str, position_title: str, applicant_phone: str | None = None, applicant_address: str | None = None, hiring_manager_name: str | None = None, opening_paragraph: str = '', body_paragraphs: list | None = None, closing_paragraph: str = '', date: str | None = None)[source]

Data structure for cover letter generation.

to_dict() Dict[str, Any][source]

Convert to dictionary for template rendering.

class hired.DefaultAIAgent(*, model: str = 'default', api_key: str | None = None)[source]

Default AI agent implementation (mock).

class hired.JDWorkspace(kb, jd_id: str, *, store: JDStore | None = None)[source]

Reports, company research, interview-prep briefings, and parsed jobs for one engagement.

>>> import tempfile, os
>>> os.environ['HIRED_DATA_DIR'] = tempfile.mkdtemp()
>>> from hired.candidate import CandidateKnowledgeBase
>>> kb = CandidateKnowledgeBase()
>>> ws = kb.jd('acme', company='Acme, Inc.', label='Acme roles')
>>> ws.save_report('staff-ds', {'verdict': {'recommendation': 'apply'}})
>>> ws.get_report('staff-ds')['verdict']['recommendation']
'apply'
>>> ws.meta['company']
'Acme, Inc.'
report_versions(job_id: str) list[str][source]

Keys of archived prior versions of a job’s report (chronological).

save_briefing(key: str, data: dict) None[source]

Persist an interview-prep research briefing (keyed by subject/job).

save_company_report(company: str, data: dict) None[source]

Persist a company/people research report (keyed by company name).

save_report(job_id: str, data: dict, *, archive: bool = True) None[source]

Persist the current alignment report, archiving the prior one first.

Archiving (on by default) snapshots any existing report into report_history so the alignment-review agent can diff versions.

class hired.JobAnalyzer(job: JobResult)[source]

Analyze job postings to extract key information for resume tailoring.

extract_keywords(top_n: int = 20) List[str][source]

Extract most important keywords from job posting.

Parameters:

top_n – Number of top keywords to return

Returns:

List of keywords sorted by relevance

extract_requirements() List[str][source]

Extract job requirements from description.

Returns:

List of requirement strings

extract_skills(include_soft_skills: bool = True) Set[str][source]

Extract mentioned skills from job posting.

Parameters:

include_soft_skills – Whether to include soft skills

Returns:

Set of identified skills

get_summary() Dict[str, Any][source]

Get a summary of the job posting.

Returns:

Dictionary with job summary

to_job_info_text() str[source]

Convert job posting to a formatted text suitable for resume generation.

Returns:

Formatted job description text

class hired.JobMatcher(candidate_skills: List[str] | None = None, candidate_keywords: List[str] | None = None, required_skills: List[str] | None = None, min_salary: float | None = None, max_salary: float | None = None, preferred_locations: List[str] | None = None, remote_only: bool = False)[source]

Match candidate profiles against job postings.

Examples

>>> matcher = JobMatcher(candidate_skills=['python', 'django', 'aws'])
>>> scores = matcher.score_jobs(job_results)
>>> top_jobs = matcher.get_top_matches(job_results, n=10)
filter_jobs(jobs: List[JobResult], min_score: float = 50.0) List[JobResult][source]

Filter jobs that meet minimum score threshold.

Parameters:
  • jobs – List of JobResult objects

  • min_score – Minimum score threshold (0-100)

Returns:

List of JobResult objects that meet threshold

get_recommendations(jobs: List[JobResult], top_n: int = 5) str[source]

Get human-readable recommendations based on job matches.

Parameters:
  • jobs – List of JobResult objects

  • top_n – Number of top jobs to include in recommendations

Returns:

Formatted recommendation string

get_top_matches(jobs: List[JobResult], n: int = 10, min_score: float = 0.0) List[MatchScore][source]

Get top N job matches sorted by score.

Parameters:
  • jobs – List of JobResult objects

  • n – Number of top matches to return

  • min_score – Minimum score threshold (0-100)

Returns:

List of MatchScore objects sorted by overall_score descending

identify_skill_gaps(jobs: List[JobResult]) Dict[str, int][source]

Identify skills frequently requested but not possessed by candidate.

Parameters:

jobs – List of JobResult objects to analyze

Returns:

frequency} for missing skills

Return type:

Dictionary of {skill

score_job(job: JobResult) MatchScore[source]

Score a single job against candidate profile.

Parameters:

job – JobResult to score

Returns:

MatchScore object

score_jobs(jobs: List[JobResult]) List[MatchScore][source]

Score multiple jobs.

Parameters:

jobs – List of JobResult objects

Returns:

List of MatchScore objects

class hired.JobResult(title: str, source: str, company: str | None = None, company_url: str | None = None, job_url: str | None = None, location: LocationInfo | None = None, is_remote: bool | None = None, description: str | None = None, job_type: JobType | None = None, compensation: CompensationInfo | None = None, date_posted: datetime | None = None, date_updated: datetime | None = None, application_deadline: datetime | None = None, skills: List[str] = <factory>, benefits: List[str] = <factory>, emails: List[str] = <factory>, raw_data: Dict[str, ~typing.Any]=<factory>)[source]

Standardized job result across all sources.

This provides a unified interface regardless of which source the job was retrieved from.

to_dict() Dict[str, Any][source]

Convert JobResult to dictionary.

class hired.JobSearchSource[source]

Abstract base class for job search sources.

All job search sources must implement this interface to be registered in the system.

abstract property display_name: str

Return the display name of this source (e.g., ‘Indeed’, ‘USAJobs’).

abstractmethod get_setup_instructions() str[source]

Return setup instructions for this source.

Should include: - Where to get API keys if needed - Environment variables or config file settings - URLs for documentation

Returns:

Multi-line string with setup instructions.

abstractmethod is_configured() bool[source]

Check if this source is properly configured.

Returns:

True if the source is ready to use, False otherwise.

abstract property name: str

Return the name of this source (e.g., ‘indeed’, ‘usajobs’).

abstract property requires_auth: bool

Return True if this source requires authentication/API keys.

abstractmethod search(criteria: SearchCriteria) List[JobResult][source]

Search for jobs using the given criteria.

Parameters:

criteria – SearchCriteria object with search parameters

Returns:

List of JobResult objects

Raises:
  • SourceConfigError – If the source is not properly configured

  • Exception – For other errors during search

validate_configured() None[source]

Validate that the source is configured, raise error if not.

Raises:

SourceConfigError – If the source is not properly configured

class hired.JobSources(registry=None)[source]

Main facade for accessing job search sources.

Provides both mapping interface (dict-like access) and attribute access to registered job sources.

Examples

>>> sources = JobSources()
>>> # List all available sources
>>> sources.list()
['jobspy', 'usajobs', 'adzuna']
>>> # Access via attribute
>>> results = sources.jobspy.search(SearchCriteria(query="python developer"))
>>> # Access via mapping
>>> results = sources['indeed'].search(SearchCriteria(query="data scientist"))
>>> # Search across multiple sources
>>> results = sources.search_all(
...     SearchCriteria(query="software engineer", location="San Francisco")
... )
get_info(name: str) Dict[str, any][source]

Get information about a source.

Parameters:

name – Name of the source

Returns:

Dictionary with source information including setup instructions

get_source(name: str) JobSearchSource[source]

Get a source by name.

Parameters:

name – Name of the source

Returns:

JobSearchSource instance

Raises:

KeyError – If source not found

keys() List[str][source]

Get list of source names (dict-like interface).

list() List[str][source]

List all registered sources.

Returns:

List of source names

list_available() List[str][source]

List sources that are configured and ready to use.

Returns:

List of configured source names

list_unconfigured() List[str][source]

List sources that need configuration.

Returns:

List of unconfigured source names

print_status() None[source]

Print the status of all registered sources.

search(source_name: str, criteria: SearchCriteria) List[JobResult][source]

Search using a specific source.

Parameters:
  • source_name – Name of the source to use

  • criteria – Search criteria

Returns:

List of JobResult objects

search_all(criteria: SearchCriteria, sources: List[str] | None = None, skip_unconfigured: bool = True) List[JobResult][source]

Search across multiple sources.

Parameters:
  • criteria – Search criteria

  • sources – Optional list of source names. If None, uses all available sources.

  • skip_unconfigured – If True, skip sources that are not configured

Returns:

Combined list of JobResult objects from all sources

class hired.JobType(value)[source]

Standardized job types across all sources.

class hired.LLMConfig(model: str, temperature: float = 0.7, max_tokens: int | None = None, top_p: float = 1.0, provider: str = 'openai', api_key: str | None = None, base_url: str | None = None, extra_params: dict = <factory>)[source]

Configuration for LLM model selection and parameters.

>>> config = LLMConfig(model="gpt-4", temperature=0.7)
>>> config.model
'gpt-4'
to_dspy_lm()[source]

Convert to DSPy LM instance.

to_langchain_kwargs() dict[source]

Convert to LangChain model kwargs.

class hired.LLMResumeAgent(*, model: str = 'gpt-4o-mini', client: Any | None = None, api_key: str | None = None)[source]

AI agent that tailors a candidate’s profile to a job via an LLM.

Opt-in alternative to DefaultAIAgent (which is a pass-through). It is dependency-injected and lazy: openai is imported only when an agent is used without an injected client, so importing hired never requires openai, and no API key is read at construction time. Inject a client (anything exposing the OpenAI-style chat.completions.create) to test without network or secrets.

>>> class _FakeClient:
...     class chat:
...         class completions:
...             @staticmethod
...             def create(**_):
...                 ...
class hired.MatchScore(job: JobResult, overall_score: float, skill_match_score: float, keyword_match_score: float, matched_skills: Set[str] = <factory>, missing_skills: Set[str] = <factory>, matched_keywords: Set[str] = <factory>, compensation_match: bool | None = None, location_match: bool | None = None)[source]

Score for a job match.

get_summary() str[source]

Get human-readable summary.

to_dict() Dict[str, Any][source]

Convert to dictionary.

class hired.RenderingConfig(format: str = 'pdf', theme: str = 'default', custom_css: str | None = None, custom_template: str | None = None)[source]

Configuration for resume rendering.

class hired.Requirement(*, id: str = <factory>, text: str, skill_type: SkillType = SkillType.TECHNICAL, requirement_class: RequirementClass = RequirementClass.DIFFERENTIATOR, required_level: int = 3)[source]

One atomic requirement extracted verbatim from a job description.

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class hired.RequirementRecord(*, requirement: Requirement, match_state: MatchState = MatchState.UNKNOWN, field_completeness: FieldCompleteness = FieldCompleteness.OPEN, bucket: Bucket | None = None, match_type: MatchType = MatchType.NONE, candidate_level: int = 0, gap_size: int = 0, source_skill: str | None = None, adjacency_basis: str | None = None, transferability: Transferability | None = None, closeability: Closeability | None = None, close_method: CloseMethod | None = None, time_to_close: TimeToClose | None = None, ai_leverage: AILeverage = AILeverage.NONE, confidence: ConfidenceLevel = ConfidenceLevel.LOW, uncertainty_reason: str | None = None, evidence: Evidence | None = None, impact: int = 3, info_gain: float = 0.0, needs_clarification: bool = False, talking_point: str | None = None)[source]

The analysis of one requirement against the candidate’s knowledge.

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

hired.ResumeContent

alias of ResumeSchemaExtended

class hired.ResumeExpertAgent(*, llm_config: LLMConfig | None = None, model_registry: ModelRegistry | None = None)[source]

Autonomous agent that uses ResumeSession as a tool.

Operates in auto mode, making decisions about expansion, distillation, search, and generation operations to produce complete resumes.

>>> config = LLMConfig(model="gpt-4")
>>> agent = ResumeExpertAgent(llm_config=config)
>>> agent.llm_config.model
'gpt-4'
create_resume(session: ResumeSession, *, mode: str = 'standard', max_iterations: int = 5) str[source]

Autonomously create resume using session as tool.

Operates in plan-and-execute pattern: 1. Analyze job and candidate info 2. Plan resume creation strategy 3. Execute operations (expand, distill, match) 4. Generate resume 5. Critique and refine

execute_plan(session: ResumeSession, plan: Plan, *, interactive: bool = False, approval_callback: Callable[[PlanStep], str] | None = None) dict[source]

Execute a plan step by step.

Parameters:
  • session – Resume session to operate on

  • plan – Plan to execute

  • interactive – If True, pause after each step for approval

Returns:

Dict with execution results and final outputs

propose_plan(session: ResumeSession, *, mode: str = 'standard') Plan[source]

Generate execution plan for resume creation.

Returns structured Plan object that can be edited before execution.

revise_plan(plan: Plan, instruction: str) Plan[source]

Revise plan based on natural language instruction.

Uses LLM to interpret instruction and modify plan accordingly.

class hired.ResumeSchema(*, field_schema: str | None = None, basics: Basics | None = None, work: list[WorkItem] | None = None, volunteer: list[VolunteerItem] | None = None, education: list[EducationItem] | None = None, awards: list[Award] | None = None, certificates: list[Certificate] | None = None, publications: list[Publication] | None = None, skills: list[Skill] | None = None, languages: list[Language] | None = None, interests: list[Interest] | None = None, references: list[Reference] | None = None, projects: list[Project] | None = None, meta: Meta | None = None)[source]
model_config = {'extra': 'forbid'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class hired.ResumeSchemaExtended(*, field_schema: str | None = None, basics: Basics | None = None, work: list[WorkItem] | None = None, volunteer: list[VolunteerItem] | None = None, education: list[EducationItem] | None = None, awards: list[Award] | None = None, certificates: list[Certificate] | None = None, publications: list[Publication] | None = None, skills: list[Skill] | None = None, languages: list[Language] | None = None, interests: list[Interest] | None = None, references: list[Reference] | None = None, projects: list[Project] | None = None, meta: Meta | None = None, **extra_data: Any)[source]

Extended version of ResumeSchema that allows extra fields for custom sections.

This class inherits all the validation and structure from ResumeSchema but allows additional fields to be stored for custom sections.

model_config = {'extra': 'allow'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class hired.ResumeSession(job_info: str, candidate_info: str, *, mode: OperationMode = OperationMode.MANUAL, system_prompt: str | None = None, max_recent_turns: int = 10, llm_config: LLMConfig | None = None, model_registry: ModelRegistry | None = None, auto_persist: bool = True, data_dir: Path | None = None, name: str | None = None)[source]

Stateful conversation session for resume creation.

Provides manual chat interface where users give natural language instructions to perform expansion, distillation, search, and generation operations. Maintains conversation history and structured state.

>>> config = LLMConfig("gpt-4")
>>> session = ResumeSession(
...     job_info="Senior ML Engineer at TechCo",
...     candidate_info="5 years Python, ML experience",
...     llm_config=config
... )
>>> session.llm_config.model
'gpt-4'
chat(user_message: str) str[source]

Process user instruction and return assistant response.

This is the main interface for manual mode operation. Automatically persists session after each turn if auto_persist enabled.

property history: list[Turn]

Get all conversation turns.

classmethod list_persisted(data_dir: Path | None = None) Iterable[dict][source]

List all persisted sessions.

>>> for session_info in ResumeSession.list_persisted():
...     print(session_info['session_id'])
classmethod load(session_id: str, *, data_dir: Path | None = None, llm_config: LLMConfig | None = None) ResumeSession | None[source]

Load session from persistent storage.

>>> session = ResumeSession.load("abc123def456")
>>> session.session_id if session else None
'abc123def456'
property metadata: dict

Return a small metadata dict for quick inspection.

Includes: session_id, name, created_at (iso), n_turns, mode, model

save(data_dir: Path | None = None) Path[source]

Manually save session to persistent storage.

Returns path to saved session file.

property snapshots: list[SessionSnapshot]

Get all session snapshots.

property state: SessionState

Get current session state.

switch_mode(mode: OperationMode) None[source]

Switch between manual and auto operation modes.

class hired.SearchCriteria(query: str, location: str | None = None, country: str | None = None, city: str | None = None, state: str | None = None, postal_code: str | None = None, distance_miles: int | None = None, job_type: JobType | None = None, is_remote: bool | None = None, posted_within_days: int | None = None, results_wanted: int = 20, offset: int = 0, min_salary: float | None = None, max_salary: float | None = None, keywords: List[str] = <factory>, exclude_keywords: List[str] = <factory>, source_params: Dict[str, ~typing.Any]=<factory>)[source]

Standardized search criteria across all sources.

Different sources may not support all criteria, but this provides a consistent interface for users.

hired.check_resume_ats(resume_content: Dict[str, Any], job: JobResult | None = None) ATSReport[source]

Quick utility to check resume ATS compatibility.

Parameters:
  • resume_content – Resume content as dictionary (JSON Resume format)

  • job – Optional JobResult for keyword matching

Returns:

ATSReport

Examples

>>> from hired import mk_content_for_resume
>>> from hired.ats_checker import check_resume_ats
>>>
>>> resume = mk_content_for_resume(candidate_info, job_info)
>>> report = check_resume_ats(resume.model_dump(), job_result)
>>> print(report.get_summary())
hired.classify(record: RequirementRecord) RequirementRecord[source]

Fill gap_size and bucket (and needs_clarification) in place.

Returns the same record for convenience.

hired.extract_job_keywords(job: JobResult, top_n: int = 20) List[str][source]

Extract top keywords from a job posting.

Parameters:
  • job – JobResult object

  • top_n – Number of keywords to return

Returns:

List of top keywords

hired.generate_cover_letter_content(candidate_info: Dict[str, Any], job_info: Dict[str, Any] | JobResult, tone: str = 'professional') CoverLetterData[source]

Generate cover letter content from candidate and job information.

Parameters:
  • candidate_info – Candidate information (resume dict or basics)

  • job_info – Job information (dict, text, or JobResult)

  • tone – Tone of the letter (‘professional’, ‘enthusiastic’, ‘formal’)

Returns:

CoverLetterData object with generated content

Examples

>>> data = generate_cover_letter_content(
...     candidate_info={'basics': {'name': 'Jane Doe', 'email': 'jane@example.com'}},
...     job_info={'title': 'Software Engineer', 'company': 'TechCorp'},
... )
hired.get_job_skills(job: JobResult) Set[str][source]

Extract skills mentioned in job posting.

Parameters:

job – JobResult object

Returns:

Set of skills

hired.job_to_text(job: JobResult) str[source]

Convert a JobResult to formatted text for resume generation.

Parameters:

job – JobResult object

Returns:

Formatted text description

hired.mk_content_for_resume(candidate_info_src: ContentSource | str | dict, job_info_src: ContentSource | str | dict | JobResult, *, agent: Any | None = None, validate: bool = True, strict: bool = False) ResumeSchemaExtended[source]

Generate resume content from candidate and job information.

Parameters:
  • candidate_info_src – Candidate information as ContentSource, file path, or dict

  • job_info_src – Job information as ContentSource, file path, dict, or JobResult

  • agent – Optional AI agent for content generation

  • validate – Whether to validate the generated content

  • strict – Whether to use strict validation

Returns:

ResumeSchemaExtended object with generated content

Examples

>>> # Using file paths
>>> content = mk_content_for_resume("candidate.json", "job.txt")
>>>
>>> # Using JobResult from job search
>>> from hired import JobSources, SearchCriteria
>>> sources = JobSources()
>>> jobs = sources.jobspy.search(SearchCriteria(query="python developer"))
>>> content = mk_content_for_resume(candidate_dict, jobs[0])
hired.mk_cover_letter(candidate_info: Dict[str, Any], job_info: Dict[str, Any] | JobResult, *, tone: str = 'professional', format: str = 'text', output_path: str | None = None) str[source]

Generate and render a cover letter.

Parameters:
  • candidate_info – Candidate information (resume dict or basics)

  • job_info – Job information (dict, text, or JobResult)

  • tone – Tone of the letter (‘professional’, ‘enthusiastic’, ‘formal’)

  • format – Output format (‘text’, ‘html’, ‘markdown’)

  • output_path – Optional path to save the cover letter

Returns:

Rendered cover letter as string

Examples

>>> from hired import mk_cover_letter, JobSources, SearchCriteria
>>>
>>> # From job search result
>>> sources = JobSources()
>>> jobs = sources.jobspy.search(SearchCriteria(query="software engineer"))
>>>
>>> letter = mk_cover_letter(
...     candidate_info={'basics': {'name': 'Jane Doe', 'email': 'jane@example.com'}},
...     job_info=jobs[0],
...     format='html'
... )
hired.mk_resume(content: ResumeSchemaExtended | dict, rendering: RenderingConfig | dict | None = None, *, output_path: str | None = None, strict: bool = False) bytes[source]

Render resume content to final format.

hired.quick_match(candidate_skills: List[str], jobs: List[JobResult], top_n: int = 10) List[MatchScore][source]

Quick utility function to match jobs against candidate skills.

Parameters:
  • candidate_skills – List of candidate’s skills

  • jobs – List of JobResult objects

  • top_n – Number of top matches to return

Returns:

List of top MatchScore objects

Examples

>>> from hired import JobSources, SearchCriteria
>>> from hired.matching import quick_match
>>>
>>> sources = JobSources()
>>> jobs = sources.jobspy.search(SearchCriteria(query="python developer"))
>>>
>>> matches = quick_match(
...     candidate_skills=['python', 'django', 'postgresql'],
...     jobs=jobs,
...     top_n=5
... )
>>>
>>> for match in matches:
...     print(match.get_summary())
hired.render_report_markdown(report: AlignmentReport) str[source]

Render the report as a Markdown string.