Download scripts/upload.py from SearchingMan/FLUX.1-dev-ConvRot: direct link, hf CLI and curl.
- Browser
- Download file 6.66 kB
-
https://huggingface.co/SearchingMan/FLUX.1-dev-ConvRot/resolve/main/scripts/upload.py
- Command line
-
hf download hf://SearchingMan/FLUX.1-dev-ConvRot/scripts/upload.py
-
curl -L -o upload.py https://huggingface.co/SearchingMan/FLUX.1-dev-ConvRot/resolve/main/scripts/upload.py
6.66 kB
| #!/usr/bin/env python3 | |
| """Dry-run by default uploader for the FLUX.1-dev ConvRot Hugging Face repo.""" | |
| from __future__ import annotations | |
| import argparse | |
| import hashlib | |
| import json | |
| import os | |
| import subprocess | |
| import sys | |
| from pathlib import Path | |
| from typing import Any | |
| ROOT = Path(__file__).resolve().parents[1] | |
| MANIFEST_PATH = ROOT / "release_manifest.json" | |
| VERIFY_SCRIPT = ROOT / "scripts/verify_release.py" | |
| VERIFICATION_PATH = ROOT / "release_verification.json" | |
| CHUNK_BYTES = 16 * 1024 * 1024 | |
| def parse_args() -> argparse.Namespace: | |
| manifest = json.loads(MANIFEST_PATH.read_text(encoding="utf-8")) | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument("--repo-id", default=manifest["suggested_repo_id"]) | |
| parser.add_argument( | |
| "--model-root", | |
| type=Path, | |
| default=Path(os.environ.get("COMFYUI_MODELS_ROOT", "/mnt/d/comfyui/models")), | |
| ) | |
| parser.add_argument("--revision", default="main") | |
| parser.add_argument("--execute", action="store_true", help="Perform network writes; default is dry-run.") | |
| parser.add_argument( | |
| "--support-only", | |
| action="store_true", | |
| help="Upload documentation/evidence only; do not re-upload model artifacts.", | |
| ) | |
| parser.add_argument( | |
| "--create-private", | |
| action="store_true", | |
| help="Create a new private model repository before upload.", | |
| ) | |
| parser.add_argument( | |
| "--accept-flux-license", | |
| action="store_true", | |
| help="Confirm that the uploader reviewed and accepts the upstream FLUX.1-dev license.", | |
| ) | |
| return parser.parse_args() | |
| def load_manifest() -> dict[str, Any]: | |
| value = json.loads(MANIFEST_PATH.read_text(encoding="utf-8")) | |
| if not isinstance(value, dict): | |
| raise RuntimeError("release manifest must be a JSON object") | |
| return value | |
| def sha256_file(path: Path) -> str: | |
| digest = hashlib.sha256() | |
| with path.open("rb") as handle: | |
| for chunk in iter(lambda: handle.read(CHUNK_BYTES), b""): | |
| digest.update(chunk) | |
| return digest.hexdigest() | |
| def existing_verification_is_current(manifest: dict[str, Any], model_root: Path) -> bool: | |
| if not VERIFICATION_PATH.is_file(): | |
| return False | |
| verification = json.loads(VERIFICATION_PATH.read_text(encoding="utf-8")) | |
| if verification.get("status") != "PASS" or not verification.get("model_hashes_verified"): | |
| return False | |
| if verification.get("artifact_total_bytes") != manifest.get("artifact_total_bytes"): | |
| return False | |
| support = {record["path"]: record for record in verification.get("support_files", [])} | |
| for relative in manifest["required_repository_files"]: | |
| record = support.get(relative) | |
| path = ROOT / relative | |
| if record is None or not path.is_file() or path.is_symlink(): | |
| return False | |
| if path.stat().st_size != record["bytes"] or sha256_file(path) != record["sha256"]: | |
| return False | |
| verified_artifacts = { | |
| record["repo_path"]: record for record in verification.get("artifacts", []) | |
| } | |
| verification_mtime_ns = VERIFICATION_PATH.stat().st_mtime_ns | |
| for artifact in manifest["artifacts"]: | |
| record = verified_artifacts.get(artifact["repo_path"]) | |
| source = model_root / artifact["source_relative_path"] | |
| if record is None or not record.get("hash_verified") or not source.is_file(): | |
| return False | |
| if record.get("sha256") != artifact["sha256"]: | |
| return False | |
| if source.stat().st_size != artifact["bytes"] or source.stat().st_mtime_ns > verification_mtime_ns: | |
| return False | |
| return True | |
| def main() -> int: | |
| args = parse_args() | |
| manifest = load_manifest() | |
| model_root = args.model_root.expanduser().resolve(strict=True) | |
| plan = { | |
| "mode": "execute" if args.execute else "dry-run", | |
| "repo_id": args.repo_id, | |
| "revision": args.revision, | |
| "create_private": args.create_private, | |
| "support_only": args.support_only, | |
| "support_root": str(ROOT), | |
| "artifact_total_bytes": manifest["artifact_total_bytes"], | |
| "artifacts": [ | |
| { | |
| "source": str(model_root / artifact["source_relative_path"]), | |
| "repo_path": artifact["repo_path"], | |
| "bytes": artifact["bytes"], | |
| "sha256": artifact["sha256"], | |
| } | |
| for artifact in manifest["artifacts"] | |
| ], | |
| } | |
| print(json.dumps(plan, indent=2)) | |
| if not args.execute: | |
| print("DRY RUN: no repository was created and no files were uploaded.") | |
| return 0 | |
| if not args.accept_flux_license: | |
| raise SystemExit("Refusing upload: pass --accept-flux-license after reviewing LICENSE_NOTICE.md") | |
| if existing_verification_is_current(manifest, model_root): | |
| print("Reusing current full-hash release_verification.json") | |
| else: | |
| subprocess.run( | |
| [sys.executable, str(VERIFY_SCRIPT), "--model-root", str(model_root), "--models"], | |
| check=True, | |
| ) | |
| from huggingface_hub import HfApi | |
| api = HfApi() | |
| if args.create_private: | |
| api.create_repo(repo_id=args.repo_id, repo_type="model", private=True, exist_ok=False) | |
| support_paths = [ | |
| ".gitattributes", | |
| "LICENSE_NOTICE.md", | |
| "README.md", | |
| "assets/*", | |
| "manifests/*", | |
| "release_manifest.json", | |
| "release_verification.json", | |
| "scripts/*", | |
| "workflows/*", | |
| ] | |
| api.upload_folder( | |
| repo_id=args.repo_id, | |
| repo_type="model", | |
| folder_path=str(ROOT), | |
| path_in_repo=".", | |
| revision=args.revision, | |
| allow_patterns=support_paths, | |
| ignore_patterns=["**/__pycache__/**", "**/*.pyc"], | |
| commit_message="Add model card, workflows, and verified release evidence", | |
| ) | |
| if args.support_only: | |
| print(f"Support-file upload complete: https://huggingface.co/{args.repo_id}") | |
| return 0 | |
| for artifact in manifest["artifacts"]: | |
| source = model_root / artifact["source_relative_path"] | |
| api.upload_file( | |
| repo_id=args.repo_id, | |
| repo_type="model", | |
| path_or_fileobj=str(source), | |
| path_in_repo=artifact["repo_path"], | |
| revision=args.revision, | |
| commit_message=f"Add {artifact['repo_path']}", | |
| ) | |
| print(f"Upload complete: https://huggingface.co/{args.repo_id}") | |
| print("If publication is intended, configure gating and review visibility in Hugging Face settings before making the repository public.") | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |