Spaces:
Running
Running
| """``talentry-rank`` - the one command that produces the submission CSV. | |
| This is the entry point pinned in ``submission_metadata.yaml``'s | |
| ``reproduce_command`` field: | |
| python -m talentry.cli.rank --candidates ./candidates.jsonl --out ./submission.csv | |
| The command is deliberately tiny - all the engineering lives in the package, | |
| and this file just argparses, dispatches and reports. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import logging | |
| import sys | |
| import time | |
| from pathlib import Path | |
| from talentry import __version__ | |
| from talentry.io.candidates import load_candidates | |
| from talentry.io.submission import write_submission, write_submission_xlsx | |
| from talentry.ranker import parse_job_description, rank_candidates | |
| def _build_parser() -> argparse.ArgumentParser: | |
| p = argparse.ArgumentParser( | |
| prog="talentry-rank", | |
| description="Rank the top 100 candidates from a Redrob JSONL pool against a JD.", | |
| ) | |
| p.add_argument( | |
| "--candidates", | |
| required=True, | |
| type=Path, | |
| help="Path to candidates.jsonl (gzip ok).", | |
| ) | |
| p.add_argument( | |
| "--jd", | |
| type=Path, | |
| default=None, | |
| help="Path to job description text file. Defaults to the default JD shipped with the package.", | |
| ) | |
| p.add_argument( | |
| "--out", | |
| type=Path, | |
| default=Path("submission.csv"), | |
| help=( | |
| "Output path. Format is inferred from the extension: " | |
| ".csv -> CSV, .xlsx -> Excel. Default: submission.csv" | |
| ), | |
| ) | |
| p.add_argument( | |
| "--also-xlsx", | |
| action="store_true", | |
| help="Also emit a sibling .xlsx file next to --out (handy for human review).", | |
| ) | |
| p.add_argument( | |
| "--top-k", | |
| type=int, | |
| default=100, | |
| help="Number of candidates to keep. Default: 100 (hackathon requirement).", | |
| ) | |
| p.add_argument( | |
| "--limit", | |
| type=int, | |
| default=None, | |
| help="Optional cap on candidates loaded (useful for smoke tests).", | |
| ) | |
| p.add_argument( | |
| "--quiet", | |
| action="store_true", | |
| help="Suppress per-stage progress logging.", | |
| ) | |
| p.add_argument("--version", action="version", version=f"talentry-ai {__version__}") | |
| return p | |
| def main(argv: list[str] | None = None) -> int: | |
| args = _build_parser().parse_args(argv) | |
| logging.basicConfig( | |
| level=logging.WARNING if args.quiet else logging.INFO, | |
| format="%(message)s", | |
| stream=sys.stderr, | |
| ) | |
| log = logging.getLogger("talentry.cli") | |
| log.info("[talentry-rank] v%s", __version__) | |
| log.info("[talentry-rank] loading candidates from %s …", args.candidates) | |
| t0 = time.perf_counter() | |
| candidates = load_candidates(args.candidates, limit=args.limit) | |
| log.info( | |
| "[talentry-rank] loaded %d candidates in %.2fs", len(candidates), time.perf_counter() - t0 | |
| ) | |
| jd = parse_job_description(args.jd) | |
| log.info("[talentry-rank] JD parsed - title=%r seniority=%s", jd.title, jd.seniority) | |
| ranked = rank_candidates(candidates, jd, top_k=args.top_k, progress=not args.quiet) | |
| if len(ranked) < args.top_k: | |
| log.warning( | |
| "[talentry-rank] only %d candidates ranked (< top_k=%d). " | |
| "Submission requires exactly 100 rows.", | |
| len(ranked), | |
| args.top_k, | |
| ) | |
| strict = args.top_k == 100 | |
| out_ext = args.out.suffix.lower() | |
| if out_ext == ".xlsx": | |
| out = write_submission_xlsx(ranked, args.out, strict=strict) | |
| else: | |
| out = write_submission(ranked, args.out, strict=strict) | |
| log.info( | |
| "[talentry-rank] wrote %s submission → %s", | |
| "strict-validated" if strict else f"non-strict (top_k={args.top_k})", | |
| out, | |
| ) | |
| # Optional sibling .xlsx for human review. | |
| if args.also_xlsx and out_ext != ".xlsx": | |
| sibling = args.out.with_suffix(".xlsx") | |
| write_submission_xlsx(ranked, sibling, strict=strict) | |
| log.info("[talentry-rank] also wrote XLSX → %s", sibling) | |
| return 0 | |
| if __name__ == "__main__": # pragma: no cover | |
| raise SystemExit(main()) | |