Skip to content
This repository was archived by the owner on Jun 5, 2025. It is now read-only.

Commit 941e824

Browse files
committed
feat: version endpoint
1 parent 8106c53 commit 941e824

File tree

4 files changed

+59
-5
lines changed

4 files changed

+59
-5
lines changed

poetry.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ build = ">=1.0.0"
4040
wheel = ">=0.40.0"
4141
litellm = ">=1.52.11"
4242
pytest-asyncio = "0.25.2"
43-
llama_cpp_python = ">=0.3.2"
43+
llama_cpp_python = "==0.3.5"
4444
scikit-learn = ">=1.6.0"
4545
python-dotenv = ">=1.0.1"
4646

src/codegate/server.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import traceback
2+
from typing import AsyncGenerator
23

34
import structlog
4-
from fastapi import APIRouter, FastAPI, Request
5+
from fastapi import APIRouter, Depends, FastAPI, HTTPException, Request
56
from fastapi.middleware.cors import CORSMiddleware
67
from fastapi.responses import JSONResponse
78
from starlette.middleware.errors import ServerErrorMiddleware
9+
from httpx import AsyncClient, HTTPStatusError
810

911
from codegate import __description__, __version__
1012
from codegate.dashboard.dashboard import dashboard_router
@@ -27,6 +29,23 @@ async def custom_error_handler(request, exc: Exception):
2729
logger.error(traceback.print_list(extracted_traceback[-3:]))
2830
return JSONResponse({"error": str(exc)}, status_code=500)
2931

32+
async def get_http_client() -> AsyncGenerator[AsyncClient, None]:
33+
async with AsyncClient() as client:
34+
yield client
35+
36+
async def fetch_latest_version(client: AsyncClient) -> str:
37+
url = "https://api.github.com/repos/stacklok/codegate/releases/latest"
38+
headers = {
39+
"Accept": "application/vnd.github+json",
40+
"X-GitHub-Api-Version": "2022-11-28"
41+
}
42+
try:
43+
response = await client.get(url, headers=headers)
44+
response.raise_for_status()
45+
data = response.json()
46+
return data.get("tag_name", "unknown")
47+
except HTTPStatusError as e:
48+
raise HTTPException(status_code=e.response.status_code, detail=str(e))
3049

3150
def init_app(pipeline_factory: PipelineFactory) -> FastAPI:
3251
"""Create the FastAPI application."""
@@ -94,6 +113,26 @@ async def log_user_agent(request: Request, call_next):
94113
async def health_check():
95114
return {"status": "healthy"}
96115

116+
@system_router.get("/version")
117+
async def version_check(client: AsyncClient = Depends(get_http_client)):
118+
try:
119+
latest_version = await fetch_latest_version(client)
120+
121+
# normalize the versions as github will return them with a 'v' prefix
122+
current_version = __version__.lstrip('v')
123+
latest_version_stripped = latest_version.lstrip('v')
124+
125+
is_latest: bool = latest_version_stripped == current_version
126+
127+
return {
128+
"current_version": current_version,
129+
"latest_version": latest_version_stripped,
130+
"is_latest": is_latest,
131+
}
132+
except HTTPException as e:
133+
return {"current_version": __version__, "latest_version": "unknown", "error": e.detail}
134+
135+
97136
app.include_router(system_router)
98137
app.include_router(dashboard_router)
99138

tests/test_server.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,21 @@ def test_health_check(test_client: TestClient) -> None:
8181
assert response.status_code == 200
8282
assert response.json() == {"status": "healthy"}
8383

84+
def test_version_endpoint(test_client: TestClient) -> None:
85+
"""Test the version endpoint."""
86+
response = test_client.get("/version")
87+
assert response.status_code == 200
88+
89+
response_data = response.json()
90+
assert "current_version" in response_data
91+
assert isinstance(response_data["current_version"], str)
92+
93+
assert "latest_version" in response_data
94+
assert isinstance(response_data["latest_version"], str)
95+
96+
assert "is_latest" in response_data
97+
assert isinstance(response_data["is_latest"], bool)
98+
8499

85100
@patch("codegate.pipeline.secrets.manager.SecretsManager")
86101
@patch("codegate.server.ProviderRegistry")

0 commit comments

Comments
 (0)