SPB Git forge

spb/doc-api

Public
2commits 1branches 0releases
15.7 MBsize
maindefault branch
13 days agolast push
Python 88.3% TypeScript 7.6% Shell 4.1%
3.6 KB · 82 lines python
Raw Blame History
1#!/usr/bin/env python32"""Re-runnable OpenAI model discovery: GET /v1/models -> sanitized snapshot + diff against the previous run.34- Calls GET /v1/models (free) via scripts/live.py (auth injected, call logged to reports/live-requests.jsonl).5- Diffs the returned ids against sources/openai/models-api-raw.json (previous run): prints NEW / REMOVED ids and6  any change of `shutdown_date`, and writes sources/openai/models-diff.json.7- Saves the sanitized listing to sources/openai/models-api-raw.json and the id list to sources/openai/model-ids.txt8  (unless --dry-run). The previous listing is kept as sources/openai/models-api-raw.prev.json.910Usage: python3 scripts/discover_openai_models.py [--dry-run]11Exit code 0 always (a diff is information, not an error); prints a one-line summary.12"""13from __future__ import annotations1415import json16import sys17from datetime import datetime, timezone18from pathlib import Path1920sys.path.insert(0, str(Path(__file__).resolve().parent.parent))21from scripts.live import openai_request, save_sanitized  # noqa: E4022223ROOT = Path(__file__).resolve().parent.parent24RAW = ROOT / "sources/openai/models-api-raw.json"25PREV = ROOT / "sources/openai/models-api-raw.prev.json"26IDS = ROOT / "sources/openai/model-ids.txt"27DIFF = ROOT / "sources/openai/models-diff.json"282930def main() -> int:31    dry = "--dry-run" in sys.argv32    previous = json.loads(RAW.read_text()) if RAW.exists() else {"data": []}33    prev_models = {m["id"]: m for m in previous.get("data", [])}3435    st, body, hdrs = openai_request("GET", "/v1/models", note="discover_openai_models")36    if st != 200 or not isinstance(body, dict):37        print(f"GET /v1/models -> HTTP {st}; aborting without writing", file=sys.stderr)38        return 039    models = sorted(body.get("data", []), key=lambda m: (m.get("created", 0), m["id"]))40    cur_models = {m["id"]: m for m in models}4142    new_ids = sorted(set(cur_models) - set(prev_models))43    removed_ids = sorted(set(prev_models) - set(cur_models))44    changed = []45    for mid in sorted(set(cur_models) & set(prev_models)):46        a, b = prev_models[mid], cur_models[mid]47        for k in ("shutdown_date", "owned_by", "created"):48            if a.get(k) != b.get(k):49                changed.append({"id": mid, "field": k, "before": a.get(k), "after": b.get(k)})5051    now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")52    diff = {53        "checked_at": now,54        "previous_count": len(prev_models), "current_count": len(cur_models),55        "new": [cur_models[i] for i in new_ids],56        "removed": [prev_models[i] for i in removed_ids],57        "changed": changed,58        "dry_run": dry,59    }60    for m in diff["new"]:61        print(f"NEW      {m['id']}  (owned_by={m.get('owned_by')}, shutdown_date={m.get('shutdown_date')})")62    for m in diff["removed"]:63        print(f"REMOVED  {m['id']}  (was shutdown_date={m.get('shutdown_date')})")64    for c in changed:65        print(f"CHANGED  {c['id']}.{c['field']}: {c['before']} -> {c['after']}")66    print(f"summary: {len(cur_models)} ids live, {len(new_ids)} new, {len(removed_ids)} removed, {len(changed)} changed")6768    save_sanitized(diff, DIFF)69    if not dry:70        if RAW.exists():71            PREV.write_text(RAW.read_text())72        save_sanitized({"object": body.get("object", "list"), "retrieved_at": now, "data": models}, RAW)73        IDS.write_text("\n".join(sorted(cur_models)) + "\n")74        print(f"wrote {RAW.relative_to(ROOT)}, {IDS.relative_to(ROOT)}, {DIFF.relative_to(ROOT)}")75    else:76        print(f"dry run: wrote only {DIFF.relative_to(ROOT)}")77    return 0787980if __name__ == "__main__":81    sys.exit(main())82