Download scripts/assets.py from nmarshall/nanobrush: direct link, hf CLI and curl.
- Browser
- Download file 2.18 kB
-
https://huggingface.co/nmarshall/nanobrush/resolve/main/scripts/assets.py
- Command line
-
hf download hf://nmarshall/nanobrush/scripts/assets.py
-
curl -L -o assets.py https://huggingface.co/nmarshall/nanobrush/resolve/main/scripts/assets.py
2.18 kB
| #!/usr/bin/env python3 | |
| """Hydrate and verify Xet-backed assets in the single Nanobrush Git checkout.""" | |
| import argparse | |
| import hashlib | |
| from pathlib import Path | |
| import subprocess | |
| import sys | |
| import storage_policy as policy | |
| ROOT = Path(__file__).resolve().parents[1] | |
| def run(*args, capture=False): | |
| return subprocess.run(args, cwd=ROOT, check=True, stdout=subprocess.PIPE if capture else None).stdout | |
| def main(): | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("command", choices=("check", "fetch")) | |
| args = parser.parse_args() | |
| policy.check_setup() | |
| policy.check_index() | |
| if args.command == "fetch": | |
| run("git", "lfs", "pull", "hf") | |
| # A fresh clone's cache starts empty; verify hydrated working bytes directly. | |
| count = 0 | |
| paths = policy.git("ls-files", "-z").split(b"\0") | |
| for raw in paths: | |
| if not raw: | |
| continue | |
| path = raw.decode("utf-8") | |
| if not policy.is_asset(path): | |
| continue | |
| pointer = policy.git("show", ":" + path) | |
| policy.check_asset(path, pointer) | |
| if not pointer: | |
| expected_hash, size = hashlib.sha256(b"").hexdigest(), 0 | |
| else: | |
| lines = pointer.decode().splitlines() | |
| expected_hash, size = lines[1].split(":", 1)[1], int(lines[2].split()[1]) | |
| payload = ROOT / path | |
| if payload.is_symlink() or not payload.is_file() or payload.stat().st_size != size: | |
| raise ValueError(f"Missing/unhydrated asset: {path}; run assets-fetch") | |
| digest = hashlib.sha256() | |
| with payload.open("rb") as stream: | |
| for chunk in iter(lambda: stream.read(1024 * 1024), b""): | |
| digest.update(chunk) | |
| if digest.hexdigest() != expected_hash: | |
| raise ValueError(f"Modified/unhydrated asset: {path}; preserve edits before fetching") | |
| count += 1 | |
| print(f"Verified {count} hydrated Xet/LFS assets against staged pointer identities.") | |
| if __name__ == "__main__": | |
| try: | |
| main() | |
| except (ValueError, OSError, subprocess.CalledProcessError) as error: | |
| print(f"Assets: {error}", file=sys.stderr) | |
| sys.exit(1) | |