SPB Git forge

spb/job-ka

Public
231commits 1branches 0releases
38.4 MBsize
maindefault branch
45 min agolast push
HTML 82% Python 14.7% TypeScript 1.9% CSS 1% JavaScript 0.5%
3.3 KB · 91 lines python
Raw Blame History
1# =============================================================================2# Job·Ka — Groupe KA3# Auteur  : Simon-Pierre Boucher4# Contact : contact@spboucher.ai5# Fichier : scripts/backfill_enrich.py6# Rôle    : Backfill de l'enrichissement Phase 3 (exigences structurées,7#           séniorité, avantages) sur les offres déjà en base — sans toucher8#           content_hash (la prochaine synchro réalignera naturellement)9# Créé    : 2026-08-25   Modifié : 2026-08-2510# =============================================================================11"""Réapplique les nouveaux extracteurs (extract_requirements, parse_seniority,12extract_benefits élargi) aux offres stockées, à partir du titre et de la13description déjà en base. Idempotent : ne remplit que les champs manquants,14n'écrase jamais une valeur fournie par un ATS.1516Usage : python -m scripts.backfill_enrich [--all]   (défaut : offres actives)17"""18from __future__ import annotations1920import json21import sys22import time23from pathlib import Path2425sys.path.insert(0, str(Path(__file__).resolve().parent.parent))2627from jobka import db                                    # noqa: E40228from jobka.normalize import (                           # noqa: E40229    extract_benefits, extract_requirements, parse_seniority)303132def run(only_active: bool = True) -> dict:33    con = db.connect()   # applique aussi la migration (colonne seniority)34    where = "WHERE active=1" if only_active else ""35    rows = con.execute(36        f"SELECT uid, title, description, employment_type, requirements,"37        f" benefits, seniority FROM jobs {where}").fetchall()3839    stats = {"scanned": len(rows), "requirements": 0, "seniority": 0,40             "benefits": 0, "updated": 0}41    t0 = time.time()42    for r in rows:43        try:44            reqs = json.loads(r["requirements"] or "{}")45        except ValueError:46            reqs = {}47        try:48            bens = json.loads(r["benefits"] or "[]")49        except ValueError:50            bens = []5152        changed = False53        extracted = extract_requirements(r["title"] or "", r["description"] or "")54        added_req = {k: v for k, v in extracted.items() if k not in reqs}55        if added_req:56            reqs.update(added_req)57            stats["requirements"] += 158            changed = True5960        seniority = r["seniority"]61        if not seniority:62            seniority = parse_seniority(r["title"] or "", reqs,63                                        r["employment_type"])64            if seniority:65                stats["seniority"] += 166                changed = True6768        if not bens and r["description"]:69            bens = extract_benefits(r["description"])70            if bens:71                stats["benefits"] += 172                changed = True7374        if changed:75            con.execute(76                "UPDATE jobs SET requirements=?, seniority=?, benefits=?"77                " WHERE uid=?",78                (json.dumps(reqs, ensure_ascii=False), seniority,79                 json.dumps(bens, ensure_ascii=False), r["uid"]))80            stats["updated"] += 18182    con.commit()83    con.close()84    stats["seconds"] = round(time.time() - t0, 1)85    return stats868788if __name__ == "__main__":89    out = run(only_active="--all" not in sys.argv)90    print(f"[backfill-enrich] {out}")91