Download code/docs/workbook/build_workbook.py from viai957/align: direct link, hf CLI and curl.
- Browser
- Download file 4.83 kB
-
https://huggingface.co/viai957/align/resolve/main/code/docs/workbook/build_workbook.py
- Command line
-
hf download hf://viai957/align/code/docs/workbook/build_workbook.py
-
curl -L -o build_workbook.py https://huggingface.co/viai957/align/resolve/main/code/docs/workbook/build_workbook.py
4.83 kB
| """Build the Leanstral-8B project workbook from the JSON sheets in ./data. | |
| The xlsx is a BUILD ARTEFACT: edit data/*.json (or use the `journal` / `status` | |
| subcommands below), never the workbook, or the next build will overwrite your edit. | |
| Style follows the Duplex training workbook: one header row (bold white Calibri on | |
| #305496, centred, wrapped), body cells top-aligned and wrapped, frozen header row, | |
| autofilter over the used range, and Source / Confidence / Status columns. | |
| python build_workbook.py # rebuild Leanstral_8B_Workbook.xlsx | |
| python build_workbook.py journal "event" "result" "evidence" "next action" | |
| python build_workbook.py status WBS 4.1 "Done" # set the Status cell of one row by Id | |
| Docs tooling, not align runtime: it is outside the dependency firewall's scan and | |
| may import openpyxl. | |
| """ | |
| from __future__ import annotations | |
| import contextlib | |
| import datetime as dt | |
| import fcntl | |
| import json | |
| import os | |
| import sys | |
| from pathlib import Path | |
| HERE = Path(__file__).resolve().parent | |
| DATA = HERE / "data" | |
| OUT = HERE / "Leanstral_8B_Workbook.xlsx" | |
| LOCK = DATA / ".workbook.lock" | |
| def locked(): | |
| """One writer at a time: journal/status are read-modify-write on data/*.json, and two concurrent | |
| CLI calls would otherwise read the same snapshot and drop each other's change.""" | |
| LOCK.parent.mkdir(parents=True, exist_ok=True) | |
| with open(LOCK, "w") as fh: | |
| fcntl.flock(fh, fcntl.LOCK_EX) | |
| try: | |
| yield | |
| finally: | |
| fcntl.flock(fh, fcntl.LOCK_UN) | |
| # sheet order in the workbook; each name maps to data/<name>.json | |
| SHEETS = ["README", "WBS", "Recipe_Stack", "Datasets", "Data_Gaps", "Evals_Gates", | |
| "Experiment_Plan", "Journal", "Sources"] | |
| def load(name: str) -> dict: | |
| d = json.loads((DATA / f"{name}.json").read_text(encoding="utf-8")) | |
| cols, widths = d["columns"], d["widths"] | |
| if len(cols) != len(widths): | |
| raise SystemExit(f"{name}: {len(cols)} columns but {len(widths)} widths") | |
| for i, r in enumerate(d["rows"]): | |
| if len(r) != len(cols): | |
| raise SystemExit(f"{name} row {i + 2}: {len(r)} cells, expected {len(cols)}: {r[:2]}") | |
| return d | |
| def save(name: str, d: dict) -> None: | |
| p = DATA / f"{name}.json" | |
| tmp = p.with_name(f"{p.name}.tmp{os.getpid()}") | |
| tmp.write_text(json.dumps(d, indent=1, ensure_ascii=False) + "\n", encoding="utf-8") | |
| os.replace(tmp, p) | |
| def build() -> Path: | |
| from openpyxl import Workbook | |
| from openpyxl.styles import Alignment, Font, PatternFill | |
| from openpyxl.utils import get_column_letter | |
| head_font = Font(name="Calibri", bold=True, color="FFFFFFFF") | |
| head_fill = PatternFill("solid", fgColor="FF305496") | |
| head_align = Alignment(horizontal="center", vertical="center", wrap_text=True) | |
| body_font = Font(name="Calibri", size=11) | |
| body_align = Alignment(vertical="top", wrap_text=True) | |
| wb = Workbook() | |
| wb.remove(wb.worksheets[0]) | |
| for name in SHEETS: | |
| d = load(name) | |
| ws = wb.create_sheet(name) | |
| ws.append(d["columns"]) | |
| for c in ws[1]: | |
| c.font, c.fill, c.alignment = head_font, head_fill, head_align | |
| for r in d["rows"]: | |
| ws.append(r) | |
| for row in ws.iter_rows(min_row=2): | |
| for c in row: | |
| c.font, c.alignment = body_font, body_align | |
| for i, w in enumerate(d["widths"], start=1): | |
| ws.column_dimensions[get_column_letter(i)].width = w | |
| ws.freeze_panes = "A2" | |
| ws.auto_filter.ref = f"A1:{get_column_letter(len(d['columns']))}{ws.max_row}" | |
| tmp = OUT.with_name(f"{OUT.stem}.tmp{os.getpid()}.xlsx") | |
| wb.save(tmp) | |
| os.replace(tmp, OUT) | |
| return OUT | |
| def journal(event: str, result: str, evidence: str, nxt: str) -> None: | |
| d = load("Journal") | |
| d["rows"].append([dt.date.today().isoformat(), event, result, evidence, nxt]) | |
| save("Journal", d) | |
| def set_status(sheet: str, row_id: str, status: str) -> None: | |
| d = load(sheet) | |
| col = d["columns"].index("Status") | |
| hits = [r for r in d["rows"] if r[0] == row_id] | |
| if len(hits) != 1: | |
| raise SystemExit(f"{sheet}: {len(hits)} rows with Id {row_id!r}") | |
| hits[0][col] = status | |
| save(sheet, d) | |
| def main(argv: list[str]) -> int: | |
| with locked(): | |
| return _main(argv) | |
| def _main(argv: list[str]) -> int: | |
| if argv[:1] == ["journal"]: | |
| if len(argv) != 5: | |
| raise SystemExit("usage: journal EVENT RESULT EVIDENCE NEXT") | |
| journal(*argv[1:]) | |
| elif argv[:1] == ["status"]: | |
| if len(argv) != 4: | |
| raise SystemExit("usage: status SHEET ID STATUS") | |
| set_status(*argv[1:]) | |
| elif argv: | |
| raise SystemExit(__doc__) | |
| print(build()) | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main(sys.argv[1:])) | |