"""Manifest-verified, new-repository-only HF upload. Dry run unless --publish. Use `hf auth login` locally. Never place tokens in a card or a command argument. A model repository and its synthetic demo Space are distinct publish targets. """ from pathlib import Path import argparse,hashlib,json,re,sys ROOT=Path(__file__).resolve().parents[1] DENY=('.sqlite','.sqlite3','.db','.env','.pem','.key','.db-wal','.db-shm','.sqlite3-wal','.sqlite3-shm') def release_files(root=ROOT): root=Path(root).resolve();manifest=json.loads((root/'release_manifest.json').read_text());paths=[];seen=set() for item in manifest['files']: name=item['path'];p=root/name if name in seen:raise ValueError('duplicate manifest path') seen.add(name) if '\\' in name or name.startswith('/') or '..' in Path(name).parts or p.is_symlink() or not p.resolve().is_relative_to(root):raise ValueError('unsafe release path') if name.lower().endswith(DENY) or any(x.startswith('.') and x not in ('.github','.dockerignore','.gitignore','.keep','.gitattributes') for x in Path(name).parts):raise ValueError('private or unexpected path in manifest') raw=p.read_bytes() if len(raw)!=item['bytes'] or hashlib.sha256(raw).hexdigest()!=item['sha256']:raise ValueError(f'changed release file: {name}') paths.append(p) return paths+[root/'release_manifest.json'] def main(): p=argparse.ArgumentParser();p.add_argument('--repo',default=None);p.add_argument('--target',choices=['model','space'],default='model') p.add_argument('--space-dir',type=Path,default=ROOT.parent/'PhillNet-Recall-Space') p.add_argument('--publish',action='store_true');p.add_argument('--public',action='store_true') a=p.parse_args();root=ROOT if a.target=='model' else a.space_dir.resolve() repo=a.repo or ('ayjays132/PhillNet-Recall' if a.target=='model' else 'ayjays132/PhillNet-Recall-Demo') if not re.fullmatch(r'[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+',repo):raise ValueError('repository must be owner/name') paths=release_files(root);manifest=json.loads((root/'release_manifest.json').read_text());version=manifest.get('version','unknown') print(json.dumps({'repo':repo,'target':a.target,'version':version,'files':len(paths),'bytes':sum(f.stat().st_size for f in paths), 'visibility':'public' if a.public else 'private','action':'publish' if a.publish else 'dry_run'},indent=2)) if not a.publish:return 0 from huggingface_hub import HfApi,CommitOperationAdd api=HfApi();account=api.whoami() if account.get('name')!=repo.split('/')[0]:raise RuntimeError('logged-in account does not own the requested personal namespace') kwargs={'repo_type':a.target,'private':not a.public,'exist_ok':False} if a.target=='space':kwargs['space_sdk']='docker' # Existing repositories are never overwritten and their audience is unchanged. api.create_repo(repo,**kwargs) info=api.create_commit(repo,repo_type=a.target,commit_message=f'PhillNet Recall {version}: verified release', operations=[CommitOperationAdd(path_in_repo=str(f.relative_to(root)),path_or_fileobj=str(f)) for f in paths]) print(json.dumps({'repo':repo,'commit':info.oid,'commit_url':info.commit_url,'uploaded_files':len(paths)})) return 0 if __name__=='__main__':raise SystemExit(main())