Download ml/scripts/emit_sample.py from PRiyanshu0-1/TrackChain: direct link, hf CLI and curl.
- Browser
- Download file 10.7 kB
-
https://huggingface.co/PRiyanshu0-1/TrackChain/resolve/main/ml/scripts/emit_sample.py
- Command line
-
hf download hf://PRiyanshu0-1/TrackChain/ml/scripts/emit_sample.py
-
curl -L -o emit_sample.py https://huggingface.co/PRiyanshu0-1/TrackChain/resolve/main/ml/scripts/emit_sample.py
10.7 kB
| # Emits a full SOTA contract-compliant inspection slice to the backend (tc.v1). | |
| # Supports Device Registration, JWT Token Exchange, HMAC-SHA256 Request Signing, Telemetry, and ML Fusion Defect Ingestion. | |
| import argparse | |
| import hashlib | |
| import hmac | |
| import json | |
| import sys | |
| import time | |
| import urllib.request | |
| from typing import Dict, Any | |
| def sign_request(secret: str, payload_bytes: bytes, timestamp_str: str) -> str: | |
| """Compute HMAC-SHA256 signature for body + timestamp.""" | |
| msg = payload_bytes + timestamp_str.encode("utf-8") | |
| return hmac.new(secret.encode("utf-8"), msg, hashlib.sha256).hexdigest() | |
| def emit_sample_slice( | |
| backend_url: str = "http://127.0.0.1:8000", | |
| signing_secret: str = "trackchain-request-signing-secret-change-in-production", | |
| ): | |
| print(f"[INFO] Connecting to TrackChain backend at: {backend_url}") | |
| # 1. Health check & Observability Probing | |
| try: | |
| req = urllib.request.Request(f"{backend_url}/health", method="GET") | |
| with urllib.request.urlopen(req, timeout=5) as res: | |
| if res.status == 200: | |
| print(f"[OK] Backend health probe verified: {res.read().decode('utf-8')}") | |
| except Exception as exc: | |
| print(f"[ERROR] Could not connect to backend health endpoint at {backend_url}: {exc}") | |
| print("[TIP] Make sure the backend is running via: uvicorn src.main:app --port 8000") | |
| sys.exit(1) | |
| # 2. Register Edge Inspection Device | |
| device_id = f"RPI-5-ITMS-{int(time.time()) % 10000:04d}" | |
| device_payload = { | |
| "device_id": device_id, | |
| "name": "Track Inspection Cart Unit 1", | |
| "hardware_version": "Raspberry Pi 5 (8GB)", | |
| "firmware_version": "v1.4.2-prod", | |
| "camera_model": "Sony IMX477 1080p60", | |
| "imu_model": "Bosch BNO085 100Hz", | |
| "gnss_model": "u-blox NEO-M9N RTK", | |
| } | |
| raw_api_key = None | |
| try: | |
| data = json.dumps(device_payload).encode("utf-8") | |
| req = urllib.request.Request( | |
| f"{backend_url}/api/v1/devices/register", | |
| data=data, | |
| headers={"Content-Type": "application/json"}, | |
| method="POST", | |
| ) | |
| with urllib.request.urlopen(req, timeout=5) as res: | |
| reg_resp = json.loads(res.read().decode("utf-8")) | |
| raw_api_key = reg_resp.get("api_key") | |
| print(f"[OK] Registered edge device: {device_id} (API Key: {raw_api_key[:12]}...)") | |
| except Exception as exc: | |
| print(f"[ERROR] Device registration failed: {exc}") | |
| sys.exit(1) | |
| # 3. Exchange API Key for Scoped JWT Token | |
| access_token = None | |
| try: | |
| token_payload = {"device_id": device_id, "api_key": raw_api_key} | |
| data = json.dumps(token_payload).encode("utf-8") | |
| req = urllib.request.Request( | |
| f"{backend_url}/api/v1/devices/token", | |
| data=data, | |
| headers={"Content-Type": "application/json"}, | |
| method="POST", | |
| ) | |
| with urllib.request.urlopen(req, timeout=5) as res: | |
| token_resp = json.loads(res.read().decode("utf-8")) | |
| access_token = token_resp.get("access_token") | |
| print(f"[OK] Authenticated JWT access token issued: {access_token[:18]}... (Expires: {token_resp.get('expires_in_seconds')}s)") | |
| except Exception as exc: | |
| print(f"[ERROR] Token exchange failed: {exc}") | |
| sys.exit(1) | |
| auth_headers = { | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {access_token}", | |
| } | |
| # 4. Start Monitoring Session | |
| session_id = f"ses-live-{int(time.time())}" | |
| session_payload = { | |
| "id": session_id, | |
| "name": "Northern Railway Track Maintenance Inspection", | |
| "track_id": "IR-NR-MAIN01", | |
| "track_section": "Delhi-Mathura Km 102.0 to 108.0", | |
| "track_direction": "down", | |
| "start_chainage_m": 102000.0, | |
| "operator_name": "Senior Section Engineer (P-Way)", | |
| "device_id": device_id, | |
| } | |
| try: | |
| data = json.dumps(session_payload).encode("utf-8") | |
| req = urllib.request.Request( | |
| f"{backend_url}/api/v1/sessions", | |
| data=data, | |
| headers=auth_headers, | |
| method="POST", | |
| ) | |
| with urllib.request.urlopen(req, timeout=5) as res: | |
| created_session = json.loads(res.read().decode("utf-8")) | |
| session_id = created_session.get("id", session_id) | |
| print(f"[OK] Started monitoring session: {session_id} on {session_payload['track_section']}") | |
| except Exception as exc: | |
| print(f"[ERROR] Session creation failed: {exc}") | |
| sys.exit(1) | |
| # 5. Ingest High-Frequency Telemetry Batch with HMAC Signing | |
| telemetry_payload = { | |
| "schema_version": "tc.v1", | |
| "idempotency_key": f"idemp-tel-{int(time.time())}", | |
| "session_id": session_id, | |
| "device_id": device_id, | |
| "samples": [ | |
| { | |
| "chainage_m": 102400.0 + (i * 25.0), | |
| "speed_mps": 30.5, | |
| "speed_kmh": 109.8, | |
| "vibration_rms": 0.85 if i != 2 else 3.25, | |
| "track_gauge_mm": 1676.0 if i != 2 else 1692.5, | |
| "cant_mm": 12.0, | |
| "twist_mm_per_m": 0.8 if i != 2 else 4.6, | |
| "latitude": 28.535 - (i * 0.0005), | |
| "longitude": 77.284 + (i * 0.0005), | |
| } | |
| for i in range(10) | |
| ], | |
| } | |
| ts_str = str(int(time.time())) | |
| tel_bytes = json.dumps(telemetry_payload).encode("utf-8") | |
| sig = sign_request(signing_secret, tel_bytes, ts_str) | |
| tel_headers = auth_headers.copy() | |
| tel_headers["X-Signature"] = sig | |
| tel_headers["X-Timestamp"] = ts_str | |
| tel_headers["X-Idempotency-Key"] = telemetry_payload["idempotency_key"] | |
| try: | |
| req = urllib.request.Request( | |
| f"{backend_url}/api/v1/telemetry/batch", | |
| data=tel_bytes, | |
| headers=tel_headers, | |
| method="POST", | |
| ) | |
| with urllib.request.urlopen(req, timeout=5) as res: | |
| tel_resp = json.loads(res.read().decode("utf-8")) | |
| print(f"[OK] Ingested HMAC-signed telemetry batch: {tel_resp['inserted']} samples (session: {tel_resp['session_id']})") | |
| except Exception as exc: | |
| print(f"[ERROR] Telemetry ingestion failed: {exc}") | |
| sys.exit(1) | |
| # 6. Ingest Multi-Modal ML Fused Defect Event with Explainability | |
| defect_payload = { | |
| "session_id": session_id, | |
| "device_id": device_id, | |
| "chainage_m": 102450.0, | |
| "defect_class": "missing_fastener", | |
| "defect_family": "visual_component", | |
| "severity": "critical", | |
| "decision": "INSPECT_KNOWN", | |
| "confidence": 0.94, | |
| "source_model": "yolo_v8_detector", | |
| "stream_source": "vision", | |
| "description": "Multi-modal confirmation: Missing fastening clip with coincident lateral acceleration spike at KM 102+450", | |
| "latitude": 28.534, | |
| "longitude": 77.285, | |
| "supporting_signals": [ | |
| { | |
| "model_name": "yolo_v8_detector", | |
| "model_version": "v1.0.0", | |
| "signal_type": "bounding_box", | |
| "raw_score": 0.94, | |
| "calibrated_score": 0.94, | |
| "threshold": 0.5, | |
| "fired": True, | |
| "label": "missing_fastener", | |
| "bbox": [120.0, 240.0, 180.0, 310.0], | |
| "explanation": "High-confidence visual missing fastener detection", | |
| }, | |
| { | |
| "model_name": "en13848_physics_engine", | |
| "model_version": "v1.0.0", | |
| "signal_type": "exceedance", | |
| "raw_score": 4.6, | |
| "calibrated_score": 0.82, | |
| "threshold": 0.5, | |
| "fired": True, | |
| "label": "twist_fault", | |
| "explanation": "Twist exceeds EN 13848 safety limit (4.6mm/m > 4.0mm/m)", | |
| }, | |
| ], | |
| } | |
| defect_bytes = json.dumps(defect_payload).encode("utf-8") | |
| req = urllib.request.Request( | |
| f"{backend_url}/api/v1/defects", | |
| data=defect_bytes, | |
| headers=auth_headers, | |
| method="POST", | |
| ) | |
| try: | |
| with urllib.request.urlopen(req, timeout=5) as res: | |
| created_defect = json.loads(res.read().decode("utf-8")) | |
| defect_id = created_defect.get("id") | |
| print(f"[OK] Ingested fused defect event: {defect_id}") | |
| print(f" - Class: {created_defect['defect_class']}, Severity: {created_defect['severity']}, Confidence: {created_defect['confidence']}") | |
| print(f" - Supporting Signals: {len(created_defect.get('supporting_signals', []))} ML models linked for explainability") | |
| except Exception as exc: | |
| print(f"[ERROR] Defect event ingestion failed: {exc}") | |
| sys.exit(1) | |
| # 7. Dashboard KPI Verification | |
| try: | |
| req = urllib.request.Request(f"{backend_url}/api/v1/dashboard/summary", headers=auth_headers, method="GET") | |
| with urllib.request.urlopen(req, timeout=5) as res: | |
| summary = json.loads(res.read().decode("utf-8")) | |
| print(f"[OK] Live Dashboard KPI Summary:") | |
| print(f" - Total Defects: {summary['total_defects']}, Critical: {summary['critical_defects']}, Open Alerts: {summary['open_alerts']}") | |
| except Exception as exc: | |
| print(f"[ERROR] Dashboard summary query failed: {exc}") | |
| # 8. Prometheus Metrics Verification | |
| try: | |
| req = urllib.request.Request(f"{backend_url}/metrics", method="GET") | |
| with urllib.request.urlopen(req, timeout=5) as res: | |
| metrics_raw = res.read().decode("utf-8") | |
| has_req = "trackchain_http_requests_total" in metrics_raw | |
| has_def = "trackchain_defects_created_total" in metrics_raw | |
| print(f"[OK] Prometheus Observability: HTTP Metrics: {has_req}, Defect Metrics: {has_def}") | |
| except Exception as exc: | |
| print(f"[WARN] Metrics query notice: {exc}") | |
| print("\n" + "=" * 80) | |
| print(" [SUCCESS] TrackChain Edge-to-Cloud Integration Slice Verified Successfully!") | |
| print("=" * 80) | |
| if __name__ == "__main__": | |
| parser = argparse.ArgumentParser(description="Emit TrackChain SOTA production inspection slice.") | |
| parser.add_argument( | |
| "--backend-url", | |
| default="http://127.0.0.1:8000", | |
| help="Backend API base URL (default: http://127.0.0.1:8000)", | |
| ) | |
| parser.add_argument( | |
| "--signing-secret", | |
| default="trackchain-request-signing-secret-change-in-production", | |
| help="HMAC-SHA256 request signing secret", | |
| ) | |
| args = parser.parse_args() | |
| emit_sample_slice(args.backend_url, args.signing_secret) | |