Spaces:
Running
Running
Xiangyi Li
Run page backend: full-text search over a run's traces, token records, prompts and reports; a dev-only editor flag for local viewing.
ac8cc14 Download dev/run_readonly.py from benchflow/posttrain-arena: direct link, hf CLI and curl.
- Browser
- Download file 3.29 kB
-
https://huggingface.co/spaces/benchflow/posttrain-arena/resolve/main/dev/run_readonly.py
- Command line
-
hf download hf://spaces/benchflow/posttrain-arena/dev/run_readonly.py
-
curl -L -o run_readonly.py https://huggingface.co/spaces/benchflow/posttrain-arena/resolve/main/dev/run_readonly.py
3.29 kB
| """Dev only, not served by the Space: run the app locally against live HF data with every write path disabled. | |
| HF_TOKEN=... python dev/run_readonly.py [port] [--as-editor] | |
| HfApi write methods and non-GET httpx calls raise, so a local page load cannot upload, reconcile the | |
| budget ledger, launch or cancel jobs, or touch the live Space. | |
| --as-editor makes every GET and HEAD request to this local process act as a signed-in BenchFlow editor, so the dashboard | |
| can open transcripts, token views and search without an OAuth sign-in. It patches auth.principal in this process only: | |
| the Space runs app.py, which never imports this file, so its access rules are unchanged. Other methods keep the real check. | |
| """ | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1])) | |
| import os | |
| import httpx | |
| import huggingface_hub | |
| from huggingface_hub import HfApi | |
| # Job logs, costs and stop reasons need a token; without one the page loads but those fields go quietly empty. | |
| if not os.environ.get('HF_TOKEN'): | |
| stored = huggingface_hub.get_token() | |
| if not stored: sys.exit('No HF token: set HF_TOKEN or run `hf auth login`; job logs, costs and stop reasons need it.') | |
| os.environ['HF_TOKEN'] = stored | |
| print('Using the locally stored HF token (read-only: every write path below is disabled).') | |
| WRITES = ('upload_file', 'upload_folder', 'upload_large_folder', 'create_commit', 'create_repo', 'delete_repo', 'delete_file', 'delete_folder', | |
| 'create_branch', 'delete_branch', 'create_tag', 'delete_tag', 'super_squash_history', 'update_repo_settings', 'move_repo', | |
| 'run_job', 'run_uv_job', 'cancel_job', 'create_scheduled_job', 'delete_scheduled_job', 'restart_space', 'pause_space', | |
| 'add_space_secret', 'delete_space_secret', 'add_space_variable', 'delete_space_variable', 'duplicate_space', 'request_space_hardware') | |
| def blocked(name): | |
| def refuse(*args, **kwargs): raise RuntimeError(f'dev read-only guard: {name} is disabled') | |
| return refuse | |
| for name in WRITES: | |
| if hasattr(HfApi, name): setattr(HfApi, name, blocked('HfApi.' + name)) | |
| if hasattr(huggingface_hub, name): setattr(huggingface_hub, name, blocked('huggingface_hub.' + name)) | |
| for name in ('post', 'put', 'patch', 'delete'): setattr(httpx, name, blocked('httpx.' + name)) | |
| _stream = httpx.stream | |
| def get_stream(method, *args, **kwargs): | |
| if method.upper() != 'GET': raise RuntimeError('dev read-only guard: httpx.stream ' + method) | |
| return _stream(method, *args, **kwargs) | |
| httpx.stream = get_stream | |
| import uvicorn | |
| import app # noqa: E402 (imported after the guard on purpose) | |
| import collab | |
| collab.system_post = blocked('collab.system_post') | |
| AS_EDITOR = '--as-editor' in sys.argv | |
| if AS_EDITOR: | |
| sys.argv.remove('--as-editor') | |
| import auth | |
| _principal = auth.principal | |
| def principal(request): | |
| if request.method in ('GET', 'HEAD'): return {'name': 'local-dev', 'orgs': [{'name': 'benchflow', 'roleInOrg': 'write'}]} | |
| return _principal(request) | |
| auth.principal = principal | |
| print('--as-editor: local GET requests act as a BenchFlow editor (this process only).') | |
| if __name__ == '__main__': | |
| uvicorn.run(app.app, host='127.0.0.1', port=int(sys.argv[1]) if len(sys.argv) > 1 else 7861, access_log=False) | |