Skip to content

Commit b932f8e

Browse files
Danelegendclaude
andcommitted
feat(health): include service version in /health response
Clients can now read ``version`` from the ``/health`` payload to gate calls to functionality that's only available in newer releases. The value is sourced from the installed package metadata rather than a hardcoded string, so the FastAPI app and the health response stay in sync with the version declared in pyproject.toml. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 54b9123 commit b932f8e

3 files changed

Lines changed: 26 additions & 3 deletions

File tree

code-interpreter/app/main.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import subprocess
55
from collections.abc import AsyncGenerator
66
from contextlib import asynccontextmanager
7+
from importlib.metadata import version as _package_version
78
from shutil import which
89
from typing import Final
910

@@ -22,6 +23,8 @@
2223

2324
logger = logging.getLogger(__name__)
2425

26+
SERVICE_VERSION: Final[str] = _package_version("code-interpreter")
27+
2528

2629
def _ensure_docker_image_available() -> None:
2730
"""Ensure the Docker executor image is available locally.
@@ -95,7 +98,7 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
9598
def create_app() -> FastAPI:
9699
app = FastAPI(
97100
title="Code Interpreter API",
98-
version="0.1.0",
101+
version=SERVICE_VERSION,
99102
docs_url="/docs",
100103
redoc_url="/redoc",
101104
openapi_url="/openapi.json",
@@ -106,7 +109,11 @@ def create_app() -> FastAPI:
106109
def health() -> HealthResponse:
107110
"""Health check that verifies the executor backend is operational."""
108111
result = get_executor().check_health()
109-
return HealthResponse(status=result.status, message=result.message)
112+
return HealthResponse(
113+
status=result.status,
114+
message=result.message,
115+
version=SERVICE_VERSION,
116+
)
110117

111118
app.include_router(api_router, prefix="/v1")
112119
return app

code-interpreter/app/models/schemas.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,10 @@ class ListFilesResponse(BaseModel):
120120
class HealthResponse(BaseModel):
121121
status: Literal["ok", "error"]
122122
message: StrictStr | None = None
123+
version: StrictStr = Field(
124+
...,
125+
description=(
126+
"Semver of the running service. Clients can compare against a "
127+
"required minimum to detect whether new functionality is available."
128+
),
129+
)

code-interpreter/tests/integration_tests/test_health.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import pytest
88
from fastapi.testclient import TestClient
99

10-
from app.main import create_app
10+
from app.main import SERVICE_VERSION, create_app
1111
from app.services.executor_base import HealthCheck
1212
from app.services.executor_docker import DockerExecutor
1313
from app.services.executor_factory import get_executor
@@ -29,6 +29,7 @@ def test_health_returns_ok_when_backend_healthy() -> None:
2929
body = response.json()
3030
assert body["status"] == "ok"
3131
assert body["message"] is None
32+
assert body["version"] == SERVICE_VERSION
3233

3334

3435
def test_health_returns_error_when_backend_unhealthy() -> None:
@@ -42,6 +43,14 @@ def test_health_returns_error_when_backend_unhealthy() -> None:
4243
body = response.json()
4344
assert body["status"] == "error"
4445
assert body["message"] == "daemon down"
46+
assert body["version"] == SERVICE_VERSION
47+
48+
49+
def test_health_version_matches_package_metadata() -> None:
50+
"""The version should come from the installed package, not be hardcoded."""
51+
from importlib.metadata import version as package_version
52+
53+
assert package_version("code-interpreter") == SERVICE_VERSION
4554

4655

4756
def _make_completed(returncode: int, stderr: bytes = b"") -> subprocess.CompletedProcess[bytes]:

0 commit comments

Comments
 (0)