openai[patch]: warn at construction when async-callable api_key is used

An async callable openai_api_key means the sync client cannot be
built, so sync entry points (invoke/stream) will fail at runtime
with a ValueError. Surface this constraint immediately at model
construction time via a UserWarning so callers don't first discover
it on a runtime invocation.
This commit is contained in:
LangSmith Issues Agent
2026-05-26 19:00:16 +00:00
parent 7bb4130c7d
commit 554533cc40
2 changed files with 43 additions and 0 deletions

View File

@@ -14,6 +14,7 @@
from __future__ import annotations
import base64
import inspect
import json
import logging
import os
@@ -1184,6 +1185,20 @@ class BaseChatOpenAI(BaseChatModel):
sync_api_key_value, async_api_key_value = _resolve_sync_and_async_api_keys(
self.openai_api_key
)
# Surface the sync/async constraint at construction time so callers
# don't first discover it on a runtime invocation. An async-callable
# api_key means the sync client cannot be built, and sync entry
# points (invoke/stream) will fail with a clearer ValueError later.
if inspect.iscoroutinefunction(self.openai_api_key):
warnings.warn(
"An async callable was provided for `openai_api_key`. "
"The sync client will not be available; only async entry "
"points (`ainvoke`, `astream`, ...) will work. To use sync "
"methods, provide a string or a sync callable for the API "
"key.",
UserWarning,
stacklevel=2,
)
client_params: dict = {
"organization": self.openai_organization,

View File

@@ -3803,3 +3803,31 @@ def test_defer_loading_in_responses_api_payload() -> None:
assert weather_tool["defer_loading"] is True
assert weather_tool["type"] == "function"
assert {"type": "tool_search"} in result["tools"]
def test_async_callable_api_key_warns_at_construction() -> None:
"""An async callable api_key should warn at construction time."""
async def async_api_key() -> str:
return "sk-test"
with pytest.warns(UserWarning, match="async callable"):
llm = ChatOpenAI(model="gpt-4o-mini", openai_api_key=async_api_key)
assert llm.client is None
assert llm.root_client is None
assert llm.async_client is not None
with pytest.raises(ValueError, match="Sync client is not available"):
llm.invoke("hello")
def test_sync_callable_api_key_does_not_warn() -> None:
"""A sync callable api_key must not trigger the async-callable warning."""
def sync_api_key() -> str:
return "sk-test"
with warnings.catch_warnings():
warnings.simplefilter("error", UserWarning)
ChatOpenAI(model="gpt-4o-mini", openai_api_key=sync_api_key)