This commit is contained in:
David Alberto Adler
2025-09-07 20:40:53 +01:00
parent 0fc7236673
commit da48e8c4ea
166 changed files with 1689 additions and 4514 deletions
+15 -3
View File
@@ -3,6 +3,7 @@
from typing import TYPE_CHECKING
from importlib import import_module
import builtins
import sys
if TYPE_CHECKING:
from .annotations import get_discriminator
@@ -162,6 +163,18 @@ _dynamic_imports: dict[str, str] = {
}
def dynamic_import(modname, retries=3):
for attempt in range(retries):
try:
return import_module(modname, __package__)
except KeyError:
# Clear any half-initialized module and retry
sys.modules.pop(modname, None)
if attempt == retries - 1:
break
raise KeyError(f"Failed to import module '{modname}' after {retries} attempts")
def __getattr__(attr_name: str) -> object:
module_name = _dynamic_imports.get(attr_name)
if module_name is None:
@@ -170,9 +183,8 @@ def __getattr__(attr_name: str) -> object:
)
try:
module = import_module(module_name, __package__)
result = getattr(module, attr_name)
return result
module = dynamic_import(module_name)
return getattr(module, attr_name)
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
+10
View File
@@ -17,6 +17,9 @@ T = TypeVar("T")
class EventStream(Generic[T]):
# Holds a reference to the SDK client to avoid it being garbage collected
# and cause termination of the underlying httpx client.
client_ref: Optional[object]
response: httpx.Response
generator: Generator[T, None, None]
@@ -25,9 +28,11 @@ class EventStream(Generic[T]):
response: httpx.Response,
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
client_ref: Optional[object] = None,
):
self.response = response
self.generator = stream_events(response, decoder, sentinel)
self.client_ref = client_ref
def __iter__(self):
return self
@@ -43,6 +48,9 @@ class EventStream(Generic[T]):
class EventStreamAsync(Generic[T]):
# Holds a reference to the SDK client to avoid it being garbage collected
# and cause termination of the underlying httpx client.
client_ref: Optional[object]
response: httpx.Response
generator: AsyncGenerator[T, None]
@@ -51,9 +59,11 @@ class EventStreamAsync(Generic[T]):
response: httpx.Response,
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
client_ref: Optional[object] = None,
):
self.response = response
self.generator = stream_events_async(response, decoder, sentinel)
self.client_ref = client_ref
def __aiter__(self):
return self
+2 -2
View File
@@ -64,8 +64,8 @@ def get_security_from_env(security: Any, security_class: Any) -> Optional[BaseMo
security_dict: Any = {}
if os.getenv("OPENROUTER_BEARER_AUTH"):
security_dict["bearer_auth"] = os.getenv("OPENROUTER_BEARER_AUTH")
if os.getenv("OPENROUTER_API_KEY"):
security_dict["api_key"] = os.getenv("OPENROUTER_API_KEY")
return security_class(**security_dict) if security_dict else None