mirror of
https://github.com/daijro/camoufox.git
synced 2026-10-03 16:00:19 +00:00
pythonlib left the model to fpgen, whose first import downloads the
first release the GitHub API lists: model-4/2025, whose WebGL records
have no vendor or renderer. Every generated launch on a fresh install
failed with KeyError: 'vendor'. scripts/pin-fpgen-model.py pinned the
model for CI only, and fpgen's five-week refresh replaced even that
pin, under a stamp the script's --check still trusted.
fpgen is now imported only through fpgen_model.load_fpgen(), which
installs the release named by the pin, checks the archive and each
file against their sha256, and dates the files past fpgen's refresh.
It writes the layout and stamp the script and the TypeScript launcher
use, verifies an install by hashing it, and leaves FPGEN_MODEL_URL to
fpgen. `camoufox fetch` installs the model as well. The pin gains each
file's sha256; the package carries a copy of it, and the script now
calls the module.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
(cherry picked from commit f043de3598)
46 lines
1.6 KiB
Python
Executable File
46 lines
1.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Install the pinned fpgen model before anything imports fpgen.
|
|
|
|
The launcher does this itself on first use (pythonlib/camoufox/fpgen_model.py,
|
|
which explains why fpgen's own download is not used). This entry point exists
|
|
for jobs that need the model in place before they start: CI, image builds, and
|
|
the TypeScript golden recorder.
|
|
|
|
Usage:
|
|
python3 scripts/pin-fpgen-model.py # install if not already pinned
|
|
python3 scripts/pin-fpgen-model.py --check # verify only; non-zero if not pinned
|
|
python3 scripts/pin-fpgen-model.py --force # re-download and reinstall
|
|
"""
|
|
|
|
import argparse
|
|
import sys
|
|
|
|
try:
|
|
from camoufox.fpgen_model import PIN, ensure_fpgen_model, fpgen_data_dir, is_pinned
|
|
except ImportError:
|
|
sys.exit('camoufox is not installed; `pip install -e pythonlib` first')
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser(description=__doc__,
|
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
ap.add_argument('--check', action='store_true', help='verify only; non-zero if not pinned')
|
|
ap.add_argument('--force', action='store_true', help='reinstall even if already pinned')
|
|
args = ap.parse_args()
|
|
|
|
if args.check:
|
|
if is_pinned():
|
|
print(f'OK: fpgen model pinned to {PIN["tag"]}')
|
|
return 0
|
|
print(f'fpgen model is NOT pinned to {PIN["tag"]}; run scripts/pin-fpgen-model.py',
|
|
file=sys.stderr)
|
|
return 1
|
|
|
|
ensure_fpgen_model(force=args.force)
|
|
print(f'OK: fpgen model {PIN["tag"]} pinned in {fpgen_data_dir()}', file=sys.stderr)
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
raise SystemExit(main())
|