Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ def __init__(
compaction_strategy: CompactionStrategy | None = None,
tokenizer: TokenizerProtocol | None = None,
additional_properties: dict[str, Any] | None = None,
timeout: float | None = None,
) -> None:
"""Initialize a raw Microsoft Foundry chat client.

Expand All @@ -207,6 +208,8 @@ def __init__(
compaction_strategy: Optional per-client compaction override.
tokenizer: Optional tokenizer for compaction strategies.
additional_properties: Additional properties stored on the client instance.
timeout: HTTP timeout in seconds for requests. When not provided, the
OpenAI SDK default is used (connect: 5s, total: 600s).
"""
foundry_settings = load_settings(
FoundrySettings,
Expand Down Expand Up @@ -255,9 +258,13 @@ def __init__(
if owns_project_client:
openai_kwargs["http_client"] = create_foundry_feature_usage_http_client()

openai_client = project_client.get_openai_client(**openai_kwargs)
if timeout is not None:
openai_client = openai_client.with_options(timeout=timeout)

super().__init__(
model=resolved_model,
async_client=project_client.get_openai_client(**openai_kwargs),
async_client=openai_client,
default_headers=default_headers,
instruction_role=instruction_role,
compaction_strategy=compaction_strategy,
Expand Down Expand Up @@ -1129,6 +1136,7 @@ def __init__(
additional_properties: dict[str, Any] | None = None,
middleware: (Sequence[ChatAndFunctionMiddlewareTypes] | None) = None,
function_invocation_configuration: FunctionInvocationConfiguration | None = None,
timeout: float | None = None,
) -> None:
"""Initialize a Foundry chat client.

Expand All @@ -1149,6 +1157,8 @@ def __init__(
additional_properties: Additional properties stored on the client instance.
middleware: Optional sequence of middleware.
function_invocation_configuration: Optional function invocation configuration.
timeout: HTTP timeout in seconds for requests. When not provided, the
OpenAI SDK default is used (connect: 5s, total: 600s).
"""
super().__init__(
project_endpoint=project_endpoint,
Expand All @@ -1165,4 +1175,5 @@ def __init__(
additional_properties=additional_properties,
middleware=middleware,
function_invocation_configuration=function_invocation_configuration,
timeout=timeout,
)
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,30 @@ def test_foundry_chat_client_init_uses_explicit_parameters() -> None:
assert all(parameter.kind != inspect.Parameter.VAR_KEYWORD for parameter in signature.parameters.values())


def test_init_applies_timeout_to_openai_client() -> None:
mock_openai_client = _make_mock_openai_client()
timeout_client = _make_mock_openai_client()
mock_openai_client.with_options.return_value = timeout_client
mock_project_client = MagicMock()
mock_project_client.get_openai_client.return_value = mock_openai_client

client = FoundryChatClient(project_client=mock_project_client, model=_TEST_FOUNDRY_MODEL, timeout=12.5)

mock_openai_client.with_options.assert_called_once_with(timeout=12.5)
assert client.client is timeout_client


def test_init_without_timeout_keeps_openai_client() -> None:
mock_openai_client = _make_mock_openai_client()
mock_project_client = MagicMock()
mock_project_client.get_openai_client.return_value = mock_openai_client

client = FoundryChatClient(project_client=mock_project_client, model=_TEST_FOUNDRY_MODEL)

mock_openai_client.with_options.assert_not_called()
assert client.client is mock_openai_client


def test_init_with_default_header() -> None:
default_headers = {"X-Unit-Test": "test-guid"}
mock_openai_client = _make_mock_openai_client()
Expand Down
Loading