Compare commits

...
Author SHA1 Message Date
Nicolò Boschi 50c38f8a53 Add Python client get_version helper
Adds HindsightClient.get_version()/aget_version() convenience wrappers for
the existing /version endpoint, re-exports VersionResponse for typed callers,
and tests both paths against a mocked MonitoringApi.

Python parity for #2252 (TypeScript getVersion). Fixes #2248.
2026-06-17 11:23:02 +02:00
3 changed files with 83 additions and 0 deletions
@@ -53,6 +53,7 @@ from hindsight_client_api.models.reflect_response import ReflectResponse
# Re-export response types for convenient access
from hindsight_client_api.models.retain_response import RetainResponse
from hindsight_client_api.models.version_response import VersionResponse
from .hindsight_client import Hindsight
@@ -159,4 +160,5 @@ __all__ = [
"ListMemoryUnitsResponse",
"BankProfileResponse",
"DispositionTraits",
"VersionResponse",
]
@@ -46,6 +46,7 @@ from hindsight_client_api.models.list_memory_units_response import ListMemoryUni
from hindsight_client_api.models.recall_response import RecallResponse
from hindsight_client_api.models.reflect_response import ReflectResponse
from hindsight_client_api.models.retain_response import RetainResponse
from hindsight_client_api.models.version_response import VersionResponse
def _run_async(coro):
@@ -245,6 +246,29 @@ class Hindsight:
if self._api_client:
await self._api_client.close()
def get_version(self) -> VersionResponse:
"""
Read the connected Hindsight API version and feature flags
(sync wrapper — prefer :meth:`aget_version` in async code).
Useful for integrations that need to enforce a minimum server version
before enabling a workflow.
Returns:
VersionResponse with ``api_version`` and ``features``.
"""
return _run_async(self._monitoring_api.get_version(_request_timeout=self._timeout))
async def aget_version(self) -> VersionResponse:
"""
Read the connected Hindsight API version and feature flags
(async — preferred over :meth:`get_version`).
Returns:
VersionResponse with ``api_version`` and ``features``.
"""
return await self._monitoring_api.get_version(_request_timeout=self._timeout)
# Simplified methods for main operations
def retain(
@@ -0,0 +1,57 @@
"""
Tests for the get_version()/aget_version() convenience wrappers.
These mock the underlying MonitoringApi so no running server is required —
they verify the wrapper delegates to the generated client and returns the
typed VersionResponse (parity with the TypeScript client's getVersion helper).
"""
from unittest.mock import AsyncMock
from hindsight_client import Hindsight, VersionResponse
from hindsight_client_api.models.features_info import FeaturesInfo
def _make_client() -> Hindsight:
return Hindsight(base_url="http://localhost:8888")
def _version_response() -> VersionResponse:
features = FeaturesInfo(
observations=True,
mcp=True,
worker=True,
bank_config_api=True,
bank_llm_health=True,
file_upload_api=True,
document_export_api=True,
document_import_api=True,
audit_log=True,
llm_trace=True,
store_document_text=True,
)
return VersionResponse(api_version="0.8.2", features=features)
async def test_aget_version_delegates_to_monitoring_api():
"""aget_version() should call MonitoringApi.get_version and return its result."""
client = _make_client()
client._monitoring_api.get_version = AsyncMock(return_value=_version_response())
version = await client.aget_version()
assert version.api_version == "0.8.2"
assert version.features.observations is True
client._monitoring_api.get_version.assert_awaited_once()
def test_get_version_delegates_to_monitoring_api():
"""get_version() (sync) should call MonitoringApi.get_version and return its result."""
client = _make_client()
# AsyncMock returns an awaitable when called, which the sync wrapper awaits via _run_async.
client._monitoring_api.get_version = AsyncMock(return_value=_version_response())
version = client.get_version()
assert version.api_version == "0.8.2"
client._monitoring_api.get_version.assert_called_once()