Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/AI_Brain / sub_brains/money_agents/dashboard.py |
| Date | Not specified in source |
| Repository | Janady13/AI_Brain |
| Revision | 11aa50ef5d7692e8abd1b8d74ae31c5c29201b14 |
| Branch | codex/build-online-github-ani-irqa7y |
| Path or archive member | sub_brains/money_agents/dashboard.py |
| Original SHA-256 | f39e8129a83c80d1167e449d1ac85e988629d8a8944ab59e657207dcc711c8f7 |
| Git blob SHA | aee83aa96a008d8b3798709976ec890a130a0879 |
| Reading-copy SHA-256 | f39e8129a83c80d1167e449d1ac85e988629d8a8944ab59e657207dcc711c8f7 |
Every recorded occurrence
These 23 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-irqa7y | 11aa50ef5d7692e8abd1b8d74ae31c5c29201b14 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-hr4y0z | 366ab848896ae49159cfb3f6c201b8c5a731e9c8 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-i3cigl | 3a6e002311c48c27ffd41ef4a2a31c63947128cd | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani | 49db80a641b10ab62d16cc7643bd0b367f93951c | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-hrtsoc | 50285aff347685f043e7a72e4d72891eebaa6cd6 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-7v4kug | 5cd0bbf744b0aee9445913337e852889d9a8098e | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-nbgsix | 840945d70b88674d8f40d330001cc63d871dc8e2 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | copilot/vscode1760283895982 | 9e1c1a5b171addb5bb4a83b2ea7dede50c1cc81e | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-jf5olo | c6653627c453ab428d665226167fa5f4aa05e9a5 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | feature/seeder-engine-tests | cdb497ece2d1a770ca8c83eb1de8923cfaa9eceb | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-7nmb21 | d0f50071c85cddaaebbf9c4dd1313bd7676986da | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-0etkns | e250b19d446bdffd542c9eea31cead12e30800d6 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-hr4y0z | 366ab848896ae49159cfb3f6c201b8c5a731e9c8 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-irqa7y | 11aa50ef5d7692e8abd1b8d74ae31c5c29201b14 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-i3cigl | 3a6e002311c48c27ffd41ef4a2a31c63947128cd | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-7v4kug | 5cd0bbf744b0aee9445913337e852889d9a8098e | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-nbgsix | 840945d70b88674d8f40d330001cc63d871dc8e2 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | copilot/vscode1760283895982 | 9e1c1a5b171addb5bb4a83b2ea7dede50c1cc81e | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-7nmb21 | d0f50071c85cddaaebbf9c4dd1313bd7676986da | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | feature/seeder-engine-tests | cdb497ece2d1a770ca8c83eb1de8923cfaa9eceb | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani | 49db80a641b10ab62d16cc7643bd0b367f93951c | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-jf5olo | c6653627c453ab428d665226167fa5f4aa05e9a5 | Open original |
| Janady13/AI_Brain / sub_brains/money_agents/dashboard.py | codex/build-online-github-ani-hrtsoc | 50285aff347685f043e7a72e4d72891eebaa6cd6 | Open original |
Recovered source transcript
Download complete source text ↓149 lines · 4.7 KB
#!/usr/bin/env python3
import logging
import os
import sys
import time
import uuid
from typing import Any, Dict
import psycopg
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from psycopg.rows import dict_row
DB_URL = os.environ.get("DATABASE_URL")
if not DB_URL:
print("ERR: DATABASE_URL not set", file=sys.stderr)
sys.exit(1)
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
templates = Jinja2Templates(directory=os.path.join(BASE_DIR, "templates"))
app = FastAPI(title="Money Agents Dashboard")
# Simple JSON logger with request IDs
logger = logging.getLogger("money_agents.dashboard")
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("%(message)s"))
logger.setLevel(logging.INFO)
logger.addHandler(handler)
@app.middleware("http")
async def add_request_id_logging(request: Request, call_next):
rid = request.headers.get("X-Request-ID", str(uuid.uuid4()))
start = time.time()
try:
response = await call_next(request)
return response
finally:
dur_ms = int((time.time() - start) * 1000)
record = {
"event": "http_request",
"method": request.method,
"path": request.url.path,
"status": getattr(response, "status_code", 0),
"duration_ms": dur_ms,
"request_id": rid,
}
logger.info(__import__("json").dumps(record))
def db_fetch(sql: str, args: tuple = ()):
with psycopg.connect(DB_URL) as conn:
with conn.cursor(row_factory=dict_row) as cur:
cur.execute(sql, args)
return list(cur.fetchall())
@app.get("/", response_class=HTMLResponse)
def index(request: Request):
return templates.TemplateResponse(
"index.html",
{
"request": request,
},
)
@app.get("/healthz")
def healthz():
return JSONResponse({"status": "ok"})
@app.get("/readyz")
def readyz():
try:
db_fetch("SELECT 1")
return JSONResponse({"status": "ready"})
except Exception as e:
return JSONResponse({"status": "not_ready", "error": str(e)}, status_code=503)
@app.get("/panel/overview", response_class=HTMLResponse)
def panel_overview(request: Request):
revenue = db_fetch("SELECT revenue FROM revenue_v")
revenue_val = revenue[0]["revenue"] if revenue else 0
active_workers = db_fetch("""
SELECT COUNT(*) AS n FROM (
SELECT worker_id, MAX(ts) AS last FROM logs
WHERE ts > NOW() - interval '30 seconds' AND worker_id IS NOT NULL
GROUP BY worker_id
) t
""")
active = active_workers[0]["n"] if active_workers else 0
jobs_pending = db_fetch("SELECT COUNT(*) AS n FROM jobs WHERE status='pending'")
pending = jobs_pending[0]["n"] if jobs_pending else 0
return templates.TemplateResponse(
"panel_overview.html",
{"request": request, "revenue": revenue_val, "active": active, "pending": pending},
)
@app.get("/panel/jobs", response_class=HTMLResponse)
def panel_jobs(request: Request):
rows = db_fetch(
"SELECT id, status, payload, started_at, finished_at FROM jobs ORDER BY id DESC LIMIT 100"
)
return templates.TemplateResponse("panel_jobs.html", {"request": request, "rows": rows})
@app.get("/panel/workers", response_class=HTMLResponse)
def panel_workers(request: Request):
rows = db_fetch(
"""
SELECT worker_id,
MAX(ts) AS last_heartbeat,
SUM(CASE WHEN message='completed' THEN 1 ELSE 0 END) AS jobs_completed
FROM logs WHERE worker_id IS NOT NULL
GROUP BY worker_id
ORDER BY last_heartbeat DESC
LIMIT 100
"""
)
return templates.TemplateResponse("panel_workers.html", {"request": request, "rows": rows})
@app.get("/panel/transactions", response_class=HTMLResponse)
def panel_transactions(request: Request):
rows = db_fetch(
"SELECT id, job_id, amount, service, status, ts FROM transactions ORDER BY ts DESC LIMIT 100"
)
return templates.TemplateResponse("panel_transactions.html", {"request": request, "rows": rows})
@app.get("/panel/logs", response_class=HTMLResponse)
def panel_logs(request: Request, q: str = ""):
if q:
rows = db_fetch(
"SELECT id, worker_id, job_id, level, message, ts FROM logs WHERE message ILIKE %s OR level ILIKE %s ORDER BY ts DESC LIMIT 100",
(f"%{q}%", f"%{q}%"),
)
else:
rows = db_fetch(
"SELECT id, worker_id, job_id, level, message, ts FROM logs ORDER BY ts DESC LIMIT 100"
)
return templates.TemplateResponse("panel_logs.html", {"request": request, "rows": rows, "q": q})