fester/backend/api/api.py

108 lines
3.1 KiB
Python

"""
Fester backend — core API facade.
This module exposes a single `bus`, `registry`, `observability`, `ws_stream`,
plus thin wrapper functions for the API layer. It used to be broken
(referenced `bus` before creation, imported nonexistent `_endpoint` symbols,
duplicated CauseGraphEngine setup). It now wires everything cleanly.
"""
from backend.events.bus import EventBus
from backend.metrics.observability import ObservabilityHub
from backend.metrics.node_state import NodeStateRegistry
from backend.analysis.cause_graph import CauseGraphEngine
# =========================================================
# GLOBAL CORE SYSTEM INITIALIZATION (SINGLETON LAYER)
# =========================================================
bus = EventBus()
registry = NodeStateRegistry()
observability = ObservabilityHub(registry, bus)
observability.attach_bus()
# Cause graph — subscribes ONCE, no recursion (ingest only)
cause_graph = CauseGraphEngine()
cause_graph.attach_bus(bus)
bus.subscribe(cause_graph.ingest)
# WebSocket stream — attached lazily by main.py when FastAPI starts,
# because the WS layer needs the running app's connection registry.
ws_stream = None # set by backend.main when app boots
def attach_ws_stream(stream):
"""Called by backend.main during startup to bind a WebSocketStream."""
global ws_stream
ws_stream = stream
ws_stream.attach_bus(bus)
# =========================================================
# API REGISTRATION LAYER
# Thin wrappers so Cockpit / external callers can bind cleanly.
# =========================================================
# These imports are deliberately placed AFTER the singletons above are
# initialized, because some api/* modules may want to import `bus` etc.
from backend.api import build as build_api
from backend.api import nodes as nodes_api
from backend.api import replay as replay_api
from backend.api import debugger as debugger_api
from backend.api import timeline as timeline_api
from backend.api import metrics as metrics_api
from backend.api import autopsy as autopsy_api
from backend.api import pipeline_control as pipeline_control_api
from backend.api import cause as cause_api
def build(spec, nodes, cluster=None, intelligence=None):
return build_api.build_endpoint(spec, nodes, cluster, intelligence)
def replay(session_id):
return replay_api.replay_endpoint(session_id, registry)
def debugger(session_id):
return debugger_api.debugger_endpoint(session_id, registry, bus)
def timeline(session_id):
return timeline_api.timeline_endpoint(session_id)
def nodes():
return nodes_api.nodes_endpoint(registry)
def metrics():
return metrics_api.metrics_endpoint(registry)
def autopsy(session_id):
return autopsy_api.autopsy_endpoint(session_id)
def pipeline_control(action, payload=None):
return pipeline_control_api.pipeline_control_endpoint(action, payload, bus)
__all__ = [
"bus",
"registry",
"observability",
"ws_stream",
"cause_graph",
"attach_ws_stream",
"build",
"replay",
"debugger",
"timeline",
"nodes",
"metrics",
"autopsy",
"pipeline_control",
]