Download reference/refresh-capabilities.py from olaservo/sandyland: direct link, hf CLI and curl.
- Browser
- Download file 9.12 kB
-
https://huggingface.co/spaces/olaservo/sandyland/resolve/main/reference/refresh-capabilities.py
- Command line
-
hf download hf://spaces/olaservo/sandyland/reference/refresh-capabilities.py
-
curl -L -o refresh-capabilities.py https://huggingface.co/spaces/olaservo/sandyland/resolve/main/reference/refresh-capabilities.py
9.12 kB
| """Re-pull `inference-provider-capabilities.jsonl` from the HF Inference Providers catalog. | |
| The snapshot next to this script is dated data (see the `.md`): the repo convention is to | |
| re-pull whenever it is more than ~7 days old, because provider capability booleans, prices, | |
| and even whole `(model, provider)` routes churn week to week. | |
| What it does: fetch the catalog's backing endpoint (the same one the HF Inference Providers | |
| page reads), keep only `status: "live"` provider rows, flatten each to one record, stamp every | |
| record with the pull date, and write the JSONL sorted by model id (case-insensitively) then | |
| provider β the stable order the file has always used, so a re-pull diffs cleanly. | |
| It writes the DATA only. The `.md`'s prose β snapshot date, row/model counts, the provider | |
| capability table, the notable-gaps bullets, the cheapest-routes table β is hand-maintained; | |
| `--summary` prints the recomputed numbers to paste in, and `--diff` reports what changed | |
| against the committed snapshot so the drift is easy to write up. | |
| python refresh-capabilities.py --diff --summary # pull + report (writes the JSONL) | |
| python refresh-capabilities.py --dry-run --diff # report only, write nothing | |
| python refresh-capabilities.py --retrieved 2026-07-27 # override the stamp (default: today) | |
| Needs no API key β the catalog endpoint is public. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import urllib.request | |
| from collections import defaultdict | |
| from datetime import date | |
| from pathlib import Path | |
| from typing import Any | |
| _HERE = Path(__file__).resolve().parent | |
| OUT = _HERE / "inference-provider-capabilities.jsonl" | |
| ENDPOINT = "https://router.huggingface.co/v1/models" | |
| SOURCE = "https://huggingface.co/inference/models" | |
| # Record field order β frozen so a re-pull produces a minimal diff. Documented in the .md. | |
| FIELDS = ("model", "owned_by", "provider", "context_length", "input_price_per_mtok", | |
| "output_price_per_mtok", "supports_tools", "supports_structured_output", | |
| "is_model_author", "retrieved", "source", "endpoint") | |
| def _price(v: Any) -> float | None: | |
| """USD per 1M tokens as the catalog reports it, rounded to kill float noise | |
| (the endpoint returns e.g. 0.9299999999999999 for a $0.93 route).""" | |
| return None if v is None else round(float(v), 6) | |
| def fetch(endpoint: str = ENDPOINT) -> list[dict[str, Any]]: | |
| with urllib.request.urlopen(endpoint, timeout=120) as resp: | |
| return json.load(resp)["data"] | |
| def flatten(models: list[dict[str, Any]], retrieved: str) -> list[dict[str, Any]]: | |
| rows: list[dict[str, Any]] = [] | |
| for m in models: | |
| for p in m.get("providers") or []: | |
| if p.get("status") != "live": | |
| continue | |
| pricing = p.get("pricing") or {} | |
| rows.append({ | |
| "model": m["id"], | |
| "owned_by": m.get("owned_by"), | |
| "provider": p.get("provider"), | |
| "context_length": p.get("context_length"), | |
| "input_price_per_mtok": _price(pricing.get("input")), | |
| "output_price_per_mtok": _price(pricing.get("output")), | |
| # Absent/None reads as "the provider doesn't expose it" β coerce so the | |
| # column is a clean boolean for consumers that filter on it. | |
| "supports_tools": bool(p.get("supports_tools")), | |
| "supports_structured_output": bool(p.get("supports_structured_output")), | |
| "is_model_author": bool(p.get("is_model_author")), | |
| "retrieved": retrieved, | |
| "source": SOURCE, | |
| "endpoint": endpoint_of(m), | |
| }) | |
| rows.sort(key=lambda r: (r["model"].lower(), r["provider"])) | |
| return rows | |
| def endpoint_of(_model: dict[str, Any]) -> str: | |
| return ENDPOINT | |
| def _read_committed() -> list[dict[str, Any]]: | |
| if not OUT.exists(): | |
| return [] | |
| return [json.loads(line) for line in OUT.read_text(encoding="utf-8").splitlines() if line.strip()] | |
| def report_diff(old: list[dict[str, Any]], new: list[dict[str, Any]]) -> None: | |
| """What changed vs the committed snapshot, keyed by (model, provider) and ignoring | |
| the `retrieved` stamp (which changes on every pull by construction).""" | |
| def index(rows: list[dict[str, Any]]) -> dict[tuple[str, str], dict[str, Any]]: | |
| return {(r["model"], r["provider"]): {k: v for k, v in r.items() if k != "retrieved"} for r in rows} | |
| o, n = index(old), index(new) | |
| prev_date = old[0].get("retrieved") if old else "(none)" | |
| added, removed = sorted(n.keys() - o.keys()), sorted(o.keys() - n.keys()) | |
| flipped = [(k, {f: (o[k][f], n[k][f]) for f in o[k] if o[k][f] != n[k][f]}) | |
| for k in sorted(o.keys() & n.keys()) if o[k] != n[k]] | |
| print(f"\n--- drift vs committed snapshot ({prev_date}) ---") | |
| print(f"{len(added)} added, {len(removed)} removed, {len(flipped)} changed " | |
| f"({len(o)} -> {len(n)} rows)") | |
| for k in added: | |
| print(f" + {k[0]} @ {k[1]}") | |
| for k in removed: | |
| print(f" - {k[0]} @ {k[1]}") | |
| for k, d in flipped: | |
| print(f" ~ {k[0]} @ {k[1]}: " + ", ".join(f"{f} {a}->{b}" for f, (a, b) in d.items())) | |
| def report_summary(rows: list[dict[str, Any]]) -> None: | |
| """Recompute the hand-maintained numbers in the .md so they can be pasted in.""" | |
| both = [r for r in rows if r["supports_tools"] and r["supports_structured_output"]] | |
| tools_only = [r for r in rows if r["supports_tools"] and not r["supports_structured_output"]] | |
| print(f"\n--- .md summary numbers ---") | |
| print(f"Rows: {len(rows)} live (model, provider) pairs across " | |
| f"{len({r['model'] for r in rows})} models and {len({r['provider'] for r in rows})} providers.") | |
| print(f"Both tools + structured output: {len(both)} provider rows across " | |
| f"{len({r['model'] for r in both})} models. Tools-only: {len(tools_only)} rows.") | |
| profile: dict[str, list[int]] = defaultdict(lambda: [0, 0, 0]) | |
| for r in rows: | |
| e = profile[r["provider"]] | |
| e[0] += 1 | |
| e[1] += bool(r["supports_tools"]) | |
| e[2] += bool(r["supports_tools"] and r["supports_structured_output"]) | |
| print("\n| Provider | live rows | tools | tools **+** structured output |") | |
| print("| --- | ---: | ---: | ---: |") | |
| # Same ordering as the .md: both-capable providers first (most structured-output | |
| # routes), then the tools-only ones (most tool routes), then the capability-less | |
| # bulk host β so the table reads as a capability ranking, not a volume ranking. | |
| both_capable = sorted((p for p, e in profile.items() if e[2]), key=lambda p: -profile[p][2]) | |
| rest = sorted((p for p, e in profile.items() if not e[2] and e[1]), key=lambda p: -profile[p][1]) | |
| none = sorted((p for p, e in profile.items() if not e[1]), key=lambda p: -profile[p][0]) | |
| for p in [*both_capable, *rest, *none]: | |
| live, t, b = profile[p] | |
| print(f"| {p} | {live} | {t} | {b if b else '**0**'} |") | |
| cheapest: dict[str, dict[str, Any]] = {} | |
| for r in both: | |
| if r["input_price_per_mtok"] is None: | |
| continue | |
| cur = cheapest.get(r["model"]) | |
| if cur is None or r["input_price_per_mtok"] < cur["input_price_per_mtok"]: | |
| cheapest[r["model"]] = r | |
| print("\n| Model | Cheapest both-capable provider | Context | $ In / Out (1M) |") | |
| print("| --- | --- | ---: | --- |") | |
| for r in sorted(cheapest.values(), key=lambda r: r["input_price_per_mtok"])[:5]: | |
| ctx = f"{round((r['context_length'] or 0) / 1000)}K" if r["context_length"] else "?" | |
| print(f"| {r['model']} | {r['provider']} | {ctx} | " | |
| f"{r['input_price_per_mtok']} / {r['output_price_per_mtok']} |") | |
| def main() -> int: | |
| ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) | |
| ap.add_argument("--retrieved", default=date.today().isoformat(), | |
| help="snapshot date to stamp on every record (default: today)") | |
| ap.add_argument("--dry-run", action="store_true", help="don't write the JSONL") | |
| ap.add_argument("--diff", action="store_true", help="report drift vs the committed snapshot") | |
| ap.add_argument("--summary", action="store_true", help="print the .md's hand-maintained numbers") | |
| args = ap.parse_args() | |
| old = _read_committed() | |
| rows = flatten(fetch(), args.retrieved) | |
| if args.diff: | |
| report_diff(old, rows) | |
| if args.summary: | |
| report_summary(rows) | |
| if args.dry_run: | |
| print(f"\n(dry run β {len(rows)} rows not written)") | |
| return 0 | |
| OUT.write_text("".join(json.dumps({k: r[k] for k in FIELDS}, separators=(",", ":"), | |
| ensure_ascii=False) + "\n" for r in rows), encoding="utf-8") | |
| print(f"\nWrote {len(rows)} rows to {OUT} (retrieved {args.retrieved}).") | |
| print("Now update inference-provider-capabilities.md by hand: snapshot date, row/model " | |
| "counts, provider table, notable-gaps bullets, cheapest-routes table.") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |