Download scripts/deploy_hf_space.py from Websterfly/Ai-detector-websterfly: direct link, hf CLI and curl.
- Browser
- Download file 3.69 kB
-
https://huggingface.co/spaces/Websterfly/Ai-detector-websterfly/resolve/main/scripts/deploy_hf_space.py
- Command line
-
hf download hf://spaces/Websterfly/Ai-detector-websterfly/scripts/deploy_hf_space.py
-
curl -L -o deploy_hf_space.py https://huggingface.co/spaces/Websterfly/Ai-detector-websterfly/resolve/main/scripts/deploy_hf_space.py
3.69 kB
| """Deploy only Websterfly/Ai-detector-websterfly using a securely configured token. | |
| No GitHub operations, no hardware purchases, no secret values in output. | |
| """ | |
| import argparse,hashlib,json,os,time | |
| from pathlib import Path | |
| from huggingface_hub import HfApi | |
| SPACE='Websterfly/Ai-detector-websterfly' | |
| ROOT=Path(__file__).resolve().parents[1] | |
| def manifest(folder): | |
| files=[] | |
| for path in sorted(folder.rglob('*')): | |
| if not path.is_file() or '__pycache__' in path.parts or path.suffix=='.pyc':continue | |
| rel=path.relative_to(folder) | |
| if path.suffix in ('.safetensors','.incomplete') or '.env' in rel.parts or any(p in ('.git','.cache','.venv','work') for p in rel.parts):raise ValueError('Unsafe deployment path: '+str(rel)) | |
| files.append({'path':str(rel),'bytes':path.stat().st_size,'sha256':hashlib.sha256(path.read_bytes()).hexdigest()}) | |
| return files | |
| def main(): | |
| parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--check',action='store_true');parser.add_argument('--wait',action='store_true');args=parser.parse_args() | |
| folder=ROOT/'work/huggingface-upload' | |
| if not folder.exists():raise SystemExit('Build upload directory with scripts/build_hf_space.py first.') | |
| files=manifest(folder) | |
| readme=(folder/'README.md').read_text();dockerfile=(folder/'Dockerfile').read_text() | |
| if 'sdk: docker' not in readme or 'app_port: 7860' not in readme or 'EXPOSE 7860' not in dockerfile:raise SystemExit('Docker/port metadata validation failed.') | |
| token=os.getenv('HF_TOKEN') | |
| print(json.dumps({'target':SPACE,'files':len(files),'bytes':sum(f['bytes'] for f in files),'secure_write_token_configured':bool(token),'remote_written':False},indent=2),flush=True) | |
| (ROOT/'work/huggingface-deployment-manifest.json').write_text(json.dumps({'space':SPACE,'files':files},indent=2)) | |
| if args.check:return | |
| if not token:raise SystemExit('Deployment blocked: configure a Space-scoped write token securely as HF_TOKEN in this execution environment. Do not paste the token into chat.') | |
| api=HfApi(token=token) | |
| try: | |
| api.whoami() | |
| before=api.space_info(SPACE) | |
| # Parent guard prevents overwriting an intervening change without review. | |
| commit=api.upload_folder(repo_id=SPACE,repo_type='space',folder_path=str(folder),parent_commit=before.sha, | |
| commit_message='Deploy educational AI detector research workbench using Docker', | |
| ignore_patterns=['**/__pycache__/**','**/*.pyc','**/.env','*.safetensors','**/*.safetensors','**/.cache/**']) | |
| except Exception as exc: | |
| # Keep headers/tokens out of errors; details can be diagnosed without dumping auth. | |
| raise SystemExit('Deployment request failed ('+type(exc).__name__+'). Check token scope and Space access; no credential values printed.') | |
| print(json.dumps({'commit_url':str(commit.commit_url),'space_url':'https://huggingface.co/spaces/'+SPACE,'remote_written':True}),flush=True) | |
| if not args.wait:return | |
| for attempt in range(180): | |
| runtime=api.get_space_runtime(SPACE);stage=str(runtime.stage) | |
| print(json.dumps({'runtime_stage':stage,'poll':attempt+1}),flush=True) | |
| if stage=='RUNNING': | |
| print('Space reports RUNNING. Verify /health, /ready, /workbench and a small real inference before declaring model readiness.',flush=True);return | |
| if any(s in stage for s in ['ERROR','FAILED']):raise SystemExit('Space build/runtime failed; inspect authenticated logs.') | |
| time.sleep(10) | |
| raise SystemExit('Space is still building/starting after the monitoring window. Deployment commit was created; inspect its runtime status.') | |
| if __name__=='__main__':main() | |