Initial commit
This commit is contained in:
parent
b14b14eb30
commit
8aaab5accb
100
ix_relay.py
Normal file
100
ix_relay.py
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
IX Relay — Federated Inference Network
|
||||||
|
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-relay
|
||||||
|
|
||||||
|
The khettara for AI power.
|
||||||
|
Your idle hardware earns you compute credits.
|
||||||
|
Share compute. Earn credits. Use when you need it.
|
||||||
|
"""
|
||||||
|
from fastapi import FastAPI, Request
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
import sqlite3, json, time, os, hashlib, secrets
|
||||||
|
|
||||||
|
app = FastAPI(title="IX Relay", version="1.0.0")
|
||||||
|
app.add_middleware(CORSMiddleware, allow_origins=["*"],
|
||||||
|
allow_methods=["*"], allow_headers=["*"])
|
||||||
|
|
||||||
|
DB = os.environ.get("RELAY_DB", "./relay.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, endpoint TEXT,
|
||||||
|
backend TEXT DEFAULT 'cpu', capacity INTEGER DEFAULT 1,
|
||||||
|
credits REAL DEFAULT 0, last_seen INTEGER,
|
||||||
|
status TEXT DEFAULT 'idle', version TEXT DEFAULT '1.0'
|
||||||
|
)""")
|
||||||
|
c.execute("""CREATE TABLE IF NOT EXISTS accounts (
|
||||||
|
id TEXT PRIMARY KEY, credits REAL DEFAULT 10.0, created_at INTEGER
|
||||||
|
)""")
|
||||||
|
c.execute("""CREATE TABLE IF NOT EXISTS jobs (
|
||||||
|
id TEXT PRIMARY KEY, model TEXT, node_id TEXT,
|
||||||
|
credits_cost REAL DEFAULT 0.1, status TEXT DEFAULT 'pending',
|
||||||
|
created_at INTEGER, completed_at INTEGER
|
||||||
|
)""")
|
||||||
|
c.commit()
|
||||||
|
|
||||||
|
init_db()
|
||||||
|
|
||||||
|
@app.post("/register-node")
|
||||||
|
async def register_node(request: Request):
|
||||||
|
"""Register your IX instance as a relay node."""
|
||||||
|
data = await request.json()
|
||||||
|
node_id = hashlib.sha256(
|
||||||
|
f"{data.get('endpoint','')}{secrets.token_hex(8)}".encode()
|
||||||
|
).hexdigest()[:16]
|
||||||
|
with db() as c:
|
||||||
|
c.execute("""INSERT OR REPLACE INTO nodes (id,endpoint,backend,capacity,last_seen,version)
|
||||||
|
VALUES (?,?,?,?,?,?)""",
|
||||||
|
(node_id, data.get("endpoint",""), data.get("backend","cpu"),
|
||||||
|
int(data.get("capacity",1)), int(time.time()), data.get("version","1.0")))
|
||||||
|
c.commit()
|
||||||
|
return {"node_id":node_id,
|
||||||
|
"message":"Node registered. You will receive inference jobs and earn credits.",
|
||||||
|
"initial_credits":0}
|
||||||
|
|
||||||
|
@app.get("/nodes")
|
||||||
|
async def list_nodes():
|
||||||
|
"""List active relay nodes (last 5 minutes)."""
|
||||||
|
cutoff = int(time.time()) - 300
|
||||||
|
with db() as c:
|
||||||
|
rows = c.execute("""SELECT id,backend,capacity,credits,status
|
||||||
|
FROM nodes WHERE last_seen > ? ORDER BY credits DESC""", (cutoff,)).fetchall()
|
||||||
|
return {"active_nodes":len(rows),"nodes":[dict(r) for r in rows]}
|
||||||
|
|
||||||
|
@app.get("/credits/{account_id}")
|
||||||
|
async def get_credits(account_id: str):
|
||||||
|
with db() as c:
|
||||||
|
acc = c.execute("SELECT credits FROM accounts WHERE id=?", (account_id,)).fetchone()
|
||||||
|
if not acc:
|
||||||
|
return JSONResponse({"error":"Account not found"}, status_code=404)
|
||||||
|
return {"account_id":account_id,"credits":acc["credits"]}
|
||||||
|
|
||||||
|
@app.post("/create-account")
|
||||||
|
async def create_account():
|
||||||
|
account_id = secrets.token_hex(16)
|
||||||
|
with db() as c:
|
||||||
|
c.execute("INSERT INTO accounts (id,credits,created_at) VALUES (?,?,?)",
|
||||||
|
(account_id, 10.0, int(time.time())))
|
||||||
|
c.commit()
|
||||||
|
return {"account_id":account_id,"initial_credits":10.0,
|
||||||
|
"message":"Account created. 10 free credits to start."}
|
||||||
|
|
||||||
|
@app.get("/health")
|
||||||
|
async def health():
|
||||||
|
return {"status":"ok","service":"IX Relay","author":"Salka Elmadani","version":"1.0.0"}
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import uvicorn
|
||||||
|
print("IX Relay — Federated Inference Network")
|
||||||
|
print("The khettara for AI power.")
|
||||||
|
print("Built in Morocco for the world.")
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT","7938")))
|
||||||
Loading…
Reference in New Issue
Block a user