Spaces:
Running
Running
SignalLayer Labs
fix: coherent recovery snapshots and public deployment readiness (#8)
9b989e1 unverified Download scripts/verify_deployment.py from Italianhype/Blum: direct link, hf CLI and curl.
- Browser
- Download file 3.79 kB
-
https://huggingface.co/spaces/Italianhype/Blum/resolve/main/scripts/verify_deployment.py
- Command line
-
hf download hf://spaces/Italianhype/Blum/scripts/verify_deployment.py
-
curl -L -o verify_deployment.py https://huggingface.co/spaces/Italianhype/Blum/resolve/main/scripts/verify_deployment.py
3.79 kB
| """Verify source revision, JSON APIs, readiness and public read-only boundary.""" | |
| import argparse | |
| import json | |
| import subprocess | |
| import sys | |
| from pathlib import Path | |
| import time | |
| import urllib.error | |
| import urllib.request | |
| parser = argparse.ArgumentParser(description=__doc__) | |
| parser.add_argument('--backend-only', action='store_true') | |
| parser.add_argument('--timeout', type=int, default=120) | |
| args = parser.parse_args() | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'backend')) | |
| from app.core.release import source_content_hash | |
| expected_content_hash = source_content_hash() | |
| revision = subprocess.check_output(['git', 'rev-parse', 'HEAD'], text=True).strip() | |
| backend = 'https://italianhype-blum.hf.space' | |
| site = 'https://blum.signallayerlabs.workers.dev' | |
| verification_headers = { | |
| 'User-Agent': 'BLUM-Deployment-Verification/2.3.0 (+https://github.com/SignalLayerLabs/Blum)', | |
| } | |
| def request(url, **kwargs): | |
| # Identify the maintained verifier explicitly; workers.dev rejects Python's default agent. | |
| return urllib.request.Request(url, headers=verification_headers, **kwargs) | |
| def get_json(origin, path): | |
| response = urllib.request.urlopen(request(origin+path), timeout=15) | |
| if 'application/json' not in response.headers.get('Content-Type', ''): | |
| raise ValueError('Expected a JSON API response: '+path) | |
| return json.load(response) | |
| deadline = time.monotonic() + args.timeout | |
| last_error = '' | |
| while time.monotonic() < deadline: | |
| try: | |
| startup = get_json(backend, '/startup/status') | |
| deployed = get_json(backend, '/api/runtime/release') | |
| if not startup.get('api_ready') or not startup.get('ui_ready') or startup.get('last_error'): | |
| raise ValueError('Backend is restoring or unavailable.') | |
| if deployed.get('source_revision') != revision or deployed.get('version') != '2.3.0': | |
| raise ValueError('Backend revision has not finished deploying.') | |
| if deployed.get('source_content_hash') != expected_content_hash: | |
| raise ValueError('Backend protected source content does not match the verified checkout.') | |
| if not args.backend_only: | |
| public = get_json(site, '/api/release') | |
| if public.get('source_revision') != revision or public.get('source_content_hash') != expected_content_hash or not public.get('backend_ready'): | |
| raise ValueError('Cloudflare revision or backend readiness has not settled.') | |
| break | |
| except (OSError, ValueError) as exc: | |
| last_error = str(exc) | |
| time.sleep(10) | |
| else: | |
| raise SystemExit(('Backend' if args.backend_only else 'Release')+' verification failed: '+last_error) | |
| print('Backend ready at', revision, flush=True) | |
| if not args.backend_only: | |
| for path in ['/api/brain/snapshot', '/api/training/snapshot', '/api/paper-trading/snapshot?limit=1', | |
| '/api/alpha/snapshot', '/api/alpha/desk', '/api/ascent/status']: | |
| payload = get_json(site, path) | |
| if not isinstance(payload, dict): raise SystemExit('Invalid snapshot: '+path) | |
| print('Verified JSON snapshot', path, flush=True) | |
| try: | |
| urllib.request.urlopen(request(site+'/api/ascent/run', data=b'{}', method='POST'), timeout=15) | |
| raise SystemExit('Public research mutation was unexpectedly allowed.') | |
| except urllib.error.HTTPError as exc: | |
| if exc.code != 405: raise | |
| for path in ['/brain/', '/training-ground/', '/paper-trading/', '/alpha/', '/evolution/']: | |
| response = urllib.request.urlopen(request(site+path), timeout=15) | |
| if response.status != 200 or 'text/html' not in response.headers.get('Content-Type', ''): | |
| raise SystemExit('Product page unavailable: '+path) | |
| print('Cloudflare pages, live API snapshots and write protection verified.', flush=True) | |