"""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