SafeVixAI/SafeVixAI-Dataset-Hub
SafeVixAI Dataset Hub π‘οΈ The Intelligence Layer for the SafeVixAI platform β IIT Madras Road Safety Hackathon 2026 This repository hosts all datasets, pre-trained models, notebooks, and reproducible data acquisition scripts that power the SafeVixAI application. It is designed to be cloned directly into Google Colab or any research environment. Main Application Repo: SafeVixAI/SafeVixAI β‘ Quickstart (Google Colab) # Clone the entire intelligence layer !gitβ¦ See the full description on the dataset page: https://huggingface.co/datasets/SafeVixAI/SafeVixAI-Dataset-Hub.
1147
1#!/usr/bin/env python32"""3smoke_test.py β SafeVixAI Deployment Smoke Test4 5Verifies all 3 services respond correctly after deployment.6Run against live URLs or localhost.7 8Usage:9 python scripts/smoke_test.py # localhost defaults10 python scripts/smoke_test.py --backend https://safevixai-api.onrender.com --chatbot https://safevixai-chatbot.onrender.com11"""12 13import argparse14import sys15import time16 17try:18 import httpx19except ImportError:20 print("Missing httpx β run: pip install httpx")21 sys.exit(1)22 23 24PASS = 025FAIL = 026 27 28def check(label: str, condition: bool, detail: str = "") -> None:29 global PASS, FAIL30 if condition:31 PASS += 132 print(f" β
{label}")33 else:34 FAIL += 135 print(f" β {label}" + (f" β {detail}" if detail else ""))36 37 38def main():39 parser = argparse.ArgumentParser(description="SafeVixAI smoke test")40 parser.add_argument("--backend", default="http://localhost:8000", help="Backend base URL")41 parser.add_argument("--chatbot", default="http://localhost:8010", help="Chatbot base URL")42 args = parser.parse_args()43 44 backend = args.backend.rstrip("/")45 chatbot = args.chatbot.rstrip("/")46 47 client = httpx.Client(timeout=15.0, follow_redirects=True)48 49 print(f"\n{'='*60}")50 print(f" SafeVixAI Smoke Test")51 print(f" Backend: {backend}")52 print(f" Chatbot: {chatbot}")53 print(f"{'='*60}\n")54 55 # ββ Backend Health ββββββββββββββββββββββββββββββββββββββββββββββ56 print("1. Backend Health")57 try:58 r = client.get(f"{backend}/health")59 check(r.status_code == 200, f"Expected 200, got {r.status_code}")60 data = r.json()61 check(data.get("status") == "ok", f"Expected status=ok, got {data.get('status')}")62 check("database" in data, "No database key in health response")63 check("version" in data, "No version key in health response")64 except Exception as e:65 check(False, f"Connection failed: {e}")66 67 # ββ Backend Metrics βββββββββββββββββββββββββββββββββββββββββββββ68 print("\n2. Backend Metrics")69 try:70 r = client.get(f"{backend}/metrics")71 check(r.status_code == 200, f"Expected 200, got {r.status_code}")72 check("# HELP" in r.text, "No Prometheus HELP lines")73 except Exception as e:74 check(False, f"Metrics failed: {e}")75 76 # ββ Backend Emergency βββββββββββββββββββββββββββββββββββββββββββ77 print("\n3. Backend Emergency API")78 try:79 r = client.get(f"{backend}/api/v1/emergency/numbers")80 check(r.status_code == 200, f"Expected 200, got {r.status_code}")81 data = r.json()82 check("112" in str(data), "112 missing from emergency numbers")83 except Exception as e:84 check(False, f"Emergency numbers failed: {e}")85 86 # ββ Backend Geocode βββββββββββββββββββββββββββββββββββββββββββββ87 print("\n4. Backend Geocode API")88 try:89 r = client.get(f"{backend}/api/v1/geocode/reverse", params={"lat": 13.0827, "lon": 80.2707})90 check(r.status_code in (200, 503), f"Unexpected status: {r.status_code}")91 if r.status_code == 200:92 data = r.json()93 check(len(str(data)) > 10, "Empty geocode response")94 except Exception as e:95 check(False, f"Geocode failed: {e}")96 97 # ββ Backend Challan βββββββββββββββββββββββββββββββββββββββββββββ98 print("\n5. Backend Challan API")99 try:100 r = client.post(101 f"{backend}/api/v1/challan/calculate",102 json={"violation_code": "MVA_185", "state": "TAMIL NADU"},103 )104 check(r.status_code in (200, 422), f"Unexpected status: {r.status_code}")105 except Exception as e:106 check(False, f"Challan failed: {e}")107 108 # ββ Backend Auth ββββββββββββββββββββββββββββββββββββββββββββββββ109 print("\n6. Backend Auth Endpoints")110 try:111 r = client.post(f"{backend}/api/v1/auth/login", json={"email": "test@test.com", "password": "password123"})112 check(r.status_code == 401, f"Expected 401 for bad login, got {r.status_code}")113 except Exception as e:114 check(False, f"Auth login failed: {e}")115 116 try:117 r = client.get(f"{backend}/api/v1/auth/verify")118 check(r.status_code == 401, f"Expected 401 for unauthenticated verify, got {r.status_code}")119 except Exception as e:120 check(False, f"Auth verify failed: {e}")121 122 # ββ Backend Circuit Breaker ββββββββββββββββββββββββββββββββββββββ123 print("\n7. Backend Circuit Breaker (auth-gated)")124 try:125 r = client.get(f"{backend}/api/v1/circuit-breaker/")126 check(r.status_code == 401, f"Expected 401 for unauthenticated CB access, got {r.status_code}")127 except Exception as e:128 check(False, f"Circuit breaker auth check failed: {e}")129 130 # ββ Backend Rate Limiting βββββββββββββββββββββββββββββββββββββββ131 print("\n8. Backend Rate Limiting")132 try:133 # Make many rapid requests to trigger rate limit134 for _ in range(15):135 client.get(f"{backend}/api/v1/emergency/numbers")136 r = client.get(f"{backend}/api/v1/emergency/numbers")137 check(r.status_code == 429, f"Expected 429 after burst, got {r.status_code}")138 except Exception as e:139 check(False, f"Rate limit check failed: {e}")140 141 # ββ Backend CORS ββββββββββββββββββββββββββββββββββββββββββββββββ142 print("\n9. Backend CORS Headers")143 try:144 r = client.options(145 f"{backend}/api/v1/emergency/numbers",146 headers={147 "Origin": "http://localhost:3000",148 "Access-Control-Request-Method": "GET",149 },150 )151 check("access-control-allow-origin" in r.headers, "No CORS headers in response")152 except Exception as e:153 check(False, f"CORS check failed: {e}")154 155 # ββ Backend Security Headers ββββββββββββββββββββββββββββββββββββ156 print("\n10. Backend Security Headers")157 try:158 r = client.get(f"{backend}/health")159 check("strict-transport-security" in r.headers, "Missing HSTS header")160 check("x-content-type-options" in r.headers, "Missing X-Content-Type-Options")161 check("x-frame-options" in r.headers, "Missing X-Frame-Options")162 check("referrer-policy" in r.headers, "Missing Referrer-Policy")163 except Exception as e:164 check(False, f"Security headers check failed: {e}")165 166 # ββ Chatbot Health βββββββββββββββββββββββββββββββββββββββββββββ167 print("\n11. Chatbot Health")168 try:169 r = client.get(f"{chatbot}/health")170 check(r.status_code == 200, f"Expected 200, got {r.status_code}")171 data = r.json()172 check(data.get("status") == "ok", f"Expected status=ok, got {data.get('status')}")173 check("service" in data, "No service key in health response")174 except Exception as e:175 check(False, f"Chatbot connection failed: {e}")176 177 # ββ Chatbot Root ββββββββββββββββββββββββββββββββββββββββββββββββ178 print("\n12. Chatbot Root Info")179 try:180 r = client.get(f"{chatbot}/")181 check(r.status_code == 200, f"Expected 200, got {r.status_code}")182 data = r.json()183 check("endpoints" in data, "No endpoints key")184 check("chat" in str(data), "chat endpoint not listed")185 except Exception as e:186 check(False, f"Chatbot root failed: {e}")187 188 # ββ Chatbot Security Headers ββββββββββββββββββββββββββββββββββββ189 print("\n13. Chatbot Security Headers")190 try:191 r = client.get(f"{chatbot}/health")192 check("strict-transport-security" in r.headers, "Missing HSTS header")193 check("x-content-type-options" in r.headers, "Missing X-Content-Type-Options")194 check("content-security-policy" in r.headers, "Missing CSP header")195 except Exception as e:196 check(False, f"Chatbot security headers failed: {e}")197 198 # ββ Chatbot Auth Enforcement ββββββββββββββββββββββββββββββββββββ199 print("\n14. Chatbot Auth (internal key check)")200 try:201 r = client.post(f"{chatbot}/api/v1/chat/", json={"message": "hello"})202 if r.status_code == 403:203 check(True, "Internal auth key is enforced (got 403)")204 else:205 check(True, f"No auth key configured, request got {r.status_code} (acceptable in dev)")206 except Exception as e:207 check(False, f"Chatbot auth check failed: {e}")208 209 # ββ Chatbot Rate Limiting ββββββββββββββββββββββββββββββββββββββ210 print("\n15. Chatbot Rate Limiting")211 try:212 for _ in range(25):213 client.get(f"{chatbot}/api/v1/chat/health")214 r = client.get(f"{chatbot}/api/v1/chat/health")215 if r.status_code == 429:216 check(True, "Rate limiting is active on chatbot")217 else:218 check(True, f"Got {r.status_code} (rate limiting may not be on this endpoint)")219 except Exception as e:220 check(False, f"Chatbot rate limit check failed: {e}")221 222 # ββ Chatbot Metrics ββββββββββββββββββββββββββββββββββββββββββββ223 print("\n16. Chatbot Metrics")224 try:225 r = client.get(f"{chatbot}/metrics")226 check(r.status_code == 200, f"Expected 200, got {r.status_code}")227 check("api_request_total" in r.text, "Missing api_request_total metric")228 except Exception as e:229 check(False, f"Chatbot metrics failed: {e}")230 231 # ββ Summary βββββββββββββββββββββββββββββββββββββββββββββββββββββ232 print(f"\n{'='*60}")233 print(f" Results: {PASS} passed, {FAIL} failed")234 print(f"{'='*60}\n")235 236 if FAIL > 0:237 print(f"β οΈ {FAIL} check(s) failed β review details above.\n")238 sys.exit(1)239 else:240 print("β
All smoke tests passed!\n")241 sys.exit(0)242 243 244if __name__ == "__main__":245 main()246 