From b7d72fad81eb28916eb4c3df0c8a37ec12eb9a99 Mon Sep 17 00:00:00 2001 From: elmadani Date: Wed, 25 Feb 2026 00:53:30 +0000 Subject: [PATCH] Initial commit --- ix_scout.py | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 ix_scout.py diff --git a/ix_scout.py b/ix_scout.py new file mode 100644 index 0000000..8dda103 --- /dev/null +++ b/ix_scout.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +""" +IX Scout — Global Hardware Node Registry +Part of the Inference-X Ecosystem +# ​‌​‌ SALKA ELMADANI ‌​‌​ | inference-x.com | BSL-1.1 +Copyright (C) 2024-2026 Salka Elmadani. BSL-1.1. +https://git.inference-x.com/inference-x-community/ix-scout + +Real-time map of every IX node on Earth. +Anonymous. Voluntary. Community-powered. +""" +from fastapi import FastAPI, Request +from fastapi.responses import JSONResponse, HTMLResponse +from fastapi.middleware.cors import CORSMiddleware +import sqlite3, json, time, os, hashlib + +app = FastAPI(title="IX Scout", version="1.0.0", + description="Real-time global map of every Inference-X node.") +app.add_middleware(CORSMiddleware, allow_origins=["*"], + allow_methods=["*"], allow_headers=["*"]) + +DB = os.environ.get("SCOUT_DB", "./scout.db") + +def db(): + conn = sqlite3.connect(DB) + conn.row_factory = sqlite3.Row + return conn + +def init_db(): + with db() as c: + c.execute("""CREATE TABLE IF NOT EXISTS nodes ( + id TEXT PRIMARY KEY, + backend TEXT NOT NULL, + model TEXT, + tokens_per_sec REAL DEFAULT 0, + ram_gb REAL DEFAULT 0, + country TEXT DEFAULT '', + version TEXT DEFAULT '1.0', + reported_at INTEGER, + load_pct REAL DEFAULT 0 + )""") + c.commit() + +@app.on_event("startup") +async def startup(): init_db() + +@app.post("/report") +async def report_node(request: Request): + """IX Engine nodes report telemetry here (opt-in via --scout flag).""" + try: + data = await request.json() + node_id = hashlib.sha256( + f"{data.get('backend','')}{data.get('ram_gb',0)}".encode() + ).hexdigest()[:16] + with db() as c: + c.execute("""INSERT OR REPLACE INTO nodes + (id,backend,model,tokens_per_sec,ram_gb,country,version,reported_at,load_pct) + VALUES (?,?,?,?,?,?,?,?,?)""", + (node_id, data.get("backend","cpu"), data.get("model",""), + float(data.get("tokens_per_sec",0)), float(data.get("ram_gb",0)), + data.get("country",""), data.get("version","1.0"), + int(time.time()), float(data.get("load_pct",0)))) + c.commit() + return {"status":"ok","node_id":node_id} + except Exception as e: + return JSONResponse({"error":str(e)}, status_code=400) + +@app.get("/stats") +async def stats(): + """Aggregated network stats — last 24 hours.""" + cutoff = int(time.time()) - 86400 + with db() as c: + backends = c.execute(""" + SELECT backend, COUNT(*) as nodes, + AVG(tokens_per_sec) as avg_tps, + AVG(ram_gb) as avg_ram, + AVG(load_pct) as avg_load + FROM nodes WHERE reported_at > ? + GROUP BY backend ORDER BY nodes DESC + """, (cutoff,)).fetchall() + total = c.execute("SELECT COUNT(*) as t FROM nodes WHERE reported_at > ?", + (cutoff,)).fetchone() + return { + "total_nodes": total["t"] if total else 0, + "window": "24h", + "backends": [dict(b) for b in backends] + } + +@app.get("/nodes") +async def list_nodes(limit: int = 100): + """List recent nodes (anonymized).""" + cutoff = int(time.time()) - 3600 + with db() as c: + rows = c.execute(""" + SELECT backend, model, tokens_per_sec, ram_gb, country, version + FROM nodes WHERE reported_at > ? ORDER BY reported_at DESC LIMIT ? + """, (cutoff, limit)).fetchall() + return {"nodes": [dict(r) for r in rows], "count": len(rows)} + +@app.get("/health") +async def health(): + return {"status":"ok","service":"IX Scout","author":"Salka Elmadani","version":"1.0.0"} + +if __name__ == "__main__": + import uvicorn + print("IX Scout — Global Hardware Node Registry") + print("Anonymous. Voluntary. Real.") + print("Built in Morocco for the world.") + uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT","7936")))