Skip to content

Commit 690298d

Browse files
authored
feat: add versioning to api endpoints (#323)
* feat: add versioning to api endpoints * feat: version health as well
1 parent 914e093 commit 690298d

4 files changed

Lines changed: 20 additions & 20 deletions

File tree

src/lean_spec/subspecs/api/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
API server module for checkpoint sync and node status endpoints.
33
44
Provides HTTP endpoints for:
5-
- /lean/states/finalized - Serve finalized checkpoint state as SSZ
6-
- /health - Health check endpoint
5+
- /lean/v0/states/finalized - Serve finalized checkpoint state as SSZ
6+
- /lean/v0/health - Health check endpoint
77
88
Also provides a client for checkpoint sync:
99
- fetch_finalized_state: Download finalized state from a node

src/lean_spec/subspecs/api/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
DEFAULT_TIMEOUT = 60.0
3636
"""HTTP request timeout in seconds. Large states may take time to transfer."""
3737

38-
FINALIZED_STATE_ENDPOINT = "/lean/states/finalized"
38+
FINALIZED_STATE_ENDPOINT = "/lean/v0/states/finalized"
3939
"""API endpoint for fetching finalized state. Follows Beacon API conventions."""
4040

4141

src/lean_spec/subspecs/api/server.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
API server for checkpoint sync, node status, and metrics endpoints.
33
44
Provides HTTP endpoints for:
5-
- /lean/states/finalized - Serve finalized checkpoint state as SSZ
6-
- /lean/states/justified - Return latest justified checkpoint information
7-
- /health - Health check endpoint
5+
- /lean/v0/states/finalized - Serve finalized checkpoint state as SSZ
6+
- /lean/v0/states/justified - Return latest justified checkpoint information
7+
- /lean/v0/health - Health check endpoint
88
- /metrics - Prometheus metrics endpoint
99
1010
This matches the checkpoint sync API implemented in zeam.
@@ -98,10 +98,10 @@ async def start(self) -> None:
9898
app = web.Application()
9999
app.add_routes(
100100
[
101-
web.get("/health", _handle_health),
101+
web.get("/lean/v0/health", _handle_health),
102102
web.get("/metrics", _handle_metrics),
103-
web.get("/lean/states/finalized", self._handle_finalized_state),
104-
web.get("/lean/states/justified", self._handle_justified),
103+
web.get("/lean/v0/states/finalized", self._handle_finalized_state),
104+
web.get("/lean/v0/states/justified", self._handle_justified_state),
105105
]
106106
)
107107

@@ -142,7 +142,7 @@ async def _handle_finalized_state(self, _request: web.Request) -> web.Response:
142142
"""
143143
Handle finalized checkpoint state endpoint.
144144
145-
Serves the finalized state as SSZ binary at /lean/states/finalized.
145+
Serves the finalized state as SSZ binary at /lean/v0/states/finalized.
146146
This endpoint is used for checkpoint sync - clients can download
147147
the finalized state to bootstrap quickly instead of syncing from genesis.
148148
"""
@@ -166,11 +166,11 @@ async def _handle_finalized_state(self, _request: web.Request) -> web.Response:
166166

167167
return web.Response(body=ssz_bytes, content_type="application/octet-stream")
168168

169-
async def _handle_justified(self, _request: web.Request) -> web.Response:
169+
async def _handle_justified_state(self, _request: web.Request) -> web.Response:
170170
"""
171171
Handle latest justified checkpoint endpoint.
172172
173-
Returns the latest justified checkpoint information as JSON at /lean/states/justified.
173+
Returns the latest justified checkpoint information as JSON at /lean/v0/states/justified.
174174
This provides the slot number and root hash of the most recent justified checkpoint,
175175
which is useful for monitoring consensus progress and fork choice state.
176176

tests/lean_spec/subspecs/api/test_server.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def test_store_getter_provides_access_to_store(self, base_store: Store) -> None:
6262

6363

6464
class TestHealthEndpoint:
65-
"""Tests for the /health endpoint behavior."""
65+
"""Tests for the /lean/v0/health endpoint behavior."""
6666

6767
def test_returns_healthy_status_json(self) -> None:
6868
"""Health endpoint returns JSON with healthy status."""
@@ -75,7 +75,7 @@ async def run_test() -> None:
7575

7676
try:
7777
async with httpx.AsyncClient() as client:
78-
response = await client.get("http://127.0.0.1:15052/health")
78+
response = await client.get("http://127.0.0.1:15052/lean/v0/health")
7979

8080
assert response.status_code == 200
8181
data = response.json()
@@ -90,7 +90,7 @@ async def run_test() -> None:
9090

9191

9292
class TestFinalizedStateEndpoint:
93-
"""Tests for the /lean/states/finalized endpoint behavior."""
93+
"""Tests for the /lean/v0/states/finalized endpoint behavior."""
9494

9595
def test_returns_503_when_store_not_initialized(self) -> None:
9696
"""Endpoint returns 503 Service Unavailable when store is not set."""
@@ -103,7 +103,7 @@ async def run_test() -> None:
103103

104104
try:
105105
async with httpx.AsyncClient() as client:
106-
response = await client.get("http://127.0.0.1:15054/lean/states/finalized")
106+
response = await client.get("http://127.0.0.1:15054/lean/v0/states/finalized")
107107

108108
assert response.status_code == 503
109109

@@ -124,7 +124,7 @@ async def run_test() -> None:
124124

125125
try:
126126
async with httpx.AsyncClient() as client:
127-
response = await client.get("http://127.0.0.1:15056/lean/states/finalized")
127+
response = await client.get("http://127.0.0.1:15056/lean/v0/states/finalized")
128128

129129
assert response.status_code == 200
130130
assert response.headers["content-type"] == "application/octet-stream"
@@ -143,7 +143,7 @@ async def run_test() -> None:
143143

144144

145145
class TestJustifiedEndpoint:
146-
"""Tests for the /lean/states/justified endpoint behavior."""
146+
"""Tests for the /lean/v0/states/justified endpoint behavior."""
147147

148148
def test_returns_503_when_store_not_initialized(self) -> None:
149149
"""Endpoint returns 503 Service Unavailable when store is not set."""
@@ -156,7 +156,7 @@ async def run_test() -> None:
156156

157157
try:
158158
async with httpx.AsyncClient() as client:
159-
response = await client.get("http://127.0.0.1:15057/lean/states/justified")
159+
response = await client.get("http://127.0.0.1:15057/lean/v0/states/justified")
160160

161161
assert response.status_code == 503
162162

@@ -177,7 +177,7 @@ async def run_test() -> None:
177177

178178
try:
179179
async with httpx.AsyncClient() as client:
180-
response = await client.get("http://127.0.0.1:15058/lean/states/justified")
180+
response = await client.get("http://127.0.0.1:15058/lean/v0/states/justified")
181181

182182
assert response.status_code == 200
183183
assert "application/json" in response.headers["content-type"]

0 commit comments

Comments
 (0)