Skip to content

Commit a11502b

Browse files
authored
Add dedicated configure_default_client API (#82)
Closes #67
1 parent 26bda17 commit a11502b

File tree

3 files changed

+60
-6
lines changed

3 files changed

+60
-6
lines changed

src/lmstudio/json_api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,8 @@ def request_tool_call(
13921392
def _call_requested_tool() -> ToolCallResultData:
13931393
call_result = implementation(**kwds)
13941394
return ToolCallResultData(
1395-
content=json.dumps(call_result, ensure_ascii=False), tool_call_id=tool_call_id
1395+
content=json.dumps(call_result, ensure_ascii=False),
1396+
tool_call_id=tool_call_id,
13961397
)
13971398

13981399
return _call_requested_tool

src/lmstudio/sync_api.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
"LLM",
140140
"SyncModelHandle",
141141
"PredictionStream",
142+
"configure_default_client",
142143
"get_default_client",
143144
"embedding_model",
144145
"list_downloaded_models",
@@ -1606,22 +1607,43 @@ def list_loaded_models(
16061607

16071608

16081609
# Convenience API
1610+
_default_api_host = None
16091611
_default_client: Client | None = None
16101612

16111613

1614+
@sdk_public_api()
1615+
def configure_default_client(api_host: str) -> None:
1616+
"""Set the server API host for the default global client (without creating the client)."""
1617+
global _default_api_host
1618+
if _default_client is not None:
1619+
raise LMStudioClientError(
1620+
"Default client is already created, cannot set its API host."
1621+
)
1622+
_default_api_host = api_host
1623+
1624+
16121625
@sdk_public_api()
16131626
def get_default_client(api_host: str | None = None) -> Client:
16141627
"""Get the default global client (creating it if necessary)."""
16151628
global _default_client
1629+
if api_host is not None:
1630+
# This will raise an exception if the client already exists
1631+
configure_default_client(api_host)
16161632
if _default_client is None:
1617-
_default_client = Client(api_host)
1618-
elif api_host is not None:
1619-
raise LMStudioClientError(
1620-
"Default session already connected, cannot set API host."
1621-
)
1633+
_default_client = Client(_default_api_host)
16221634
return _default_client
16231635

16241636

1637+
def _reset_default_client() -> None:
1638+
# Allow the test suite to reset the client without
1639+
# having to poke directly at the module's internals
1640+
global _default_api_host, _default_client
1641+
previous_client = _default_client
1642+
_default_api_host = _default_client = None
1643+
if previous_client is not None:
1644+
previous_client.close()
1645+
1646+
16251647
@sdk_public_api()
16261648
def llm(
16271649
model_key: str | None = None,

tests/test_convenience_api.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,44 @@
1313
EXPECTED_VLM_ID,
1414
IMAGE_FILEPATH,
1515
TOOL_LLM_ID,
16+
closed_api_host,
1617
)
1718

1819

1920
@pytest.mark.lmstudio
2021
def test_get_default_client() -> None:
2122
client = lms.get_default_client()
2223
assert isinstance(client, lms.Client)
24+
# Setting the API host after creation is disallowed (even if it is consistent)
25+
with pytest.raises(lms.LMStudioClientError, match="already created"):
26+
lms.get_default_client("localhost:1234")
27+
# Ensure configured API host is used
28+
lms.sync_api._reset_default_client()
29+
try:
30+
with pytest.raises(lms.LMStudioWebsocketError, match="not reachable"):
31+
# Actually try to use the client in order to force a connection attempt
32+
lms.get_default_client(closed_api_host()).list_loaded_models()
33+
finally:
34+
lms.sync_api._reset_default_client()
35+
36+
37+
@pytest.mark.lmstudio
38+
def test_configure_default_client() -> None:
39+
# Ensure the default client already exists
40+
client = lms.get_default_client()
41+
assert isinstance(client, lms.Client)
42+
# Setting the API host after creation is disallowed (even if it is consistent)
43+
with pytest.raises(lms.LMStudioClientError, match="already created"):
44+
lms.configure_default_client("localhost:1234")
45+
# Ensure configured API host is used
46+
lms.sync_api._reset_default_client()
47+
try:
48+
lms.configure_default_client(closed_api_host())
49+
with pytest.raises(lms.LMStudioWebsocketError, match="not reachable"):
50+
# Actually try to use the client in order to force a connection attempt
51+
lms.get_default_client().list_loaded_models()
52+
finally:
53+
lms.sync_api._reset_default_client()
2354

2455

2556
@pytest.mark.lmstudio

0 commit comments

Comments
 (0)