Files
openrouter-python-sdk-retry…/src/openrouter/sdk.py
T
2025-09-07 21:39:50 +01:00

188 lines
6.8 KiB
Python

"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from .basesdk import BaseSDK
from .httpclient import AsyncHttpClient, ClientOwner, HttpClient, close_clients
from .sdkconfiguration import SDKConfiguration
from .utils.logger import Logger, get_default_logger
from .utils.retries import RetryConfig
import httpx
import importlib
from openrouter import models, utils
from openrouter._hooks import SDKHooks
from openrouter.types import OptionalNullable, UNSET
import sys
from typing import Any, Callable, Dict, List, Optional, TYPE_CHECKING, Union, cast
import weakref
if TYPE_CHECKING:
from openrouter.chat import Chat
class OpenRouter(BaseSDK):
r"""OpenRouter Chat Completions API: OpenAI-compatible Chat Completions API with additional OpenRouter features
https://openrouter.ai/docs - OpenRouter Documentation
"""
chat: "Chat"
r"""Chat completion operations"""
_sub_sdk_map = {
"chat": ("openrouter.chat", "Chat"),
}
def __init__(
self,
api_key: Optional[Union[Optional[str], Callable[[], Optional[str]]]] = None,
provider_url: Optional[str] = None,
server_idx: Optional[int] = None,
server_url: Optional[str] = None,
url_params: Optional[Dict[str, str]] = None,
client: Optional[HttpClient] = None,
async_client: Optional[AsyncHttpClient] = None,
retry_config: OptionalNullable[RetryConfig] = UNSET,
timeout_ms: Optional[int] = None,
debug_logger: Optional[Logger] = None,
) -> None:
r"""Instantiates the SDK configuring it with the provided parameters.
:param api_key: The api_key required for authentication
:param provider_url: Allows setting the provider_url variable for url substitution
:param server_idx: The index of the server to use for all methods
:param server_url: The server URL to use for all methods
:param url_params: Parameters to optionally template the server URL with
:param client: The HTTP client to use for all synchronous methods
:param async_client: The Async HTTP client to use for all asynchronous methods
:param retry_config: The retry configuration to use for all supported methods
:param timeout_ms: Optional request timeout applied to each operation in milliseconds
"""
client_supplied = True
if client is None:
client = httpx.Client()
client_supplied = False
assert issubclass(
type(client), HttpClient
), "The provided client must implement the HttpClient protocol."
async_client_supplied = True
if async_client is None:
async_client = httpx.AsyncClient()
async_client_supplied = False
if debug_logger is None:
debug_logger = get_default_logger()
assert issubclass(
type(async_client), AsyncHttpClient
), "The provided async_client must implement the AsyncHttpClient protocol."
security: Any = None
if callable(api_key):
# pylint: disable=unnecessary-lambda-assignment
security = lambda: models.Security(api_key=api_key())
else:
security = models.Security(api_key=api_key)
if server_url is not None:
if url_params is not None:
server_url = utils.template_url(server_url, url_params)
server_defaults: List[Dict[str, str]] = [
{
"provider_url": provider_url or "openrouter.ai",
},
]
BaseSDK.__init__(
self,
SDKConfiguration(
client=client,
client_supplied=client_supplied,
async_client=async_client,
async_client_supplied=async_client_supplied,
security=security,
server_url=server_url,
server_idx=server_idx,
server_defaults=server_defaults,
retry_config=retry_config,
timeout_ms=timeout_ms,
debug_logger=debug_logger,
),
parent_ref=self,
)
hooks = SDKHooks()
# pylint: disable=protected-access
self.sdk_configuration.__dict__["_hooks"] = hooks
self.sdk_configuration = hooks.sdk_init(self.sdk_configuration)
weakref.finalize(
self,
close_clients,
cast(ClientOwner, self.sdk_configuration),
self.sdk_configuration.client,
self.sdk_configuration.client_supplied,
self.sdk_configuration.async_client,
self.sdk_configuration.async_client_supplied,
)
def dynamic_import(self, modname, retries=3):
for attempt in range(retries):
try:
return importlib.import_module(modname)
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__(self, name: str):
if name in self._sub_sdk_map:
module_path, class_name = self._sub_sdk_map[name]
try:
module = self.dynamic_import(module_path)
klass = getattr(module, class_name)
instance = klass(self.sdk_configuration, parent_ref=self)
setattr(self, name, instance)
return instance
except ImportError as e:
raise AttributeError(
f"Failed to import module {module_path} for attribute {name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to find class {class_name} in module {module_path} for attribute {name}: {e}"
) from e
raise AttributeError(
f"'{type(self).__name__}' object has no attribute '{name}'"
)
def __dir__(self):
default_attrs = list(super().__dir__())
lazy_attrs = list(self._sub_sdk_map.keys())
return sorted(list(set(default_attrs + lazy_attrs)))
def __enter__(self):
return self
async def __aenter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if (
self.sdk_configuration.client is not None
and not self.sdk_configuration.client_supplied
):
self.sdk_configuration.client.close()
self.sdk_configuration.client = None
async def __aexit__(self, exc_type, exc_val, exc_tb):
if (
self.sdk_configuration.async_client is not None
and not self.sdk_configuration.async_client_supplied
):
await self.sdk_configuration.async_client.aclose()
self.sdk_configuration.async_client = None