diff --git a/ollama/_client.py b/ollama/_client.py index 3654e3c0..e420e909 100644 --- a/ollama/_client.py +++ b/ollama/_client.py @@ -750,6 +750,18 @@ def web_fetch(self, url: str) -> WebFetchResponse: ).model_dump(exclude_none=True), ) + def ping(self) -> bool: + """ + Check whether the Ollama server is running and reachable. + + Returns True if the server responds to the /api/version health endpoint. + """ + try: + data = self._request_raw('GET', '/api/version').json() + return bool(data) and 'version' in data + except ConnectionError: + return False + class AsyncClient(BaseClient): def __init__(self, host: Optional[str] = None, **kwargs) -> None: @@ -862,6 +874,18 @@ async def web_fetch(self, url: str) -> WebFetchResponse: ).model_dump(exclude_none=True), ) + async def ping(self) -> bool: + """ + Check whether the Ollama server is running and reachable. + + Returns True if the server responds to the /api/version health endpoint. + """ + try: + data = (await self._request_raw('GET', '/api/version')).json() + return bool(data) and 'version' in data + except ConnectionError: + return False + @overload async def generate( self, diff --git a/tests/test_type_serialization.py b/tests/test_type_serialization.py index e1af3512..f107fd36 100644 --- a/tests/test_type_serialization.py +++ b/tests/test_type_serialization.py @@ -122,3 +122,29 @@ def test_think_boolean_serialization(): assert ChatRequest(model='test-model', think=True).model_dump(exclude_none=True)['think'] is True assert ChatRequest(model='test-model', think=False).model_dump(exclude_none=True)['think'] is False assert 'think' not in ChatRequest(model='test-model', think=None).model_dump(exclude_none=True) + + +def test_client_ping_reports_reachable_server(): + from unittest.mock import Mock, patch + from ollama import Client, AsyncClient + mock_resp = Mock() + mock_resp.json.return_value = {'version': '0.1.0'} + with patch.object(Client, '_request_raw', return_value=mock_resp): + assert Client().ping() is True + async def run(): + with patch.object(AsyncClient, '_request_raw', return_value=mock_resp): + return await AsyncClient().ping() + import asyncio + assert asyncio.run(run()) is True + + +def test_client_ping_reports_unreachable_server(): + from unittest.mock import patch + from ollama import Client, AsyncClient + with patch.object(Client, '_request_raw', side_effect=ConnectionError('down')): + assert Client().ping() is False + async def run(): + with patch.object(AsyncClient, '_request_raw', side_effect=ConnectionError('down')): + return await AsyncClient().ping() + import asyncio + assert asyncio.run(run()) is False