mirror of
https://github.com/wassname/openrouter-python-sdk-retry-errors.git
synced 2026-08-02 12:50:48 +08:00
This commit is contained in:
@@ -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}"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user