Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions src/lean_spec/node/api/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

from collections.abc import Awaitable, Callable
from typing import NamedTuple

from aiohttp import web

Expand All @@ -18,17 +19,30 @@
Handler = Callable[[web.Request], Awaitable[web.Response]]
"""Type alias for aiohttp request handlers."""

ROUTES: dict[str, Handler] = {
"/lean/v0/health": health.handle,
"/lean/v0/states/finalized": states.handle_finalized,
"/lean/v0/checkpoints/justified": checkpoints.handle_justified,
"/lean/v0/fork_choice": fork_choice.handle,
"/metrics": metrics.handle,
}
"""Read-only API routes registered as GET."""

ADMIN_ROUTES: list[tuple[str, str, Handler]] = [
("GET", "/lean/v0/admin/aggregator", aggregator.handle_status),
("POST", "/lean/v0/admin/aggregator", aggregator.handle_toggle),

class Route(NamedTuple):
"""One API route: its verb, path, handler, and access tier."""

method: str
"""HTTP verb the route responds to."""

path: str
"""URL path the route is registered under."""

handler: Handler
"""Coroutine that serves requests to this route."""

is_admin: bool
"""True for privileged admin routes, False for public read-only routes."""


ROUTES: list[Route] = [
Route("GET", "/lean/v0/health", health.handle, is_admin=False),
Route("GET", "/lean/v0/states/finalized", states.handle_finalized, is_admin=False),
Route("GET", "/lean/v0/checkpoints/justified", checkpoints.handle_justified, is_admin=False),
Route("GET", "/lean/v0/fork_choice", fork_choice.handle, is_admin=False),
Route("GET", "/metrics", metrics.handle, is_admin=False),
Route("GET", "/lean/v0/admin/aggregator", aggregator.handle_status, is_admin=True),
Route("POST", "/lean/v0/admin/aggregator", aggregator.handle_toggle, is_admin=True),
]
"""Admin routes as (method, path, handler) triples for non-GET verbs."""
"""Every API route, public and admin alike, tagged by access tier."""
7 changes: 3 additions & 4 deletions src/lean_spec/node/api/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from aiohttp import web

from lean_spec.node.api.aggregator_controller import AggregatorController
from lean_spec.node.api.routes import ADMIN_ROUTES, ROUTES
from lean_spec.node.api.routes import ROUTES
from lean_spec.spec.forks import LstarSpec, Store

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -99,9 +99,8 @@ async def start(self) -> None:
# Absence is fine; endpoints return 503 when unset.
app["aggregator_controller"] = self.aggregator_controller

# Add all routes, generated from ROUTES and ADMIN_ROUTES.
routes = [web.get(path, handler) for path, handler in ROUTES.items()]
routes += [web.route(method, path, handler) for method, path, handler in ADMIN_ROUTES]
# Register every route from the unified table, keyed by its verb.
routes = [web.route(route.method, route.path, route.handler) for route in ROUTES]
app.add_routes(routes)

self._runner = web.AppRunner(app)
Expand Down
Loading