first commit

This commit is contained in:
Sheldon Vaughn
2025-08-22 10:31:13 -05:00
commit ab530a160e
284 changed files with 18581 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from ._version import (
__title__,
__version__,
__openapi_doc_version__,
__gen_version__,
__user_agent__,
)
from .sdk import *
from .sdkconfiguration import *
VERSION: str = __version__
OPENAPI_DOC_VERSION = __openapi_doc_version__
SPEAKEASY_GENERATOR_VERSION = __gen_version__
USER_AGENT = __user_agent__
+5
View File
@@ -0,0 +1,5 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from .sdkhooks import *
from .types import *
from .registration import *
+13
View File
@@ -0,0 +1,13 @@
from .types import Hooks
# This file is only ever generated once on the first generation and then is free to be modified.
# Any hooks you wish to add should be registered in the init_hooks function. Feel free to define them
# in this file or in separate files in the hooks folder.
def init_hooks(hooks: Hooks):
# pylint: disable=unused-argument
"""Add hooks by calling hooks.register{sdk_init/before_request/after_success/after_error}Hook
with an instance of a hook that implements that specific Hook interface
Hooks are registered per SDK instance, and are valid for the lifetime of the SDK instance"""
+76
View File
@@ -0,0 +1,76 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import httpx
from .types import (
SDKInitHook,
BeforeRequestContext,
BeforeRequestHook,
AfterSuccessContext,
AfterSuccessHook,
AfterErrorContext,
AfterErrorHook,
Hooks,
)
from .registration import init_hooks
from typing import List, Optional, Tuple
from openrouter.sdkconfiguration import SDKConfiguration
class SDKHooks(Hooks):
def __init__(self) -> None:
self.sdk_init_hooks: List[SDKInitHook] = []
self.before_request_hooks: List[BeforeRequestHook] = []
self.after_success_hooks: List[AfterSuccessHook] = []
self.after_error_hooks: List[AfterErrorHook] = []
init_hooks(self)
def register_sdk_init_hook(self, hook: SDKInitHook) -> None:
self.sdk_init_hooks.append(hook)
def register_before_request_hook(self, hook: BeforeRequestHook) -> None:
self.before_request_hooks.append(hook)
def register_after_success_hook(self, hook: AfterSuccessHook) -> None:
self.after_success_hooks.append(hook)
def register_after_error_hook(self, hook: AfterErrorHook) -> None:
self.after_error_hooks.append(hook)
def sdk_init(self, config: SDKConfiguration) -> SDKConfiguration:
for hook in self.sdk_init_hooks:
config = hook.sdk_init(config)
return config
def before_request(
self, hook_ctx: BeforeRequestContext, request: httpx.Request
) -> httpx.Request:
for hook in self.before_request_hooks:
out = hook.before_request(hook_ctx, request)
if isinstance(out, Exception):
raise out
request = out
return request
def after_success(
self, hook_ctx: AfterSuccessContext, response: httpx.Response
) -> httpx.Response:
for hook in self.after_success_hooks:
out = hook.after_success(hook_ctx, response)
if isinstance(out, Exception):
raise out
response = out
return response
def after_error(
self,
hook_ctx: AfterErrorContext,
response: Optional[httpx.Response],
error: Optional[Exception],
) -> Tuple[Optional[httpx.Response], Optional[Exception]]:
for hook in self.after_error_hooks:
result = hook.after_error(hook_ctx, response, error)
if isinstance(result, Exception):
raise result
response, error = result
return response, error
+112
View File
@@ -0,0 +1,112 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from abc import ABC, abstractmethod
import httpx
from openrouter.sdkconfiguration import SDKConfiguration
from typing import Any, Callable, List, Optional, Tuple, Union
class HookContext:
config: SDKConfiguration
base_url: str
operation_id: str
oauth2_scopes: Optional[List[str]] = None
security_source: Optional[Union[Any, Callable[[], Any]]] = None
def __init__(
self,
config: SDKConfiguration,
base_url: str,
operation_id: str,
oauth2_scopes: Optional[List[str]],
security_source: Optional[Union[Any, Callable[[], Any]]],
):
self.config = config
self.base_url = base_url
self.operation_id = operation_id
self.oauth2_scopes = oauth2_scopes
self.security_source = security_source
class BeforeRequestContext(HookContext):
def __init__(self, hook_ctx: HookContext):
super().__init__(
hook_ctx.config,
hook_ctx.base_url,
hook_ctx.operation_id,
hook_ctx.oauth2_scopes,
hook_ctx.security_source,
)
class AfterSuccessContext(HookContext):
def __init__(self, hook_ctx: HookContext):
super().__init__(
hook_ctx.config,
hook_ctx.base_url,
hook_ctx.operation_id,
hook_ctx.oauth2_scopes,
hook_ctx.security_source,
)
class AfterErrorContext(HookContext):
def __init__(self, hook_ctx: HookContext):
super().__init__(
hook_ctx.config,
hook_ctx.base_url,
hook_ctx.operation_id,
hook_ctx.oauth2_scopes,
hook_ctx.security_source,
)
class SDKInitHook(ABC):
@abstractmethod
def sdk_init(self, config: SDKConfiguration) -> SDKConfiguration:
pass
class BeforeRequestHook(ABC):
@abstractmethod
def before_request(
self, hook_ctx: BeforeRequestContext, request: httpx.Request
) -> Union[httpx.Request, Exception]:
pass
class AfterSuccessHook(ABC):
@abstractmethod
def after_success(
self, hook_ctx: AfterSuccessContext, response: httpx.Response
) -> Union[httpx.Response, Exception]:
pass
class AfterErrorHook(ABC):
@abstractmethod
def after_error(
self,
hook_ctx: AfterErrorContext,
response: Optional[httpx.Response],
error: Optional[Exception],
) -> Union[Tuple[Optional[httpx.Response], Optional[Exception]], Exception]:
pass
class Hooks(ABC):
@abstractmethod
def register_sdk_init_hook(self, hook: SDKInitHook):
pass
@abstractmethod
def register_before_request_hook(self, hook: BeforeRequestHook):
pass
@abstractmethod
def register_after_success_hook(self, hook: AfterSuccessHook):
pass
@abstractmethod
def register_after_error_hook(self, hook: AfterErrorHook):
pass
+15
View File
@@ -0,0 +1,15 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import importlib.metadata
__title__: str = "openrouter"
__version__: str = "0.1.2"
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.687.1"
__user_agent__: str = "speakeasy-sdk/python 0.1.2 2.687.1 1.0.0 openrouter"
try:
if __package__ is not None:
__version__ = importlib.metadata.version(__package__)
except importlib.metadata.PackageNotFoundError:
pass
+358
View File
@@ -0,0 +1,358 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from .sdkconfiguration import SDKConfiguration
import httpx
from openrouter import errors, models, utils
from openrouter._hooks import (
AfterErrorContext,
AfterSuccessContext,
BeforeRequestContext,
)
from openrouter.utils import RetryConfig, SerializedRequestBody, get_body_content
from typing import Callable, List, Mapping, Optional, Tuple
from urllib.parse import parse_qs, urlparse
class BaseSDK:
sdk_configuration: SDKConfiguration
def __init__(self, sdk_config: SDKConfiguration) -> None:
self.sdk_configuration = sdk_config
def _get_url(self, base_url, url_variables):
sdk_url, sdk_variables = self.sdk_configuration.get_server_details()
if base_url is None:
base_url = sdk_url
if url_variables is None:
url_variables = sdk_variables
return utils.template_url(base_url, url_variables)
def _build_request_async(
self,
method,
path,
base_url,
url_variables,
request,
request_body_required,
request_has_path_params,
request_has_query_params,
user_agent_header,
accept_header_value,
_globals=None,
security=None,
timeout_ms: Optional[int] = None,
get_serialized_body: Optional[
Callable[[], Optional[SerializedRequestBody]]
] = None,
url_override: Optional[str] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> httpx.Request:
client = self.sdk_configuration.async_client
return self._build_request_with_client(
client,
method,
path,
base_url,
url_variables,
request,
request_body_required,
request_has_path_params,
request_has_query_params,
user_agent_header,
accept_header_value,
_globals,
security,
timeout_ms,
get_serialized_body,
url_override,
http_headers,
)
def _build_request(
self,
method,
path,
base_url,
url_variables,
request,
request_body_required,
request_has_path_params,
request_has_query_params,
user_agent_header,
accept_header_value,
_globals=None,
security=None,
timeout_ms: Optional[int] = None,
get_serialized_body: Optional[
Callable[[], Optional[SerializedRequestBody]]
] = None,
url_override: Optional[str] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> httpx.Request:
client = self.sdk_configuration.client
return self._build_request_with_client(
client,
method,
path,
base_url,
url_variables,
request,
request_body_required,
request_has_path_params,
request_has_query_params,
user_agent_header,
accept_header_value,
_globals,
security,
timeout_ms,
get_serialized_body,
url_override,
http_headers,
)
def _build_request_with_client(
self,
client,
method,
path,
base_url,
url_variables,
request,
request_body_required,
request_has_path_params,
request_has_query_params,
user_agent_header,
accept_header_value,
_globals=None,
security=None,
timeout_ms: Optional[int] = None,
get_serialized_body: Optional[
Callable[[], Optional[SerializedRequestBody]]
] = None,
url_override: Optional[str] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> httpx.Request:
query_params = {}
url = url_override
if url is None:
url = utils.generate_url(
self._get_url(base_url, url_variables),
path,
request if request_has_path_params else None,
_globals if request_has_path_params else None,
)
query_params = utils.get_query_params(
request if request_has_query_params else None,
_globals if request_has_query_params else None,
)
else:
# Pick up the query parameter from the override so they can be
# preserved when building the request later on (necessary as of
# httpx 0.28).
parsed_override = urlparse(str(url_override))
query_params = parse_qs(parsed_override.query, keep_blank_values=True)
headers = utils.get_headers(request, _globals)
headers["Accept"] = accept_header_value
headers[user_agent_header] = self.sdk_configuration.user_agent
if security is not None:
if callable(security):
security = security()
security = utils.get_security_from_env(security, models.Security)
if security is not None:
security_headers, security_query_params = utils.get_security(security)
headers = {**headers, **security_headers}
query_params = {**query_params, **security_query_params}
serialized_request_body = SerializedRequestBody()
if get_serialized_body is not None:
rb = get_serialized_body()
if request_body_required and rb is None:
raise ValueError("request body is required")
if rb is not None:
serialized_request_body = rb
if (
serialized_request_body.media_type is not None
and serialized_request_body.media_type
not in (
"multipart/form-data",
"multipart/mixed",
)
):
headers["content-type"] = serialized_request_body.media_type
if http_headers is not None:
for header, value in http_headers.items():
headers[header] = value
timeout = timeout_ms / 1000 if timeout_ms is not None else None
return client.build_request(
method,
url,
params=query_params,
content=serialized_request_body.content,
data=serialized_request_body.data,
files=serialized_request_body.files,
headers=headers,
timeout=timeout,
)
def do_request(
self,
hook_ctx,
request,
error_status_codes,
stream=False,
retry_config: Optional[Tuple[RetryConfig, List[str]]] = None,
) -> httpx.Response:
client = self.sdk_configuration.client
logger = self.sdk_configuration.debug_logger
hooks = self.sdk_configuration.__dict__["_hooks"]
def do():
http_res = None
try:
req = hooks.before_request(BeforeRequestContext(hook_ctx), request)
logger.debug(
"Request:\nMethod: %s\nURL: %s\nHeaders: %s\nBody: %s",
req.method,
req.url,
req.headers,
get_body_content(req),
)
if client is None:
raise ValueError("client is required")
http_res = client.send(req, stream=stream)
except Exception as e:
_, e = hooks.after_error(AfterErrorContext(hook_ctx), None, e)
if e is not None:
logger.debug("Request Exception", exc_info=True)
raise e
if http_res is None:
logger.debug("Raising no response SDK error")
raise errors.NoResponseError("No response received")
logger.debug(
"Response:\nStatus Code: %s\nURL: %s\nHeaders: %s\nBody: %s",
http_res.status_code,
http_res.url,
http_res.headers,
"<streaming response>" if stream else http_res.text,
)
if utils.match_status_codes(error_status_codes, http_res.status_code):
result, err = hooks.after_error(
AfterErrorContext(hook_ctx), http_res, None
)
if err is not None:
logger.debug("Request Exception", exc_info=True)
raise err
if result is not None:
http_res = result
else:
logger.debug("Raising unexpected SDK error")
raise errors.OpenRouterDefaultError(
"Unexpected error occurred", http_res
)
return http_res
if retry_config is not None:
http_res = utils.retry(do, utils.Retries(retry_config[0], retry_config[1]))
else:
http_res = do()
if not utils.match_status_codes(error_status_codes, http_res.status_code):
http_res = hooks.after_success(AfterSuccessContext(hook_ctx), http_res)
return http_res
async def do_request_async(
self,
hook_ctx,
request,
error_status_codes,
stream=False,
retry_config: Optional[Tuple[RetryConfig, List[str]]] = None,
) -> httpx.Response:
client = self.sdk_configuration.async_client
logger = self.sdk_configuration.debug_logger
hooks = self.sdk_configuration.__dict__["_hooks"]
async def do():
http_res = None
try:
req = hooks.before_request(BeforeRequestContext(hook_ctx), request)
logger.debug(
"Request:\nMethod: %s\nURL: %s\nHeaders: %s\nBody: %s",
req.method,
req.url,
req.headers,
get_body_content(req),
)
if client is None:
raise ValueError("client is required")
http_res = await client.send(req, stream=stream)
except Exception as e:
_, e = hooks.after_error(AfterErrorContext(hook_ctx), None, e)
if e is not None:
logger.debug("Request Exception", exc_info=True)
raise e
if http_res is None:
logger.debug("Raising no response SDK error")
raise errors.NoResponseError("No response received")
logger.debug(
"Response:\nStatus Code: %s\nURL: %s\nHeaders: %s\nBody: %s",
http_res.status_code,
http_res.url,
http_res.headers,
"<streaming response>" if stream else http_res.text,
)
if utils.match_status_codes(error_status_codes, http_res.status_code):
result, err = hooks.after_error(
AfterErrorContext(hook_ctx), http_res, None
)
if err is not None:
logger.debug("Request Exception", exc_info=True)
raise err
if result is not None:
http_res = result
else:
logger.debug("Raising unexpected SDK error")
raise errors.OpenRouterDefaultError(
"Unexpected error occurred", http_res
)
return http_res
if retry_config is not None:
http_res = await utils.retry_async(
do, utils.Retries(retry_config[0], retry_config[1])
)
else:
http_res = await do()
if not utils.match_status_codes(error_status_codes, http_res.status_code):
http_res = hooks.after_success(AfterSuccessContext(hook_ctx), http_res)
return http_res
+987
View File
@@ -0,0 +1,987 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from .basesdk import BaseSDK
from openrouter import errors, models, utils
from openrouter._hooks import HookContext
from openrouter.types import OptionalNullable, UNSET
from openrouter.utils import eventstreaming, get_security_from_env
from openrouter.utils.unmarshal_json_response import unmarshal_json_response
from typing import Any, Dict, List, Mapping, Optional, Union
class Chat(BaseSDK):
r"""Chat completion operations"""
def complete(
self,
*,
messages: Union[
List[models.ChatCompletionMessageParam],
List[models.ChatCompletionMessageParamTypedDict],
],
model: Optional[str] = None,
frequency_penalty: OptionalNullable[float] = UNSET,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
top_logprobs: OptionalNullable[float] = UNSET,
max_completion_tokens: OptionalNullable[float] = UNSET,
max_tokens: OptionalNullable[float] = UNSET,
metadata: Optional[Dict[str, str]] = None,
presence_penalty: OptionalNullable[float] = UNSET,
reasoning: OptionalNullable[
Union[
models.ChatCompletionCreateParamsReasoning,
models.ChatCompletionCreateParamsReasoningTypedDict,
]
] = UNSET,
response_format: Optional[
Union[
models.ChatCompletionCreateParamsResponseFormatUnion,
models.ChatCompletionCreateParamsResponseFormatUnionTypedDict,
]
] = None,
seed: OptionalNullable[int] = UNSET,
stop: OptionalNullable[
Union[
models.ChatCompletionCreateParamsStop,
models.ChatCompletionCreateParamsStopTypedDict,
]
] = UNSET,
stream: OptionalNullable[bool] = False,
stream_options: OptionalNullable[
Union[
models.ChatCompletionCreateParamsStreamOptions,
models.ChatCompletionCreateParamsStreamOptionsTypedDict,
]
] = UNSET,
temperature: OptionalNullable[float] = 1,
tool_choice: Optional[
Union[
models.ChatCompletionToolChoiceOption,
models.ChatCompletionToolChoiceOptionTypedDict,
]
] = None,
tools: Optional[
Union[
List[models.ChatCompletionTool],
List[models.ChatCompletionToolTypedDict],
]
] = None,
top_p: OptionalNullable[float] = 1,
user: Optional[str] = None,
models_llm: OptionalNullable[List[str]] = UNSET,
reasoning_effort: OptionalNullable[
models.ChatCompletionCreateParamsReasoningEffort
] = UNSET,
provider: OptionalNullable[
Union[
models.ChatCompletionCreateParamsProvider,
models.ChatCompletionCreateParamsProviderTypedDict,
]
] = UNSET,
plugins: Optional[
Union[
List[models.ChatCompletionCreateParamsPluginUnion],
List[models.ChatCompletionCreateParamsPluginUnionTypedDict],
]
] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> models.ChatCompletion:
r"""Create a chat completion
Creates a model response for the given chat conversation. Supports both streaming and non-streaming modes.
:param messages: List of messages for the conversation
:param model: Model to use for completion
:param frequency_penalty: Frequency penalty (-2.0 to 2.0)
:param logit_bias: Token logit bias adjustments
:param logprobs: Return log probabilities
:param top_logprobs: Number of top log probabilities to return (0-20)
:param max_completion_tokens: Maximum tokens in completion
:param max_tokens: Maximum tokens (deprecated, use max_completion_tokens)
:param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
:param presence_penalty: Presence penalty (-2.0 to 2.0)
:param reasoning: Reasoning configuration
:param response_format: Response format configuration
:param seed: Random seed for deterministic outputs
:param stop: Stop sequences (up to 4)
:param stream: Enable streaming response
:param stream_options:
:param temperature: Sampling temperature (0-2)
:param tool_choice: Tool choice configuration
:param tools: Available tools for function calling
:param top_p: Nucleus sampling parameter (0-1)
:param user: Unique user identifier
:param models_llm: Order of models to fallback to for this request
:param reasoning_effort: Reasoning effort
:param provider: When multiple model providers are available, optionally indicate your routing preference.
:param plugins: Plugins you want to enable for this request, including their settings.
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param http_headers: Additional headers to set or replace on requests.
"""
base_url = None
url_variables = None
if timeout_ms is None:
timeout_ms = self.sdk_configuration.timeout_ms
if server_url is not None:
base_url = server_url
else:
base_url = self._get_url(base_url, url_variables)
request = models.ChatCompletionCreateParams(
messages=utils.get_pydantic_model(
messages, List[models.ChatCompletionMessageParam]
),
model=model,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
logprobs=logprobs,
top_logprobs=top_logprobs,
max_completion_tokens=max_completion_tokens,
max_tokens=max_tokens,
metadata=metadata,
presence_penalty=presence_penalty,
reasoning=utils.get_pydantic_model(
reasoning, OptionalNullable[models.ChatCompletionCreateParamsReasoning]
),
response_format=utils.get_pydantic_model(
response_format,
Optional[models.ChatCompletionCreateParamsResponseFormatUnion],
),
seed=seed,
stop=stop,
stream=stream,
stream_options=utils.get_pydantic_model(
stream_options,
OptionalNullable[models.ChatCompletionCreateParamsStreamOptions],
),
temperature=temperature,
tool_choice=utils.get_pydantic_model(
tool_choice, Optional[models.ChatCompletionToolChoiceOption]
),
tools=utils.get_pydantic_model(
tools, Optional[List[models.ChatCompletionTool]]
),
top_p=top_p,
user=user,
models_llm=models_llm,
reasoning_effort=reasoning_effort,
provider=utils.get_pydantic_model(
provider, OptionalNullable[models.ChatCompletionCreateParamsProvider]
),
plugins=utils.get_pydantic_model(
plugins, Optional[List[models.ChatCompletionCreateParamsPluginUnion]]
),
)
req = self._build_request(
method="POST",
path="/chat/completions",
base_url=base_url,
url_variables=url_variables,
request=request,
request_body_required=True,
request_has_path_params=False,
request_has_query_params=True,
user_agent_header="user-agent",
accept_header_value="application/json",
http_headers=http_headers,
security=self.sdk_configuration.security,
get_serialized_body=lambda: utils.serialize_request_body(
request, False, False, "json", models.ChatCompletionCreateParams
),
timeout_ms=timeout_ms,
)
if retries == UNSET:
if self.sdk_configuration.retry_config is not UNSET:
retries = self.sdk_configuration.retry_config
retry_config = None
if isinstance(retries, utils.RetryConfig):
retry_config = (retries, ["429", "500", "502", "503", "504"])
http_res = self.do_request(
hook_ctx=HookContext(
config=self.sdk_configuration,
base_url=base_url or "",
operation_id="createChatCompletion",
oauth2_scopes=[],
security_source=get_security_from_env(
self.sdk_configuration.security, models.Security
),
),
request=req,
error_status_codes=["400", "401", "429", "4XX", "500", "5XX"],
retry_config=retry_config,
)
response_data: Any = None
if utils.match_response(http_res, "200", "application/json"):
return unmarshal_json_response(models.ChatCompletion, http_res)
if utils.match_response(http_res, ["400", "401", "429"], "application/json"):
response_data = unmarshal_json_response(
errors.ChatCompletionErrorData, http_res
)
raise errors.ChatCompletionError(response_data, http_res)
if utils.match_response(http_res, "500", "application/json"):
response_data = unmarshal_json_response(
errors.ChatCompletionErrorData, http_res
)
raise errors.ChatCompletionError(response_data, http_res)
if utils.match_response(http_res, "4XX", "*"):
http_res_text = utils.stream_to_text(http_res)
raise errors.OpenRouterDefaultError(
"API error occurred", http_res, http_res_text
)
if utils.match_response(http_res, "5XX", "*"):
http_res_text = utils.stream_to_text(http_res)
raise errors.OpenRouterDefaultError(
"API error occurred", http_res, http_res_text
)
raise errors.OpenRouterDefaultError("Unexpected response received", http_res)
async def complete_async(
self,
*,
messages: Union[
List[models.ChatCompletionMessageParam],
List[models.ChatCompletionMessageParamTypedDict],
],
model: Optional[str] = None,
frequency_penalty: OptionalNullable[float] = UNSET,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
top_logprobs: OptionalNullable[float] = UNSET,
max_completion_tokens: OptionalNullable[float] = UNSET,
max_tokens: OptionalNullable[float] = UNSET,
metadata: Optional[Dict[str, str]] = None,
presence_penalty: OptionalNullable[float] = UNSET,
reasoning: OptionalNullable[
Union[
models.ChatCompletionCreateParamsReasoning,
models.ChatCompletionCreateParamsReasoningTypedDict,
]
] = UNSET,
response_format: Optional[
Union[
models.ChatCompletionCreateParamsResponseFormatUnion,
models.ChatCompletionCreateParamsResponseFormatUnionTypedDict,
]
] = None,
seed: OptionalNullable[int] = UNSET,
stop: OptionalNullable[
Union[
models.ChatCompletionCreateParamsStop,
models.ChatCompletionCreateParamsStopTypedDict,
]
] = UNSET,
stream: OptionalNullable[bool] = False,
stream_options: OptionalNullable[
Union[
models.ChatCompletionCreateParamsStreamOptions,
models.ChatCompletionCreateParamsStreamOptionsTypedDict,
]
] = UNSET,
temperature: OptionalNullable[float] = 1,
tool_choice: Optional[
Union[
models.ChatCompletionToolChoiceOption,
models.ChatCompletionToolChoiceOptionTypedDict,
]
] = None,
tools: Optional[
Union[
List[models.ChatCompletionTool],
List[models.ChatCompletionToolTypedDict],
]
] = None,
top_p: OptionalNullable[float] = 1,
user: Optional[str] = None,
models_llm: OptionalNullable[List[str]] = UNSET,
reasoning_effort: OptionalNullable[
models.ChatCompletionCreateParamsReasoningEffort
] = UNSET,
provider: OptionalNullable[
Union[
models.ChatCompletionCreateParamsProvider,
models.ChatCompletionCreateParamsProviderTypedDict,
]
] = UNSET,
plugins: Optional[
Union[
List[models.ChatCompletionCreateParamsPluginUnion],
List[models.ChatCompletionCreateParamsPluginUnionTypedDict],
]
] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> models.ChatCompletion:
r"""Create a chat completion
Creates a model response for the given chat conversation. Supports both streaming and non-streaming modes.
:param messages: List of messages for the conversation
:param model: Model to use for completion
:param frequency_penalty: Frequency penalty (-2.0 to 2.0)
:param logit_bias: Token logit bias adjustments
:param logprobs: Return log probabilities
:param top_logprobs: Number of top log probabilities to return (0-20)
:param max_completion_tokens: Maximum tokens in completion
:param max_tokens: Maximum tokens (deprecated, use max_completion_tokens)
:param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
:param presence_penalty: Presence penalty (-2.0 to 2.0)
:param reasoning: Reasoning configuration
:param response_format: Response format configuration
:param seed: Random seed for deterministic outputs
:param stop: Stop sequences (up to 4)
:param stream: Enable streaming response
:param stream_options:
:param temperature: Sampling temperature (0-2)
:param tool_choice: Tool choice configuration
:param tools: Available tools for function calling
:param top_p: Nucleus sampling parameter (0-1)
:param user: Unique user identifier
:param models_llm: Order of models to fallback to for this request
:param reasoning_effort: Reasoning effort
:param provider: When multiple model providers are available, optionally indicate your routing preference.
:param plugins: Plugins you want to enable for this request, including their settings.
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param http_headers: Additional headers to set or replace on requests.
"""
base_url = None
url_variables = None
if timeout_ms is None:
timeout_ms = self.sdk_configuration.timeout_ms
if server_url is not None:
base_url = server_url
else:
base_url = self._get_url(base_url, url_variables)
request = models.ChatCompletionCreateParams(
messages=utils.get_pydantic_model(
messages, List[models.ChatCompletionMessageParam]
),
model=model,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
logprobs=logprobs,
top_logprobs=top_logprobs,
max_completion_tokens=max_completion_tokens,
max_tokens=max_tokens,
metadata=metadata,
presence_penalty=presence_penalty,
reasoning=utils.get_pydantic_model(
reasoning, OptionalNullable[models.ChatCompletionCreateParamsReasoning]
),
response_format=utils.get_pydantic_model(
response_format,
Optional[models.ChatCompletionCreateParamsResponseFormatUnion],
),
seed=seed,
stop=stop,
stream=stream,
stream_options=utils.get_pydantic_model(
stream_options,
OptionalNullable[models.ChatCompletionCreateParamsStreamOptions],
),
temperature=temperature,
tool_choice=utils.get_pydantic_model(
tool_choice, Optional[models.ChatCompletionToolChoiceOption]
),
tools=utils.get_pydantic_model(
tools, Optional[List[models.ChatCompletionTool]]
),
top_p=top_p,
user=user,
models_llm=models_llm,
reasoning_effort=reasoning_effort,
provider=utils.get_pydantic_model(
provider, OptionalNullable[models.ChatCompletionCreateParamsProvider]
),
plugins=utils.get_pydantic_model(
plugins, Optional[List[models.ChatCompletionCreateParamsPluginUnion]]
),
)
req = self._build_request_async(
method="POST",
path="/chat/completions",
base_url=base_url,
url_variables=url_variables,
request=request,
request_body_required=True,
request_has_path_params=False,
request_has_query_params=True,
user_agent_header="user-agent",
accept_header_value="application/json",
http_headers=http_headers,
security=self.sdk_configuration.security,
get_serialized_body=lambda: utils.serialize_request_body(
request, False, False, "json", models.ChatCompletionCreateParams
),
timeout_ms=timeout_ms,
)
if retries == UNSET:
if self.sdk_configuration.retry_config is not UNSET:
retries = self.sdk_configuration.retry_config
retry_config = None
if isinstance(retries, utils.RetryConfig):
retry_config = (retries, ["429", "500", "502", "503", "504"])
http_res = await self.do_request_async(
hook_ctx=HookContext(
config=self.sdk_configuration,
base_url=base_url or "",
operation_id="createChatCompletion",
oauth2_scopes=[],
security_source=get_security_from_env(
self.sdk_configuration.security, models.Security
),
),
request=req,
error_status_codes=["400", "401", "429", "4XX", "500", "5XX"],
retry_config=retry_config,
)
response_data: Any = None
if utils.match_response(http_res, "200", "application/json"):
return unmarshal_json_response(models.ChatCompletion, http_res)
if utils.match_response(http_res, ["400", "401", "429"], "application/json"):
response_data = unmarshal_json_response(
errors.ChatCompletionErrorData, http_res
)
raise errors.ChatCompletionError(response_data, http_res)
if utils.match_response(http_res, "500", "application/json"):
response_data = unmarshal_json_response(
errors.ChatCompletionErrorData, http_res
)
raise errors.ChatCompletionError(response_data, http_res)
if utils.match_response(http_res, "4XX", "*"):
http_res_text = await utils.stream_to_text_async(http_res)
raise errors.OpenRouterDefaultError(
"API error occurred", http_res, http_res_text
)
if utils.match_response(http_res, "5XX", "*"):
http_res_text = await utils.stream_to_text_async(http_res)
raise errors.OpenRouterDefaultError(
"API error occurred", http_res, http_res_text
)
raise errors.OpenRouterDefaultError("Unexpected response received", http_res)
def complete_stream(
self,
*,
messages: Union[
List[models.ChatCompletionMessageParam],
List[models.ChatCompletionMessageParamTypedDict],
],
model: Optional[str] = None,
frequency_penalty: OptionalNullable[float] = UNSET,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
top_logprobs: OptionalNullable[float] = UNSET,
max_completion_tokens: OptionalNullable[float] = UNSET,
max_tokens: OptionalNullable[float] = UNSET,
metadata: Optional[Dict[str, str]] = None,
presence_penalty: OptionalNullable[float] = UNSET,
reasoning: OptionalNullable[
Union[
models.ChatStreamCompletionCreateParamsReasoning,
models.ChatStreamCompletionCreateParamsReasoningTypedDict,
]
] = UNSET,
response_format: Optional[
Union[
models.ChatStreamCompletionCreateParamsResponseFormatUnion,
models.ChatStreamCompletionCreateParamsResponseFormatUnionTypedDict,
]
] = None,
seed: OptionalNullable[int] = UNSET,
stop: OptionalNullable[
Union[
models.ChatStreamCompletionCreateParamsStop,
models.ChatStreamCompletionCreateParamsStopTypedDict,
]
] = UNSET,
stream: Optional[bool] = True,
stream_options: OptionalNullable[
Union[
models.ChatStreamCompletionCreateParamsStreamOptions,
models.ChatStreamCompletionCreateParamsStreamOptionsTypedDict,
]
] = UNSET,
temperature: OptionalNullable[float] = 1,
tool_choice: Optional[
Union[
models.ChatCompletionToolChoiceOption,
models.ChatCompletionToolChoiceOptionTypedDict,
]
] = None,
tools: Optional[
Union[
List[models.ChatCompletionTool],
List[models.ChatCompletionToolTypedDict],
]
] = None,
top_p: OptionalNullable[float] = 1,
user: Optional[str] = None,
models_llm: OptionalNullable[List[str]] = UNSET,
reasoning_effort: OptionalNullable[
models.ChatStreamCompletionCreateParamsReasoningEffort
] = UNSET,
provider: OptionalNullable[
Union[
models.ChatStreamCompletionCreateParamsProvider,
models.ChatStreamCompletionCreateParamsProviderTypedDict,
]
] = UNSET,
plugins: Optional[
Union[
List[models.ChatStreamCompletionCreateParamsPluginUnion],
List[models.ChatStreamCompletionCreateParamsPluginUnionTypedDict],
]
] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> eventstreaming.EventStream[models.StreamChatCompletionResponseBody]:
r"""Create a chat completion
Creates a model response for the given chat conversation. Supports both streaming and non-streaming modes.
:param messages: List of messages for the conversation
:param model: Model to use for completion
:param frequency_penalty: Frequency penalty (-2.0 to 2.0)
:param logit_bias: Token logit bias adjustments
:param logprobs: Return log probabilities
:param top_logprobs: Number of top log probabilities to return (0-20)
:param max_completion_tokens: Maximum tokens in completion
:param max_tokens: Maximum tokens (deprecated, use max_completion_tokens)
:param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
:param presence_penalty: Presence penalty (-2.0 to 2.0)
:param reasoning: Reasoning configuration
:param response_format: Response format configuration
:param seed: Random seed for deterministic outputs
:param stop: Stop sequences (up to 4)
:param stream: Enable streaming response
:param stream_options:
:param temperature: Sampling temperature (0-2)
:param tool_choice: Tool choice configuration
:param tools: Available tools for function calling
:param top_p: Nucleus sampling parameter (0-1)
:param user: Unique user identifier
:param models_llm: Order of models to fallback to for this request
:param reasoning_effort: Reasoning effort
:param provider: When multiple model providers are available, optionally indicate your routing preference.
:param plugins: Plugins you want to enable for this request, including their settings.
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param http_headers: Additional headers to set or replace on requests.
"""
base_url = None
url_variables = None
if timeout_ms is None:
timeout_ms = self.sdk_configuration.timeout_ms
if server_url is not None:
base_url = server_url
else:
base_url = self._get_url(base_url, url_variables)
request = models.ChatStreamCompletionCreateParams(
messages=utils.get_pydantic_model(
messages, List[models.ChatCompletionMessageParam]
),
model=model,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
logprobs=logprobs,
top_logprobs=top_logprobs,
max_completion_tokens=max_completion_tokens,
max_tokens=max_tokens,
metadata=metadata,
presence_penalty=presence_penalty,
reasoning=utils.get_pydantic_model(
reasoning,
OptionalNullable[models.ChatStreamCompletionCreateParamsReasoning],
),
response_format=utils.get_pydantic_model(
response_format,
Optional[models.ChatStreamCompletionCreateParamsResponseFormatUnion],
),
seed=seed,
stop=stop,
stream=stream,
stream_options=utils.get_pydantic_model(
stream_options,
OptionalNullable[models.ChatStreamCompletionCreateParamsStreamOptions],
),
temperature=temperature,
tool_choice=utils.get_pydantic_model(
tool_choice, Optional[models.ChatCompletionToolChoiceOption]
),
tools=utils.get_pydantic_model(
tools, Optional[List[models.ChatCompletionTool]]
),
top_p=top_p,
user=user,
models_llm=models_llm,
reasoning_effort=reasoning_effort,
provider=utils.get_pydantic_model(
provider,
OptionalNullable[models.ChatStreamCompletionCreateParamsProvider],
),
plugins=utils.get_pydantic_model(
plugins,
Optional[List[models.ChatStreamCompletionCreateParamsPluginUnion]],
),
)
req = self._build_request(
method="POST",
path="/chat/completions#stream",
base_url=base_url,
url_variables=url_variables,
request=request,
request_body_required=True,
request_has_path_params=False,
request_has_query_params=True,
user_agent_header="user-agent",
accept_header_value="text/event-stream",
http_headers=http_headers,
security=self.sdk_configuration.security,
get_serialized_body=lambda: utils.serialize_request_body(
request, False, False, "json", models.ChatStreamCompletionCreateParams
),
timeout_ms=timeout_ms,
)
if retries == UNSET:
if self.sdk_configuration.retry_config is not UNSET:
retries = self.sdk_configuration.retry_config
retry_config = None
if isinstance(retries, utils.RetryConfig):
retry_config = (retries, ["429", "500", "502", "503", "504"])
http_res = self.do_request(
hook_ctx=HookContext(
config=self.sdk_configuration,
base_url=base_url or "",
operation_id="streamChatCompletion",
oauth2_scopes=[],
security_source=get_security_from_env(
self.sdk_configuration.security, models.Security
),
),
request=req,
error_status_codes=["400", "401", "429", "4XX", "500", "5XX"],
stream=True,
retry_config=retry_config,
)
response_data: Any = None
if utils.match_response(http_res, "200", "text/event-stream"):
return eventstreaming.EventStream(
http_res,
lambda raw: utils.unmarshal_json(
raw, models.StreamChatCompletionResponseBody
),
sentinel="[DONE]",
)
if utils.match_response(http_res, ["400", "401", "429"], "application/json"):
http_res_text = utils.stream_to_text(http_res)
response_data = unmarshal_json_response(
errors.ChatCompletionErrorData, http_res, http_res_text
)
raise errors.ChatCompletionError(response_data, http_res, http_res_text)
if utils.match_response(http_res, "500", "application/json"):
http_res_text = utils.stream_to_text(http_res)
response_data = unmarshal_json_response(
errors.ChatCompletionErrorData, http_res, http_res_text
)
raise errors.ChatCompletionError(response_data, http_res, http_res_text)
if utils.match_response(http_res, "4XX", "*"):
http_res_text = utils.stream_to_text(http_res)
raise errors.OpenRouterDefaultError(
"API error occurred", http_res, http_res_text
)
if utils.match_response(http_res, "5XX", "*"):
http_res_text = utils.stream_to_text(http_res)
raise errors.OpenRouterDefaultError(
"API error occurred", http_res, http_res_text
)
http_res_text = utils.stream_to_text(http_res)
raise errors.OpenRouterDefaultError(
"Unexpected response received", http_res, http_res_text
)
async def complete_stream_async(
self,
*,
messages: Union[
List[models.ChatCompletionMessageParam],
List[models.ChatCompletionMessageParamTypedDict],
],
model: Optional[str] = None,
frequency_penalty: OptionalNullable[float] = UNSET,
logit_bias: OptionalNullable[Dict[str, float]] = UNSET,
logprobs: OptionalNullable[bool] = UNSET,
top_logprobs: OptionalNullable[float] = UNSET,
max_completion_tokens: OptionalNullable[float] = UNSET,
max_tokens: OptionalNullable[float] = UNSET,
metadata: Optional[Dict[str, str]] = None,
presence_penalty: OptionalNullable[float] = UNSET,
reasoning: OptionalNullable[
Union[
models.ChatStreamCompletionCreateParamsReasoning,
models.ChatStreamCompletionCreateParamsReasoningTypedDict,
]
] = UNSET,
response_format: Optional[
Union[
models.ChatStreamCompletionCreateParamsResponseFormatUnion,
models.ChatStreamCompletionCreateParamsResponseFormatUnionTypedDict,
]
] = None,
seed: OptionalNullable[int] = UNSET,
stop: OptionalNullable[
Union[
models.ChatStreamCompletionCreateParamsStop,
models.ChatStreamCompletionCreateParamsStopTypedDict,
]
] = UNSET,
stream: Optional[bool] = True,
stream_options: OptionalNullable[
Union[
models.ChatStreamCompletionCreateParamsStreamOptions,
models.ChatStreamCompletionCreateParamsStreamOptionsTypedDict,
]
] = UNSET,
temperature: OptionalNullable[float] = 1,
tool_choice: Optional[
Union[
models.ChatCompletionToolChoiceOption,
models.ChatCompletionToolChoiceOptionTypedDict,
]
] = None,
tools: Optional[
Union[
List[models.ChatCompletionTool],
List[models.ChatCompletionToolTypedDict],
]
] = None,
top_p: OptionalNullable[float] = 1,
user: Optional[str] = None,
models_llm: OptionalNullable[List[str]] = UNSET,
reasoning_effort: OptionalNullable[
models.ChatStreamCompletionCreateParamsReasoningEffort
] = UNSET,
provider: OptionalNullable[
Union[
models.ChatStreamCompletionCreateParamsProvider,
models.ChatStreamCompletionCreateParamsProviderTypedDict,
]
] = UNSET,
plugins: Optional[
Union[
List[models.ChatStreamCompletionCreateParamsPluginUnion],
List[models.ChatStreamCompletionCreateParamsPluginUnionTypedDict],
]
] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> eventstreaming.EventStreamAsync[models.StreamChatCompletionResponseBody]:
r"""Create a chat completion
Creates a model response for the given chat conversation. Supports both streaming and non-streaming modes.
:param messages: List of messages for the conversation
:param model: Model to use for completion
:param frequency_penalty: Frequency penalty (-2.0 to 2.0)
:param logit_bias: Token logit bias adjustments
:param logprobs: Return log probabilities
:param top_logprobs: Number of top log probabilities to return (0-20)
:param max_completion_tokens: Maximum tokens in completion
:param max_tokens: Maximum tokens (deprecated, use max_completion_tokens)
:param metadata: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values)
:param presence_penalty: Presence penalty (-2.0 to 2.0)
:param reasoning: Reasoning configuration
:param response_format: Response format configuration
:param seed: Random seed for deterministic outputs
:param stop: Stop sequences (up to 4)
:param stream: Enable streaming response
:param stream_options:
:param temperature: Sampling temperature (0-2)
:param tool_choice: Tool choice configuration
:param tools: Available tools for function calling
:param top_p: Nucleus sampling parameter (0-1)
:param user: Unique user identifier
:param models_llm: Order of models to fallback to for this request
:param reasoning_effort: Reasoning effort
:param provider: When multiple model providers are available, optionally indicate your routing preference.
:param plugins: Plugins you want to enable for this request, including their settings.
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param http_headers: Additional headers to set or replace on requests.
"""
base_url = None
url_variables = None
if timeout_ms is None:
timeout_ms = self.sdk_configuration.timeout_ms
if server_url is not None:
base_url = server_url
else:
base_url = self._get_url(base_url, url_variables)
request = models.ChatStreamCompletionCreateParams(
messages=utils.get_pydantic_model(
messages, List[models.ChatCompletionMessageParam]
),
model=model,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
logprobs=logprobs,
top_logprobs=top_logprobs,
max_completion_tokens=max_completion_tokens,
max_tokens=max_tokens,
metadata=metadata,
presence_penalty=presence_penalty,
reasoning=utils.get_pydantic_model(
reasoning,
OptionalNullable[models.ChatStreamCompletionCreateParamsReasoning],
),
response_format=utils.get_pydantic_model(
response_format,
Optional[models.ChatStreamCompletionCreateParamsResponseFormatUnion],
),
seed=seed,
stop=stop,
stream=stream,
stream_options=utils.get_pydantic_model(
stream_options,
OptionalNullable[models.ChatStreamCompletionCreateParamsStreamOptions],
),
temperature=temperature,
tool_choice=utils.get_pydantic_model(
tool_choice, Optional[models.ChatCompletionToolChoiceOption]
),
tools=utils.get_pydantic_model(
tools, Optional[List[models.ChatCompletionTool]]
),
top_p=top_p,
user=user,
models_llm=models_llm,
reasoning_effort=reasoning_effort,
provider=utils.get_pydantic_model(
provider,
OptionalNullable[models.ChatStreamCompletionCreateParamsProvider],
),
plugins=utils.get_pydantic_model(
plugins,
Optional[List[models.ChatStreamCompletionCreateParamsPluginUnion]],
),
)
req = self._build_request_async(
method="POST",
path="/chat/completions#stream",
base_url=base_url,
url_variables=url_variables,
request=request,
request_body_required=True,
request_has_path_params=False,
request_has_query_params=True,
user_agent_header="user-agent",
accept_header_value="text/event-stream",
http_headers=http_headers,
security=self.sdk_configuration.security,
get_serialized_body=lambda: utils.serialize_request_body(
request, False, False, "json", models.ChatStreamCompletionCreateParams
),
timeout_ms=timeout_ms,
)
if retries == UNSET:
if self.sdk_configuration.retry_config is not UNSET:
retries = self.sdk_configuration.retry_config
retry_config = None
if isinstance(retries, utils.RetryConfig):
retry_config = (retries, ["429", "500", "502", "503", "504"])
http_res = await self.do_request_async(
hook_ctx=HookContext(
config=self.sdk_configuration,
base_url=base_url or "",
operation_id="streamChatCompletion",
oauth2_scopes=[],
security_source=get_security_from_env(
self.sdk_configuration.security, models.Security
),
),
request=req,
error_status_codes=["400", "401", "429", "4XX", "500", "5XX"],
stream=True,
retry_config=retry_config,
)
response_data: Any = None
if utils.match_response(http_res, "200", "text/event-stream"):
return eventstreaming.EventStreamAsync(
http_res,
lambda raw: utils.unmarshal_json(
raw, models.StreamChatCompletionResponseBody
),
sentinel="[DONE]",
)
if utils.match_response(http_res, ["400", "401", "429"], "application/json"):
http_res_text = await utils.stream_to_text_async(http_res)
response_data = unmarshal_json_response(
errors.ChatCompletionErrorData, http_res, http_res_text
)
raise errors.ChatCompletionError(response_data, http_res, http_res_text)
if utils.match_response(http_res, "500", "application/json"):
http_res_text = await utils.stream_to_text_async(http_res)
response_data = unmarshal_json_response(
errors.ChatCompletionErrorData, http_res, http_res_text
)
raise errors.ChatCompletionError(response_data, http_res, http_res_text)
if utils.match_response(http_res, "4XX", "*"):
http_res_text = await utils.stream_to_text_async(http_res)
raise errors.OpenRouterDefaultError(
"API error occurred", http_res, http_res_text
)
if utils.match_response(http_res, "5XX", "*"):
http_res_text = await utils.stream_to_text_async(http_res)
raise errors.OpenRouterDefaultError(
"API error occurred", http_res, http_res_text
)
http_res_text = await utils.stream_to_text_async(http_res)
raise errors.OpenRouterDefaultError(
"Unexpected response received", http_res, http_res_text
)
+56
View File
@@ -0,0 +1,56 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import TYPE_CHECKING
from importlib import import_module
import builtins
if TYPE_CHECKING:
from .chatcompletionerror import ChatCompletionError, ChatCompletionErrorData
from .no_response_error import NoResponseError
from .openrouterdefaulterror import OpenRouterDefaultError
from .openroutererror import OpenRouterError
from .responsevalidationerror import ResponseValidationError
__all__ = [
"ChatCompletionError",
"ChatCompletionErrorData",
"NoResponseError",
"OpenRouterDefaultError",
"OpenRouterError",
"ResponseValidationError",
]
_dynamic_imports: dict[str, str] = {
"ChatCompletionError": ".chatcompletionerror",
"ChatCompletionErrorData": ".chatcompletionerror",
"NoResponseError": ".no_response_error",
"OpenRouterDefaultError": ".openrouterdefaulterror",
"OpenRouterError": ".openroutererror",
"ResponseValidationError": ".responsevalidationerror",
}
def __getattr__(attr_name: str) -> object:
module_name = _dynamic_imports.get(attr_name)
if module_name is None:
raise AttributeError(
f"No {attr_name} found in _dynamic_imports for module name -> {__name__} "
)
try:
module = import_module(module_name, __package__)
result = getattr(module, attr_name)
return result
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to get {attr_name} from {module_name}: {e}"
) from e
def __dir__():
lazy_attrs = builtins.list(_dynamic_imports.keys())
return builtins.sorted(lazy_attrs)
@@ -0,0 +1,30 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
import httpx
from openrouter.errors import OpenRouterError
from openrouter.models import chatcompletionerror as models_chatcompletionerror
from openrouter.types import BaseModel
from typing import Optional
class ChatCompletionErrorData(BaseModel):
error: models_chatcompletionerror.Error
r"""Error object structure"""
class ChatCompletionError(OpenRouterError):
r"""Chat completion error response"""
data: ChatCompletionErrorData
def __init__(
self,
data: ChatCompletionErrorData,
raw_response: httpx.Response,
body: Optional[str] = None,
):
fallback = body or raw_response.text
message = str(data.error.message) or fallback
super().__init__(message, raw_response, body)
self.data = data
@@ -0,0 +1,13 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
class NoResponseError(Exception):
"""Error raised when no HTTP response is received from the server."""
message: str
def __init__(self, message: str = "No response received"):
self.message = message
super().__init__(message)
def __str__(self):
return self.message
@@ -0,0 +1,38 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import httpx
from typing import Optional
from openrouter.errors import OpenRouterError
MAX_MESSAGE_LEN = 10_000
class OpenRouterDefaultError(OpenRouterError):
"""The fallback error class if no more specific error class is matched."""
def __init__(
self, message: str, raw_response: httpx.Response, body: Optional[str] = None
):
body_display = body or raw_response.text or '""'
if message:
message += ": "
message += f"Status {raw_response.status_code}"
headers = raw_response.headers
content_type = headers.get("content-type", '""')
if content_type != "application/json":
if " " in content_type:
content_type = f'"{content_type}"'
message += f" Content-Type {content_type}"
if len(body_display) > MAX_MESSAGE_LEN:
truncated = body_display[:MAX_MESSAGE_LEN]
remaining = len(body_display) - MAX_MESSAGE_LEN
body_display = f"{truncated}...and {remaining} more chars"
message += f". Body: {body_display}"
message = message.strip()
super().__init__(message, raw_response, body)
+26
View File
@@ -0,0 +1,26 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import httpx
from typing import Optional
class OpenRouterError(Exception):
"""The base class for all HTTP error responses."""
message: str
status_code: int
body: str
headers: httpx.Headers
raw_response: httpx.Response
def __init__(
self, message: str, raw_response: httpx.Response, body: Optional[str] = None
):
self.message = message
self.status_code = raw_response.status_code
self.body = body if body is not None else raw_response.text
self.headers = raw_response.headers
self.raw_response = raw_response
def __str__(self):
return self.message
@@ -0,0 +1,25 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import httpx
from typing import Optional
from openrouter.errors import OpenRouterError
class ResponseValidationError(OpenRouterError):
"""Error raised when there is a type mismatch between the response data and the expected Pydantic model."""
def __init__(
self,
message: str,
raw_response: httpx.Response,
cause: Exception,
body: Optional[str] = None,
):
message = f"{message}: {cause}"
super().__init__(message, raw_response, body)
@property
def cause(self):
"""Normally the Pydantic ValidationError"""
return self.__cause__
+126
View File
@@ -0,0 +1,126 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
# pyright: reportReturnType = false
import asyncio
from typing_extensions import Protocol, runtime_checkable
import httpx
from typing import Any, Optional, Union
@runtime_checkable
class HttpClient(Protocol):
def send(
self,
request: httpx.Request,
*,
stream: bool = False,
auth: Union[
httpx._types.AuthTypes, httpx._client.UseClientDefault, None
] = httpx.USE_CLIENT_DEFAULT,
follow_redirects: Union[
bool, httpx._client.UseClientDefault
] = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
pass
def build_request(
self,
method: str,
url: httpx._types.URLTypes,
*,
content: Optional[httpx._types.RequestContent] = None,
data: Optional[httpx._types.RequestData] = None,
files: Optional[httpx._types.RequestFiles] = None,
json: Optional[Any] = None,
params: Optional[httpx._types.QueryParamTypes] = None,
headers: Optional[httpx._types.HeaderTypes] = None,
cookies: Optional[httpx._types.CookieTypes] = None,
timeout: Union[
httpx._types.TimeoutTypes, httpx._client.UseClientDefault
] = httpx.USE_CLIENT_DEFAULT,
extensions: Optional[httpx._types.RequestExtensions] = None,
) -> httpx.Request:
pass
def close(self) -> None:
pass
@runtime_checkable
class AsyncHttpClient(Protocol):
async def send(
self,
request: httpx.Request,
*,
stream: bool = False,
auth: Union[
httpx._types.AuthTypes, httpx._client.UseClientDefault, None
] = httpx.USE_CLIENT_DEFAULT,
follow_redirects: Union[
bool, httpx._client.UseClientDefault
] = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
pass
def build_request(
self,
method: str,
url: httpx._types.URLTypes,
*,
content: Optional[httpx._types.RequestContent] = None,
data: Optional[httpx._types.RequestData] = None,
files: Optional[httpx._types.RequestFiles] = None,
json: Optional[Any] = None,
params: Optional[httpx._types.QueryParamTypes] = None,
headers: Optional[httpx._types.HeaderTypes] = None,
cookies: Optional[httpx._types.CookieTypes] = None,
timeout: Union[
httpx._types.TimeoutTypes, httpx._client.UseClientDefault
] = httpx.USE_CLIENT_DEFAULT,
extensions: Optional[httpx._types.RequestExtensions] = None,
) -> httpx.Request:
pass
async def aclose(self) -> None:
pass
class ClientOwner(Protocol):
client: Union[HttpClient, None]
async_client: Union[AsyncHttpClient, None]
def close_clients(
owner: ClientOwner,
sync_client: Union[HttpClient, None],
sync_client_supplied: bool,
async_client: Union[AsyncHttpClient, None],
async_client_supplied: bool,
) -> None:
"""
A finalizer function that is meant to be used with weakref.finalize to close
httpx clients used by an SDK so that underlying resources can be garbage
collected.
"""
# Unset the client/async_client properties so there are no more references
# to them from the owning SDK instance and they can be reaped.
owner.client = None
owner.async_client = None
if sync_client is not None and not sync_client_supplied:
try:
sync_client.close()
except Exception:
pass
if async_client is not None and not async_client_supplied:
try:
loop = asyncio.get_running_loop()
asyncio.run_coroutine_threadsafe(async_client.aclose(), loop)
except RuntimeError:
try:
asyncio.run(async_client.aclose())
except RuntimeError:
# best effort
pass
+957
View File
@@ -0,0 +1,957 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import TYPE_CHECKING
from importlib import import_module
import builtins
if TYPE_CHECKING:
from .annotationdetail import AnnotationDetail, AnnotationDetailTypedDict
from .chatcompletion import (
ChatCompletion,
ChatCompletionObject,
ChatCompletionTypedDict,
)
from .chatcompletionassistantmessageparam import (
ChatCompletionAssistantMessageParam,
ChatCompletionAssistantMessageParamContent,
ChatCompletionAssistantMessageParamContentTypedDict,
ChatCompletionAssistantMessageParamRole,
ChatCompletionAssistantMessageParamTypedDict,
)
from .chatcompletionchoice import (
ChatCompletionChoice,
ChatCompletionChoiceFinishReason,
ChatCompletionChoiceTypedDict,
)
from .chatcompletionchunk import (
ChatCompletionChunk,
ChatCompletionChunkObject,
ChatCompletionChunkTypedDict,
)
from .chatcompletionchunkchoice import (
ChatCompletionChunkChoice,
ChatCompletionChunkChoiceFinishReason,
ChatCompletionChunkChoiceTypedDict,
)
from .chatcompletionchunkchoicedelta import (
ChatCompletionChunkChoiceDelta,
ChatCompletionChunkChoiceDeltaRole,
ChatCompletionChunkChoiceDeltaTypedDict,
)
from .chatcompletionchunkchoicedeltatoolcall import (
ChatCompletionChunkChoiceDeltaToolCall,
ChatCompletionChunkChoiceDeltaToolCallFunction,
ChatCompletionChunkChoiceDeltaToolCallFunctionTypedDict,
ChatCompletionChunkChoiceDeltaToolCallType,
ChatCompletionChunkChoiceDeltaToolCallTypedDict,
)
from .chatcompletioncontentpart import (
ChatCompletionContentPart,
ChatCompletionContentPartTypedDict,
)
from .chatcompletioncontentpartaudio import (
ChatCompletionContentPartAudio,
ChatCompletionContentPartAudioFormat,
ChatCompletionContentPartAudioType,
ChatCompletionContentPartAudioTypedDict,
InputAudio,
InputAudioTypedDict,
)
from .chatcompletioncontentpartimage import (
ChatCompletionContentPartImage,
ChatCompletionContentPartImageImageURL,
ChatCompletionContentPartImageImageURLTypedDict,
ChatCompletionContentPartImageType,
ChatCompletionContentPartImageTypedDict,
Detail,
)
from .chatcompletioncontentparttext import (
ChatCompletionContentPartText,
ChatCompletionContentPartTextType,
ChatCompletionContentPartTextTypedDict,
)
from .chatcompletioncreateparams import (
ChatCompletionCreateParams,
ChatCompletionCreateParamsAudio,
ChatCompletionCreateParamsAudioTypedDict,
ChatCompletionCreateParamsCompletion,
ChatCompletionCreateParamsCompletionTypedDict,
ChatCompletionCreateParamsDataCollection,
ChatCompletionCreateParamsEffort,
ChatCompletionCreateParamsEngine,
ChatCompletionCreateParamsIDChainOfThought,
ChatCompletionCreateParamsIDFileParser,
ChatCompletionCreateParamsIDModeration,
ChatCompletionCreateParamsIDWeb,
ChatCompletionCreateParamsIgnoreEnum,
ChatCompletionCreateParamsIgnoreUnion,
ChatCompletionCreateParamsIgnoreUnionTypedDict,
ChatCompletionCreateParamsImage,
ChatCompletionCreateParamsImageTypedDict,
ChatCompletionCreateParamsJSONSchema,
ChatCompletionCreateParamsJSONSchemaTypedDict,
ChatCompletionCreateParamsMaxPrice,
ChatCompletionCreateParamsMaxPriceTypedDict,
ChatCompletionCreateParamsOnlyEnum,
ChatCompletionCreateParamsOnlyUnion,
ChatCompletionCreateParamsOnlyUnionTypedDict,
ChatCompletionCreateParamsOrderEnum,
ChatCompletionCreateParamsOrderUnion,
ChatCompletionCreateParamsOrderUnionTypedDict,
ChatCompletionCreateParamsPdf,
ChatCompletionCreateParamsPdfEngine,
ChatCompletionCreateParamsPdfTypedDict,
ChatCompletionCreateParamsPluginChainOfThought,
ChatCompletionCreateParamsPluginChainOfThoughtTypedDict,
ChatCompletionCreateParamsPluginFileParser,
ChatCompletionCreateParamsPluginFileParserTypedDict,
ChatCompletionCreateParamsPluginModeration,
ChatCompletionCreateParamsPluginModerationTypedDict,
ChatCompletionCreateParamsPluginUnion,
ChatCompletionCreateParamsPluginUnionTypedDict,
ChatCompletionCreateParamsPluginWeb,
ChatCompletionCreateParamsPluginWebTypedDict,
ChatCompletionCreateParamsPrompt,
ChatCompletionCreateParamsPromptTypedDict,
ChatCompletionCreateParamsProvider,
ChatCompletionCreateParamsProviderTypedDict,
ChatCompletionCreateParamsQuantization,
ChatCompletionCreateParamsReasoning,
ChatCompletionCreateParamsReasoningEffort,
ChatCompletionCreateParamsReasoningTypedDict,
ChatCompletionCreateParamsRequest,
ChatCompletionCreateParamsRequestTypedDict,
ChatCompletionCreateParamsResponseFormatGrammar,
ChatCompletionCreateParamsResponseFormatGrammarTypedDict,
ChatCompletionCreateParamsResponseFormatJSONObject,
ChatCompletionCreateParamsResponseFormatJSONObjectTypedDict,
ChatCompletionCreateParamsResponseFormatJSONSchema,
ChatCompletionCreateParamsResponseFormatJSONSchemaTypedDict,
ChatCompletionCreateParamsResponseFormatPython,
ChatCompletionCreateParamsResponseFormatPythonTypedDict,
ChatCompletionCreateParamsResponseFormatText,
ChatCompletionCreateParamsResponseFormatTextTypedDict,
ChatCompletionCreateParamsResponseFormatUnion,
ChatCompletionCreateParamsResponseFormatUnionTypedDict,
ChatCompletionCreateParamsSort,
ChatCompletionCreateParamsStop,
ChatCompletionCreateParamsStopTypedDict,
ChatCompletionCreateParamsStreamOptions,
ChatCompletionCreateParamsStreamOptionsTypedDict,
ChatCompletionCreateParamsTypeGrammar,
ChatCompletionCreateParamsTypeJSONObject,
ChatCompletionCreateParamsTypeJSONSchema,
ChatCompletionCreateParamsTypePython,
ChatCompletionCreateParamsTypeText,
ChatCompletionCreateParamsTypedDict,
)
from .chatcompletionerror import Error, ErrorTypedDict
from .chatcompletionmessage import (
ChatCompletionMessage,
ChatCompletionMessageRole,
ChatCompletionMessageTypedDict,
)
from .chatcompletionmessageparam import (
ChatCompletionMessageParam,
ChatCompletionMessageParamTypedDict,
)
from .chatcompletionmessagetoolcall import (
ChatCompletionMessageToolCall,
ChatCompletionMessageToolCallFunction,
ChatCompletionMessageToolCallFunctionTypedDict,
ChatCompletionMessageToolCallType,
ChatCompletionMessageToolCallTypedDict,
)
from .chatcompletionnamedtoolchoice import (
ChatCompletionNamedToolChoice,
ChatCompletionNamedToolChoiceFunction,
ChatCompletionNamedToolChoiceFunctionTypedDict,
ChatCompletionNamedToolChoiceType,
ChatCompletionNamedToolChoiceTypedDict,
)
from .chatcompletionsystemmessageparam import (
ChatCompletionSystemMessageParam,
ChatCompletionSystemMessageParamContent,
ChatCompletionSystemMessageParamContentTypedDict,
ChatCompletionSystemMessageParamRole,
ChatCompletionSystemMessageParamTypedDict,
)
from .chatcompletiontokenlogprob import (
ChatCompletionTokenLogprob,
ChatCompletionTokenLogprobTypedDict,
TopLogprob,
TopLogprobTypedDict,
)
from .chatcompletiontokenlogprobs import (
ChatCompletionTokenLogprobs,
ChatCompletionTokenLogprobsTypedDict,
)
from .chatcompletiontool import (
ChatCompletionTool,
ChatCompletionToolFunction,
ChatCompletionToolFunctionTypedDict,
ChatCompletionToolType,
ChatCompletionToolTypedDict,
Parameters,
ParametersTypedDict,
)
from .chatcompletiontoolchoiceoption import (
ChatCompletionToolChoiceOption,
ChatCompletionToolChoiceOptionAuto,
ChatCompletionToolChoiceOptionNone,
ChatCompletionToolChoiceOptionRequired,
ChatCompletionToolChoiceOptionTypedDict,
)
from .chatcompletiontoolmessageparam import (
ChatCompletionToolMessageParam,
ChatCompletionToolMessageParamContent,
ChatCompletionToolMessageParamContentTypedDict,
ChatCompletionToolMessageParamRole,
ChatCompletionToolMessageParamTypedDict,
)
from .chatcompletionusermessageparam import (
ChatCompletionUserMessageParam,
ChatCompletionUserMessageParamContent,
ChatCompletionUserMessageParamContentTypedDict,
ChatCompletionUserMessageParamRole,
ChatCompletionUserMessageParamTypedDict,
)
from .chatstreamcompletioncreateparams import (
ChatStreamCompletionCreateParams,
ChatStreamCompletionCreateParamsAudio,
ChatStreamCompletionCreateParamsAudioTypedDict,
ChatStreamCompletionCreateParamsCompletion,
ChatStreamCompletionCreateParamsCompletionTypedDict,
ChatStreamCompletionCreateParamsDataCollection,
ChatStreamCompletionCreateParamsEffort,
ChatStreamCompletionCreateParamsEngine,
ChatStreamCompletionCreateParamsIDChainOfThought,
ChatStreamCompletionCreateParamsIDFileParser,
ChatStreamCompletionCreateParamsIDModeration,
ChatStreamCompletionCreateParamsIDWeb,
ChatStreamCompletionCreateParamsIgnoreEnum,
ChatStreamCompletionCreateParamsIgnoreUnion,
ChatStreamCompletionCreateParamsIgnoreUnionTypedDict,
ChatStreamCompletionCreateParamsImage,
ChatStreamCompletionCreateParamsImageTypedDict,
ChatStreamCompletionCreateParamsJSONSchema,
ChatStreamCompletionCreateParamsJSONSchemaTypedDict,
ChatStreamCompletionCreateParamsMaxPrice,
ChatStreamCompletionCreateParamsMaxPriceTypedDict,
ChatStreamCompletionCreateParamsOnlyEnum,
ChatStreamCompletionCreateParamsOnlyUnion,
ChatStreamCompletionCreateParamsOnlyUnionTypedDict,
ChatStreamCompletionCreateParamsOrderEnum,
ChatStreamCompletionCreateParamsOrderUnion,
ChatStreamCompletionCreateParamsOrderUnionTypedDict,
ChatStreamCompletionCreateParamsPdf,
ChatStreamCompletionCreateParamsPdfEngine,
ChatStreamCompletionCreateParamsPdfTypedDict,
ChatStreamCompletionCreateParamsPluginChainOfThought,
ChatStreamCompletionCreateParamsPluginChainOfThoughtTypedDict,
ChatStreamCompletionCreateParamsPluginFileParser,
ChatStreamCompletionCreateParamsPluginFileParserTypedDict,
ChatStreamCompletionCreateParamsPluginModeration,
ChatStreamCompletionCreateParamsPluginModerationTypedDict,
ChatStreamCompletionCreateParamsPluginUnion,
ChatStreamCompletionCreateParamsPluginUnionTypedDict,
ChatStreamCompletionCreateParamsPluginWeb,
ChatStreamCompletionCreateParamsPluginWebTypedDict,
ChatStreamCompletionCreateParamsPrompt,
ChatStreamCompletionCreateParamsPromptTypedDict,
ChatStreamCompletionCreateParamsProvider,
ChatStreamCompletionCreateParamsProviderTypedDict,
ChatStreamCompletionCreateParamsQuantization,
ChatStreamCompletionCreateParamsReasoning,
ChatStreamCompletionCreateParamsReasoningEffort,
ChatStreamCompletionCreateParamsReasoningTypedDict,
ChatStreamCompletionCreateParamsRequest,
ChatStreamCompletionCreateParamsRequestTypedDict,
ChatStreamCompletionCreateParamsResponseFormatGrammar,
ChatStreamCompletionCreateParamsResponseFormatGrammarTypedDict,
ChatStreamCompletionCreateParamsResponseFormatJSONObject,
ChatStreamCompletionCreateParamsResponseFormatJSONObjectTypedDict,
ChatStreamCompletionCreateParamsResponseFormatJSONSchema,
ChatStreamCompletionCreateParamsResponseFormatJSONSchemaTypedDict,
ChatStreamCompletionCreateParamsResponseFormatPython,
ChatStreamCompletionCreateParamsResponseFormatPythonTypedDict,
ChatStreamCompletionCreateParamsResponseFormatText,
ChatStreamCompletionCreateParamsResponseFormatTextTypedDict,
ChatStreamCompletionCreateParamsResponseFormatUnion,
ChatStreamCompletionCreateParamsResponseFormatUnionTypedDict,
ChatStreamCompletionCreateParamsSort,
ChatStreamCompletionCreateParamsStop,
ChatStreamCompletionCreateParamsStopTypedDict,
ChatStreamCompletionCreateParamsStreamOptions,
ChatStreamCompletionCreateParamsStreamOptionsTypedDict,
ChatStreamCompletionCreateParamsTypeGrammar,
ChatStreamCompletionCreateParamsTypeJSONObject,
ChatStreamCompletionCreateParamsTypeJSONSchema,
ChatStreamCompletionCreateParamsTypePython,
ChatStreamCompletionCreateParamsTypeText,
ChatStreamCompletionCreateParamsTypedDict,
)
from .completionusage import (
CompletionTokensDetails,
CompletionTokensDetailsTypedDict,
CompletionUsage,
CompletionUsageTypedDict,
PromptTokensDetails,
PromptTokensDetailsTypedDict,
)
from .fileannotationdetail import (
ContentImageURL,
ContentImageURLTypedDict,
ContentText,
ContentTextTypedDict,
ContentTypeImageURL,
ContentTypeText,
File,
FileAnnotationDetail,
FileAnnotationDetailContentUnion,
FileAnnotationDetailContentUnionTypedDict,
FileAnnotationDetailImageURL,
FileAnnotationDetailImageURLTypedDict,
FileAnnotationDetailTypedDict,
FileTypedDict,
TypeFile,
)
from .reasoningdetail import ReasoningDetail, ReasoningDetailTypedDict
from .reasoningdetailencrypted import (
ReasoningDetailEncrypted,
ReasoningDetailEncryptedFormat,
ReasoningDetailEncryptedType,
ReasoningDetailEncryptedTypedDict,
)
from .reasoningdetailsummary import (
ReasoningDetailSummary,
ReasoningDetailSummaryFormat,
ReasoningDetailSummaryType,
ReasoningDetailSummaryTypedDict,
)
from .reasoningdetailtext import (
ReasoningDetailText,
ReasoningDetailTextFormat,
ReasoningDetailTextType,
ReasoningDetailTextTypedDict,
)
from .responseformatjsonschemaschema import (
ResponseFormatJSONSchemaSchema,
ResponseFormatJSONSchemaSchemaTypedDict,
)
from .security import Security, SecurityTypedDict
from .streamchatcompletionop import (
StreamChatCompletionResponseBody,
StreamChatCompletionResponseBodyTypedDict,
)
from .urlcitationannotationdetail import (
URLCitation,
URLCitationAnnotationDetail,
URLCitationAnnotationDetailType,
URLCitationAnnotationDetailTypedDict,
URLCitationTypedDict,
)
__all__ = [
"AnnotationDetail",
"AnnotationDetailTypedDict",
"ChatCompletion",
"ChatCompletionAssistantMessageParam",
"ChatCompletionAssistantMessageParamContent",
"ChatCompletionAssistantMessageParamContentTypedDict",
"ChatCompletionAssistantMessageParamRole",
"ChatCompletionAssistantMessageParamTypedDict",
"ChatCompletionChoice",
"ChatCompletionChoiceFinishReason",
"ChatCompletionChoiceTypedDict",
"ChatCompletionChunk",
"ChatCompletionChunkChoice",
"ChatCompletionChunkChoiceDelta",
"ChatCompletionChunkChoiceDeltaRole",
"ChatCompletionChunkChoiceDeltaToolCall",
"ChatCompletionChunkChoiceDeltaToolCallFunction",
"ChatCompletionChunkChoiceDeltaToolCallFunctionTypedDict",
"ChatCompletionChunkChoiceDeltaToolCallType",
"ChatCompletionChunkChoiceDeltaToolCallTypedDict",
"ChatCompletionChunkChoiceDeltaTypedDict",
"ChatCompletionChunkChoiceFinishReason",
"ChatCompletionChunkChoiceTypedDict",
"ChatCompletionChunkObject",
"ChatCompletionChunkTypedDict",
"ChatCompletionContentPart",
"ChatCompletionContentPartAudio",
"ChatCompletionContentPartAudioFormat",
"ChatCompletionContentPartAudioType",
"ChatCompletionContentPartAudioTypedDict",
"ChatCompletionContentPartImage",
"ChatCompletionContentPartImageImageURL",
"ChatCompletionContentPartImageImageURLTypedDict",
"ChatCompletionContentPartImageType",
"ChatCompletionContentPartImageTypedDict",
"ChatCompletionContentPartText",
"ChatCompletionContentPartTextType",
"ChatCompletionContentPartTextTypedDict",
"ChatCompletionContentPartTypedDict",
"ChatCompletionCreateParams",
"ChatCompletionCreateParamsAudio",
"ChatCompletionCreateParamsAudioTypedDict",
"ChatCompletionCreateParamsCompletion",
"ChatCompletionCreateParamsCompletionTypedDict",
"ChatCompletionCreateParamsDataCollection",
"ChatCompletionCreateParamsEffort",
"ChatCompletionCreateParamsEngine",
"ChatCompletionCreateParamsIDChainOfThought",
"ChatCompletionCreateParamsIDFileParser",
"ChatCompletionCreateParamsIDModeration",
"ChatCompletionCreateParamsIDWeb",
"ChatCompletionCreateParamsIgnoreEnum",
"ChatCompletionCreateParamsIgnoreUnion",
"ChatCompletionCreateParamsIgnoreUnionTypedDict",
"ChatCompletionCreateParamsImage",
"ChatCompletionCreateParamsImageTypedDict",
"ChatCompletionCreateParamsJSONSchema",
"ChatCompletionCreateParamsJSONSchemaTypedDict",
"ChatCompletionCreateParamsMaxPrice",
"ChatCompletionCreateParamsMaxPriceTypedDict",
"ChatCompletionCreateParamsOnlyEnum",
"ChatCompletionCreateParamsOnlyUnion",
"ChatCompletionCreateParamsOnlyUnionTypedDict",
"ChatCompletionCreateParamsOrderEnum",
"ChatCompletionCreateParamsOrderUnion",
"ChatCompletionCreateParamsOrderUnionTypedDict",
"ChatCompletionCreateParamsPdf",
"ChatCompletionCreateParamsPdfEngine",
"ChatCompletionCreateParamsPdfTypedDict",
"ChatCompletionCreateParamsPluginChainOfThought",
"ChatCompletionCreateParamsPluginChainOfThoughtTypedDict",
"ChatCompletionCreateParamsPluginFileParser",
"ChatCompletionCreateParamsPluginFileParserTypedDict",
"ChatCompletionCreateParamsPluginModeration",
"ChatCompletionCreateParamsPluginModerationTypedDict",
"ChatCompletionCreateParamsPluginUnion",
"ChatCompletionCreateParamsPluginUnionTypedDict",
"ChatCompletionCreateParamsPluginWeb",
"ChatCompletionCreateParamsPluginWebTypedDict",
"ChatCompletionCreateParamsPrompt",
"ChatCompletionCreateParamsPromptTypedDict",
"ChatCompletionCreateParamsProvider",
"ChatCompletionCreateParamsProviderTypedDict",
"ChatCompletionCreateParamsQuantization",
"ChatCompletionCreateParamsReasoning",
"ChatCompletionCreateParamsReasoningEffort",
"ChatCompletionCreateParamsReasoningTypedDict",
"ChatCompletionCreateParamsRequest",
"ChatCompletionCreateParamsRequestTypedDict",
"ChatCompletionCreateParamsResponseFormatGrammar",
"ChatCompletionCreateParamsResponseFormatGrammarTypedDict",
"ChatCompletionCreateParamsResponseFormatJSONObject",
"ChatCompletionCreateParamsResponseFormatJSONObjectTypedDict",
"ChatCompletionCreateParamsResponseFormatJSONSchema",
"ChatCompletionCreateParamsResponseFormatJSONSchemaTypedDict",
"ChatCompletionCreateParamsResponseFormatPython",
"ChatCompletionCreateParamsResponseFormatPythonTypedDict",
"ChatCompletionCreateParamsResponseFormatText",
"ChatCompletionCreateParamsResponseFormatTextTypedDict",
"ChatCompletionCreateParamsResponseFormatUnion",
"ChatCompletionCreateParamsResponseFormatUnionTypedDict",
"ChatCompletionCreateParamsSort",
"ChatCompletionCreateParamsStop",
"ChatCompletionCreateParamsStopTypedDict",
"ChatCompletionCreateParamsStreamOptions",
"ChatCompletionCreateParamsStreamOptionsTypedDict",
"ChatCompletionCreateParamsTypeGrammar",
"ChatCompletionCreateParamsTypeJSONObject",
"ChatCompletionCreateParamsTypeJSONSchema",
"ChatCompletionCreateParamsTypePython",
"ChatCompletionCreateParamsTypeText",
"ChatCompletionCreateParamsTypedDict",
"ChatCompletionMessage",
"ChatCompletionMessageParam",
"ChatCompletionMessageParamTypedDict",
"ChatCompletionMessageRole",
"ChatCompletionMessageToolCall",
"ChatCompletionMessageToolCallFunction",
"ChatCompletionMessageToolCallFunctionTypedDict",
"ChatCompletionMessageToolCallType",
"ChatCompletionMessageToolCallTypedDict",
"ChatCompletionMessageTypedDict",
"ChatCompletionNamedToolChoice",
"ChatCompletionNamedToolChoiceFunction",
"ChatCompletionNamedToolChoiceFunctionTypedDict",
"ChatCompletionNamedToolChoiceType",
"ChatCompletionNamedToolChoiceTypedDict",
"ChatCompletionObject",
"ChatCompletionSystemMessageParam",
"ChatCompletionSystemMessageParamContent",
"ChatCompletionSystemMessageParamContentTypedDict",
"ChatCompletionSystemMessageParamRole",
"ChatCompletionSystemMessageParamTypedDict",
"ChatCompletionTokenLogprob",
"ChatCompletionTokenLogprobTypedDict",
"ChatCompletionTokenLogprobs",
"ChatCompletionTokenLogprobsTypedDict",
"ChatCompletionTool",
"ChatCompletionToolChoiceOption",
"ChatCompletionToolChoiceOptionAuto",
"ChatCompletionToolChoiceOptionNone",
"ChatCompletionToolChoiceOptionRequired",
"ChatCompletionToolChoiceOptionTypedDict",
"ChatCompletionToolFunction",
"ChatCompletionToolFunctionTypedDict",
"ChatCompletionToolMessageParam",
"ChatCompletionToolMessageParamContent",
"ChatCompletionToolMessageParamContentTypedDict",
"ChatCompletionToolMessageParamRole",
"ChatCompletionToolMessageParamTypedDict",
"ChatCompletionToolType",
"ChatCompletionToolTypedDict",
"ChatCompletionTypedDict",
"ChatCompletionUserMessageParam",
"ChatCompletionUserMessageParamContent",
"ChatCompletionUserMessageParamContentTypedDict",
"ChatCompletionUserMessageParamRole",
"ChatCompletionUserMessageParamTypedDict",
"ChatStreamCompletionCreateParams",
"ChatStreamCompletionCreateParamsAudio",
"ChatStreamCompletionCreateParamsAudioTypedDict",
"ChatStreamCompletionCreateParamsCompletion",
"ChatStreamCompletionCreateParamsCompletionTypedDict",
"ChatStreamCompletionCreateParamsDataCollection",
"ChatStreamCompletionCreateParamsEffort",
"ChatStreamCompletionCreateParamsEngine",
"ChatStreamCompletionCreateParamsIDChainOfThought",
"ChatStreamCompletionCreateParamsIDFileParser",
"ChatStreamCompletionCreateParamsIDModeration",
"ChatStreamCompletionCreateParamsIDWeb",
"ChatStreamCompletionCreateParamsIgnoreEnum",
"ChatStreamCompletionCreateParamsIgnoreUnion",
"ChatStreamCompletionCreateParamsIgnoreUnionTypedDict",
"ChatStreamCompletionCreateParamsImage",
"ChatStreamCompletionCreateParamsImageTypedDict",
"ChatStreamCompletionCreateParamsJSONSchema",
"ChatStreamCompletionCreateParamsJSONSchemaTypedDict",
"ChatStreamCompletionCreateParamsMaxPrice",
"ChatStreamCompletionCreateParamsMaxPriceTypedDict",
"ChatStreamCompletionCreateParamsOnlyEnum",
"ChatStreamCompletionCreateParamsOnlyUnion",
"ChatStreamCompletionCreateParamsOnlyUnionTypedDict",
"ChatStreamCompletionCreateParamsOrderEnum",
"ChatStreamCompletionCreateParamsOrderUnion",
"ChatStreamCompletionCreateParamsOrderUnionTypedDict",
"ChatStreamCompletionCreateParamsPdf",
"ChatStreamCompletionCreateParamsPdfEngine",
"ChatStreamCompletionCreateParamsPdfTypedDict",
"ChatStreamCompletionCreateParamsPluginChainOfThought",
"ChatStreamCompletionCreateParamsPluginChainOfThoughtTypedDict",
"ChatStreamCompletionCreateParamsPluginFileParser",
"ChatStreamCompletionCreateParamsPluginFileParserTypedDict",
"ChatStreamCompletionCreateParamsPluginModeration",
"ChatStreamCompletionCreateParamsPluginModerationTypedDict",
"ChatStreamCompletionCreateParamsPluginUnion",
"ChatStreamCompletionCreateParamsPluginUnionTypedDict",
"ChatStreamCompletionCreateParamsPluginWeb",
"ChatStreamCompletionCreateParamsPluginWebTypedDict",
"ChatStreamCompletionCreateParamsPrompt",
"ChatStreamCompletionCreateParamsPromptTypedDict",
"ChatStreamCompletionCreateParamsProvider",
"ChatStreamCompletionCreateParamsProviderTypedDict",
"ChatStreamCompletionCreateParamsQuantization",
"ChatStreamCompletionCreateParamsReasoning",
"ChatStreamCompletionCreateParamsReasoningEffort",
"ChatStreamCompletionCreateParamsReasoningTypedDict",
"ChatStreamCompletionCreateParamsRequest",
"ChatStreamCompletionCreateParamsRequestTypedDict",
"ChatStreamCompletionCreateParamsResponseFormatGrammar",
"ChatStreamCompletionCreateParamsResponseFormatGrammarTypedDict",
"ChatStreamCompletionCreateParamsResponseFormatJSONObject",
"ChatStreamCompletionCreateParamsResponseFormatJSONObjectTypedDict",
"ChatStreamCompletionCreateParamsResponseFormatJSONSchema",
"ChatStreamCompletionCreateParamsResponseFormatJSONSchemaTypedDict",
"ChatStreamCompletionCreateParamsResponseFormatPython",
"ChatStreamCompletionCreateParamsResponseFormatPythonTypedDict",
"ChatStreamCompletionCreateParamsResponseFormatText",
"ChatStreamCompletionCreateParamsResponseFormatTextTypedDict",
"ChatStreamCompletionCreateParamsResponseFormatUnion",
"ChatStreamCompletionCreateParamsResponseFormatUnionTypedDict",
"ChatStreamCompletionCreateParamsSort",
"ChatStreamCompletionCreateParamsStop",
"ChatStreamCompletionCreateParamsStopTypedDict",
"ChatStreamCompletionCreateParamsStreamOptions",
"ChatStreamCompletionCreateParamsStreamOptionsTypedDict",
"ChatStreamCompletionCreateParamsTypeGrammar",
"ChatStreamCompletionCreateParamsTypeJSONObject",
"ChatStreamCompletionCreateParamsTypeJSONSchema",
"ChatStreamCompletionCreateParamsTypePython",
"ChatStreamCompletionCreateParamsTypeText",
"ChatStreamCompletionCreateParamsTypedDict",
"CompletionTokensDetails",
"CompletionTokensDetailsTypedDict",
"CompletionUsage",
"CompletionUsageTypedDict",
"ContentImageURL",
"ContentImageURLTypedDict",
"ContentText",
"ContentTextTypedDict",
"ContentTypeImageURL",
"ContentTypeText",
"Detail",
"Error",
"ErrorTypedDict",
"File",
"FileAnnotationDetail",
"FileAnnotationDetailContentUnion",
"FileAnnotationDetailContentUnionTypedDict",
"FileAnnotationDetailImageURL",
"FileAnnotationDetailImageURLTypedDict",
"FileAnnotationDetailTypedDict",
"FileTypedDict",
"InputAudio",
"InputAudioTypedDict",
"Parameters",
"ParametersTypedDict",
"PromptTokensDetails",
"PromptTokensDetailsTypedDict",
"ReasoningDetail",
"ReasoningDetailEncrypted",
"ReasoningDetailEncryptedFormat",
"ReasoningDetailEncryptedType",
"ReasoningDetailEncryptedTypedDict",
"ReasoningDetailSummary",
"ReasoningDetailSummaryFormat",
"ReasoningDetailSummaryType",
"ReasoningDetailSummaryTypedDict",
"ReasoningDetailText",
"ReasoningDetailTextFormat",
"ReasoningDetailTextType",
"ReasoningDetailTextTypedDict",
"ReasoningDetailTypedDict",
"ResponseFormatJSONSchemaSchema",
"ResponseFormatJSONSchemaSchemaTypedDict",
"Security",
"SecurityTypedDict",
"StreamChatCompletionResponseBody",
"StreamChatCompletionResponseBodyTypedDict",
"TopLogprob",
"TopLogprobTypedDict",
"TypeFile",
"URLCitation",
"URLCitationAnnotationDetail",
"URLCitationAnnotationDetailType",
"URLCitationAnnotationDetailTypedDict",
"URLCitationTypedDict",
]
_dynamic_imports: dict[str, str] = {
"AnnotationDetail": ".annotationdetail",
"AnnotationDetailTypedDict": ".annotationdetail",
"ChatCompletion": ".chatcompletion",
"ChatCompletionObject": ".chatcompletion",
"ChatCompletionTypedDict": ".chatcompletion",
"ChatCompletionAssistantMessageParam": ".chatcompletionassistantmessageparam",
"ChatCompletionAssistantMessageParamContent": ".chatcompletionassistantmessageparam",
"ChatCompletionAssistantMessageParamContentTypedDict": ".chatcompletionassistantmessageparam",
"ChatCompletionAssistantMessageParamRole": ".chatcompletionassistantmessageparam",
"ChatCompletionAssistantMessageParamTypedDict": ".chatcompletionassistantmessageparam",
"ChatCompletionChoice": ".chatcompletionchoice",
"ChatCompletionChoiceFinishReason": ".chatcompletionchoice",
"ChatCompletionChoiceTypedDict": ".chatcompletionchoice",
"ChatCompletionChunk": ".chatcompletionchunk",
"ChatCompletionChunkObject": ".chatcompletionchunk",
"ChatCompletionChunkTypedDict": ".chatcompletionchunk",
"ChatCompletionChunkChoice": ".chatcompletionchunkchoice",
"ChatCompletionChunkChoiceFinishReason": ".chatcompletionchunkchoice",
"ChatCompletionChunkChoiceTypedDict": ".chatcompletionchunkchoice",
"ChatCompletionChunkChoiceDelta": ".chatcompletionchunkchoicedelta",
"ChatCompletionChunkChoiceDeltaRole": ".chatcompletionchunkchoicedelta",
"ChatCompletionChunkChoiceDeltaTypedDict": ".chatcompletionchunkchoicedelta",
"ChatCompletionChunkChoiceDeltaToolCall": ".chatcompletionchunkchoicedeltatoolcall",
"ChatCompletionChunkChoiceDeltaToolCallFunction": ".chatcompletionchunkchoicedeltatoolcall",
"ChatCompletionChunkChoiceDeltaToolCallFunctionTypedDict": ".chatcompletionchunkchoicedeltatoolcall",
"ChatCompletionChunkChoiceDeltaToolCallType": ".chatcompletionchunkchoicedeltatoolcall",
"ChatCompletionChunkChoiceDeltaToolCallTypedDict": ".chatcompletionchunkchoicedeltatoolcall",
"ChatCompletionContentPart": ".chatcompletioncontentpart",
"ChatCompletionContentPartTypedDict": ".chatcompletioncontentpart",
"ChatCompletionContentPartAudio": ".chatcompletioncontentpartaudio",
"ChatCompletionContentPartAudioFormat": ".chatcompletioncontentpartaudio",
"ChatCompletionContentPartAudioType": ".chatcompletioncontentpartaudio",
"ChatCompletionContentPartAudioTypedDict": ".chatcompletioncontentpartaudio",
"InputAudio": ".chatcompletioncontentpartaudio",
"InputAudioTypedDict": ".chatcompletioncontentpartaudio",
"ChatCompletionContentPartImage": ".chatcompletioncontentpartimage",
"ChatCompletionContentPartImageImageURL": ".chatcompletioncontentpartimage",
"ChatCompletionContentPartImageImageURLTypedDict": ".chatcompletioncontentpartimage",
"ChatCompletionContentPartImageType": ".chatcompletioncontentpartimage",
"ChatCompletionContentPartImageTypedDict": ".chatcompletioncontentpartimage",
"Detail": ".chatcompletioncontentpartimage",
"ChatCompletionContentPartText": ".chatcompletioncontentparttext",
"ChatCompletionContentPartTextType": ".chatcompletioncontentparttext",
"ChatCompletionContentPartTextTypedDict": ".chatcompletioncontentparttext",
"ChatCompletionCreateParams": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsAudio": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsAudioTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsCompletion": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsCompletionTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsDataCollection": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsEffort": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsEngine": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsIDChainOfThought": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsIDFileParser": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsIDModeration": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsIDWeb": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsIgnoreEnum": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsIgnoreUnion": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsIgnoreUnionTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsImage": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsImageTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsJSONSchema": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsJSONSchemaTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsMaxPrice": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsMaxPriceTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsOnlyEnum": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsOnlyUnion": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsOnlyUnionTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsOrderEnum": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsOrderUnion": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsOrderUnionTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPdf": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPdfEngine": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPdfTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginChainOfThought": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginChainOfThoughtTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginFileParser": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginFileParserTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginModeration": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginModerationTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginUnion": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginUnionTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginWeb": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPluginWebTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPrompt": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsPromptTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsProvider": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsProviderTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsQuantization": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsReasoning": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsReasoningEffort": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsReasoningTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsRequest": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsRequestTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatGrammar": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatGrammarTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatJSONObject": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatJSONObjectTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatJSONSchema": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatJSONSchemaTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatPython": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatPythonTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatText": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatTextTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatUnion": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsResponseFormatUnionTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsSort": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsStop": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsStopTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsStreamOptions": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsStreamOptionsTypedDict": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsTypeGrammar": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsTypeJSONObject": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsTypeJSONSchema": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsTypePython": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsTypeText": ".chatcompletioncreateparams",
"ChatCompletionCreateParamsTypedDict": ".chatcompletioncreateparams",
"Error": ".chatcompletionerror",
"ErrorTypedDict": ".chatcompletionerror",
"ChatCompletionMessage": ".chatcompletionmessage",
"ChatCompletionMessageRole": ".chatcompletionmessage",
"ChatCompletionMessageTypedDict": ".chatcompletionmessage",
"ChatCompletionMessageParam": ".chatcompletionmessageparam",
"ChatCompletionMessageParamTypedDict": ".chatcompletionmessageparam",
"ChatCompletionMessageToolCall": ".chatcompletionmessagetoolcall",
"ChatCompletionMessageToolCallFunction": ".chatcompletionmessagetoolcall",
"ChatCompletionMessageToolCallFunctionTypedDict": ".chatcompletionmessagetoolcall",
"ChatCompletionMessageToolCallType": ".chatcompletionmessagetoolcall",
"ChatCompletionMessageToolCallTypedDict": ".chatcompletionmessagetoolcall",
"ChatCompletionNamedToolChoice": ".chatcompletionnamedtoolchoice",
"ChatCompletionNamedToolChoiceFunction": ".chatcompletionnamedtoolchoice",
"ChatCompletionNamedToolChoiceFunctionTypedDict": ".chatcompletionnamedtoolchoice",
"ChatCompletionNamedToolChoiceType": ".chatcompletionnamedtoolchoice",
"ChatCompletionNamedToolChoiceTypedDict": ".chatcompletionnamedtoolchoice",
"ChatCompletionSystemMessageParam": ".chatcompletionsystemmessageparam",
"ChatCompletionSystemMessageParamContent": ".chatcompletionsystemmessageparam",
"ChatCompletionSystemMessageParamContentTypedDict": ".chatcompletionsystemmessageparam",
"ChatCompletionSystemMessageParamRole": ".chatcompletionsystemmessageparam",
"ChatCompletionSystemMessageParamTypedDict": ".chatcompletionsystemmessageparam",
"ChatCompletionTokenLogprob": ".chatcompletiontokenlogprob",
"ChatCompletionTokenLogprobTypedDict": ".chatcompletiontokenlogprob",
"TopLogprob": ".chatcompletiontokenlogprob",
"TopLogprobTypedDict": ".chatcompletiontokenlogprob",
"ChatCompletionTokenLogprobs": ".chatcompletiontokenlogprobs",
"ChatCompletionTokenLogprobsTypedDict": ".chatcompletiontokenlogprobs",
"ChatCompletionTool": ".chatcompletiontool",
"ChatCompletionToolFunction": ".chatcompletiontool",
"ChatCompletionToolFunctionTypedDict": ".chatcompletiontool",
"ChatCompletionToolType": ".chatcompletiontool",
"ChatCompletionToolTypedDict": ".chatcompletiontool",
"Parameters": ".chatcompletiontool",
"ParametersTypedDict": ".chatcompletiontool",
"ChatCompletionToolChoiceOption": ".chatcompletiontoolchoiceoption",
"ChatCompletionToolChoiceOptionAuto": ".chatcompletiontoolchoiceoption",
"ChatCompletionToolChoiceOptionNone": ".chatcompletiontoolchoiceoption",
"ChatCompletionToolChoiceOptionRequired": ".chatcompletiontoolchoiceoption",
"ChatCompletionToolChoiceOptionTypedDict": ".chatcompletiontoolchoiceoption",
"ChatCompletionToolMessageParam": ".chatcompletiontoolmessageparam",
"ChatCompletionToolMessageParamContent": ".chatcompletiontoolmessageparam",
"ChatCompletionToolMessageParamContentTypedDict": ".chatcompletiontoolmessageparam",
"ChatCompletionToolMessageParamRole": ".chatcompletiontoolmessageparam",
"ChatCompletionToolMessageParamTypedDict": ".chatcompletiontoolmessageparam",
"ChatCompletionUserMessageParam": ".chatcompletionusermessageparam",
"ChatCompletionUserMessageParamContent": ".chatcompletionusermessageparam",
"ChatCompletionUserMessageParamContentTypedDict": ".chatcompletionusermessageparam",
"ChatCompletionUserMessageParamRole": ".chatcompletionusermessageparam",
"ChatCompletionUserMessageParamTypedDict": ".chatcompletionusermessageparam",
"ChatStreamCompletionCreateParams": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsAudio": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsAudioTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsCompletion": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsCompletionTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsDataCollection": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsEffort": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsEngine": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsIDChainOfThought": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsIDFileParser": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsIDModeration": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsIDWeb": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsIgnoreEnum": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsIgnoreUnion": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsIgnoreUnionTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsImage": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsImageTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsJSONSchema": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsJSONSchemaTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsMaxPrice": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsMaxPriceTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsOnlyEnum": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsOnlyUnion": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsOnlyUnionTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsOrderEnum": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsOrderUnion": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsOrderUnionTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPdf": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPdfEngine": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPdfTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginChainOfThought": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginChainOfThoughtTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginFileParser": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginFileParserTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginModeration": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginModerationTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginUnion": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginUnionTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginWeb": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPluginWebTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPrompt": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsPromptTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsProvider": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsProviderTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsQuantization": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsReasoning": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsReasoningEffort": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsReasoningTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsRequest": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsRequestTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatGrammar": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatGrammarTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatJSONObject": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatJSONObjectTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatJSONSchema": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatJSONSchemaTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatPython": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatPythonTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatText": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatTextTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatUnion": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsResponseFormatUnionTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsSort": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsStop": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsStopTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsStreamOptions": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsStreamOptionsTypedDict": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsTypeGrammar": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsTypeJSONObject": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsTypeJSONSchema": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsTypePython": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsTypeText": ".chatstreamcompletioncreateparams",
"ChatStreamCompletionCreateParamsTypedDict": ".chatstreamcompletioncreateparams",
"CompletionTokensDetails": ".completionusage",
"CompletionTokensDetailsTypedDict": ".completionusage",
"CompletionUsage": ".completionusage",
"CompletionUsageTypedDict": ".completionusage",
"PromptTokensDetails": ".completionusage",
"PromptTokensDetailsTypedDict": ".completionusage",
"ContentImageURL": ".fileannotationdetail",
"ContentImageURLTypedDict": ".fileannotationdetail",
"ContentText": ".fileannotationdetail",
"ContentTextTypedDict": ".fileannotationdetail",
"ContentTypeImageURL": ".fileannotationdetail",
"ContentTypeText": ".fileannotationdetail",
"File": ".fileannotationdetail",
"FileAnnotationDetail": ".fileannotationdetail",
"FileAnnotationDetailContentUnion": ".fileannotationdetail",
"FileAnnotationDetailContentUnionTypedDict": ".fileannotationdetail",
"FileAnnotationDetailImageURL": ".fileannotationdetail",
"FileAnnotationDetailImageURLTypedDict": ".fileannotationdetail",
"FileAnnotationDetailTypedDict": ".fileannotationdetail",
"FileTypedDict": ".fileannotationdetail",
"TypeFile": ".fileannotationdetail",
"ReasoningDetail": ".reasoningdetail",
"ReasoningDetailTypedDict": ".reasoningdetail",
"ReasoningDetailEncrypted": ".reasoningdetailencrypted",
"ReasoningDetailEncryptedFormat": ".reasoningdetailencrypted",
"ReasoningDetailEncryptedType": ".reasoningdetailencrypted",
"ReasoningDetailEncryptedTypedDict": ".reasoningdetailencrypted",
"ReasoningDetailSummary": ".reasoningdetailsummary",
"ReasoningDetailSummaryFormat": ".reasoningdetailsummary",
"ReasoningDetailSummaryType": ".reasoningdetailsummary",
"ReasoningDetailSummaryTypedDict": ".reasoningdetailsummary",
"ReasoningDetailText": ".reasoningdetailtext",
"ReasoningDetailTextFormat": ".reasoningdetailtext",
"ReasoningDetailTextType": ".reasoningdetailtext",
"ReasoningDetailTextTypedDict": ".reasoningdetailtext",
"ResponseFormatJSONSchemaSchema": ".responseformatjsonschemaschema",
"ResponseFormatJSONSchemaSchemaTypedDict": ".responseformatjsonschemaschema",
"Security": ".security",
"SecurityTypedDict": ".security",
"StreamChatCompletionResponseBody": ".streamchatcompletionop",
"StreamChatCompletionResponseBodyTypedDict": ".streamchatcompletionop",
"URLCitation": ".urlcitationannotationdetail",
"URLCitationAnnotationDetail": ".urlcitationannotationdetail",
"URLCitationAnnotationDetailType": ".urlcitationannotationdetail",
"URLCitationAnnotationDetailTypedDict": ".urlcitationannotationdetail",
"URLCitationTypedDict": ".urlcitationannotationdetail",
}
def __getattr__(attr_name: str) -> object:
module_name = _dynamic_imports.get(attr_name)
if module_name is None:
raise AttributeError(
f"No {attr_name} found in _dynamic_imports for module name -> {__name__} "
)
try:
module = import_module(module_name, __package__)
result = getattr(module, attr_name)
return result
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to get {attr_name} from {module_name}: {e}"
) from e
def __dir__():
lazy_attrs = builtins.list(_dynamic_imports.keys())
return builtins.sorted(lazy_attrs)
+29
View File
@@ -0,0 +1,29 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .fileannotationdetail import FileAnnotationDetail, FileAnnotationDetailTypedDict
from .urlcitationannotationdetail import (
URLCitationAnnotationDetail,
URLCitationAnnotationDetailTypedDict,
)
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from typing import Union
from typing_extensions import Annotated, TypeAliasType
AnnotationDetailTypedDict = TypeAliasType(
"AnnotationDetailTypedDict",
Union[FileAnnotationDetailTypedDict, URLCitationAnnotationDetailTypedDict],
)
r"""Annotation information"""
AnnotationDetail = Annotated[
Union[
Annotated[FileAnnotationDetail, Tag("file")],
Annotated[URLCitationAnnotationDetail, Tag("url_citation")],
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
]
r"""Annotation information"""
+92
View File
@@ -0,0 +1,92 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletionchoice import ChatCompletionChoice, ChatCompletionChoiceTypedDict
from .completionusage import CompletionUsage, CompletionUsageTypedDict
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing import List, Optional
from typing_extensions import NotRequired, TypedDict
class ChatCompletionObject(str, Enum):
CHAT_COMPLETION = "chat.completion"
class ChatCompletionTypedDict(TypedDict):
r"""Chat completion response"""
id: str
r"""Unique completion identifier"""
choices: List[ChatCompletionChoiceTypedDict]
r"""List of completion choices"""
created: float
r"""Unix timestamp of creation"""
model: str
r"""Model used for completion"""
object: ChatCompletionObject
system_fingerprint: NotRequired[Nullable[str]]
r"""System fingerprint"""
usage: NotRequired[CompletionUsageTypedDict]
r"""Token usage statistics"""
class ChatCompletion(BaseModel):
r"""Chat completion response"""
id: str
r"""Unique completion identifier"""
choices: List[ChatCompletionChoice]
r"""List of completion choices"""
created: float
r"""Unix timestamp of creation"""
model: str
r"""Model used for completion"""
object: ChatCompletionObject
system_fingerprint: OptionalNullable[str] = UNSET
r"""System fingerprint"""
usage: Optional[CompletionUsage] = None
r"""Token usage statistics"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["system_fingerprint", "usage"]
nullable_fields = ["system_fingerprint"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,102 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletioncontentpart import (
ChatCompletionContentPart,
ChatCompletionContentPartTypedDict,
)
from .chatcompletionmessagetoolcall import (
ChatCompletionMessageToolCall,
ChatCompletionMessageToolCallTypedDict,
)
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing import Any, List, Optional, Union
from typing_extensions import NotRequired, TypeAliasType, TypedDict
class ChatCompletionAssistantMessageParamRole(str, Enum):
ASSISTANT = "assistant"
ChatCompletionAssistantMessageParamContentTypedDict = TypeAliasType(
"ChatCompletionAssistantMessageParamContentTypedDict",
Union[str, List[ChatCompletionContentPartTypedDict], Any],
)
r"""Assistant message content"""
ChatCompletionAssistantMessageParamContent = TypeAliasType(
"ChatCompletionAssistantMessageParamContent",
Union[str, List[ChatCompletionContentPart], Any],
)
r"""Assistant message content"""
class ChatCompletionAssistantMessageParamTypedDict(TypedDict):
r"""Assistant message with tool calls and audio support"""
role: ChatCompletionAssistantMessageParamRole
content: NotRequired[Nullable[ChatCompletionAssistantMessageParamContentTypedDict]]
r"""Assistant message content"""
name: NotRequired[str]
r"""Optional name for the assistant"""
tool_calls: NotRequired[List[ChatCompletionMessageToolCallTypedDict]]
r"""Tool calls made by the assistant"""
refusal: NotRequired[Nullable[str]]
r"""Refusal message if content was refused"""
class ChatCompletionAssistantMessageParam(BaseModel):
r"""Assistant message with tool calls and audio support"""
role: ChatCompletionAssistantMessageParamRole
content: OptionalNullable[ChatCompletionAssistantMessageParamContent] = UNSET
r"""Assistant message content"""
name: Optional[str] = None
r"""Optional name for the assistant"""
tool_calls: Optional[List[ChatCompletionMessageToolCall]] = None
r"""Tool calls made by the assistant"""
refusal: OptionalNullable[str] = UNSET
r"""Refusal message if content was refused"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["content", "name", "tool_calls", "refusal"]
nullable_fields = ["content", "refusal"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,87 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletionmessage import ChatCompletionMessage, ChatCompletionMessageTypedDict
from .chatcompletiontokenlogprobs import (
ChatCompletionTokenLogprobs,
ChatCompletionTokenLogprobsTypedDict,
)
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing_extensions import NotRequired, TypedDict
class ChatCompletionChoiceFinishReason(str, Enum):
r"""Reason the completion finished"""
TOOL_CALLS = "tool_calls"
STOP = "stop"
LENGTH = "length"
CONTENT_FILTER = "content_filter"
ERROR = "error"
class ChatCompletionChoiceTypedDict(TypedDict):
r"""Chat completion choice"""
finish_reason: Nullable[ChatCompletionChoiceFinishReason]
r"""Reason the completion finished"""
index: float
r"""Choice index"""
message: ChatCompletionMessageTypedDict
r"""Assistant message in completion response"""
logprobs: NotRequired[Nullable[ChatCompletionTokenLogprobsTypedDict]]
r"""Log probabilities for the completion"""
class ChatCompletionChoice(BaseModel):
r"""Chat completion choice"""
finish_reason: Nullable[ChatCompletionChoiceFinishReason]
r"""Reason the completion finished"""
index: float
r"""Choice index"""
message: ChatCompletionMessage
r"""Assistant message in completion response"""
logprobs: OptionalNullable[ChatCompletionTokenLogprobs] = UNSET
r"""Log probabilities for the completion"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["logprobs"]
nullable_fields = ["finish_reason", "logprobs"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,85 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletionchunkchoice import (
ChatCompletionChunkChoice,
ChatCompletionChunkChoiceTypedDict,
)
from .completionusage import CompletionUsage, CompletionUsageTypedDict
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing import List, Optional
from typing_extensions import NotRequired, TypedDict
class ChatCompletionChunkObject(str, Enum):
CHAT_COMPLETION_CHUNK = "chat.completion.chunk"
class ChatCompletionChunkTypedDict(TypedDict):
r"""Streaming chat completion chunk"""
id: str
choices: List[ChatCompletionChunkChoiceTypedDict]
created: float
model: str
object: ChatCompletionChunkObject
system_fingerprint: NotRequired[Nullable[str]]
usage: NotRequired[CompletionUsageTypedDict]
r"""Token usage statistics"""
class ChatCompletionChunk(BaseModel):
r"""Streaming chat completion chunk"""
id: str
choices: List[ChatCompletionChunkChoice]
created: float
model: str
object: ChatCompletionChunkObject
system_fingerprint: OptionalNullable[str] = UNSET
usage: Optional[CompletionUsage] = None
r"""Token usage statistics"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["system_fingerprint", "usage"]
nullable_fields = ["system_fingerprint"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,84 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletionchunkchoicedelta import (
ChatCompletionChunkChoiceDelta,
ChatCompletionChunkChoiceDeltaTypedDict,
)
from .chatcompletiontokenlogprobs import (
ChatCompletionTokenLogprobs,
ChatCompletionTokenLogprobsTypedDict,
)
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing_extensions import NotRequired, TypedDict
class ChatCompletionChunkChoiceFinishReason(str, Enum):
TOOL_CALLS = "tool_calls"
STOP = "stop"
LENGTH = "length"
CONTENT_FILTER = "content_filter"
ERROR = "error"
class ChatCompletionChunkChoiceTypedDict(TypedDict):
r"""Streaming completion choice chunk"""
delta: ChatCompletionChunkChoiceDeltaTypedDict
r"""Delta changes in streaming response"""
finish_reason: Nullable[ChatCompletionChunkChoiceFinishReason]
index: float
logprobs: NotRequired[Nullable[ChatCompletionTokenLogprobsTypedDict]]
r"""Log probabilities for the completion"""
class ChatCompletionChunkChoice(BaseModel):
r"""Streaming completion choice chunk"""
delta: ChatCompletionChunkChoiceDelta
r"""Delta changes in streaming response"""
finish_reason: Nullable[ChatCompletionChunkChoiceFinishReason]
index: float
logprobs: OptionalNullable[ChatCompletionTokenLogprobs] = UNSET
r"""Log probabilities for the completion"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["logprobs"]
nullable_fields = ["finish_reason", "logprobs"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,108 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .annotationdetail import AnnotationDetail, AnnotationDetailTypedDict
from .chatcompletionchunkchoicedeltatoolcall import (
ChatCompletionChunkChoiceDeltaToolCall,
ChatCompletionChunkChoiceDeltaToolCallTypedDict,
)
from .reasoningdetail import ReasoningDetail, ReasoningDetailTypedDict
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing import List, Optional
from typing_extensions import NotRequired, TypedDict
class ChatCompletionChunkChoiceDeltaRole(str, Enum):
r"""The role of the message author"""
ASSISTANT = "assistant"
class ChatCompletionChunkChoiceDeltaTypedDict(TypedDict):
r"""Delta changes in streaming response"""
role: NotRequired[ChatCompletionChunkChoiceDeltaRole]
r"""The role of the message author"""
content: NotRequired[Nullable[str]]
r"""Message content delta"""
reasoning: NotRequired[Nullable[str]]
r"""Reasoning content delta"""
refusal: NotRequired[Nullable[str]]
r"""Refusal message delta"""
tool_calls: NotRequired[List[ChatCompletionChunkChoiceDeltaToolCallTypedDict]]
r"""Tool calls delta"""
reasoning_details: NotRequired[List[ReasoningDetailTypedDict]]
r"""Reasoning details delta to send reasoning details back to upstream"""
annotations: NotRequired[List[AnnotationDetailTypedDict]]
r"""Annotations delta to send annotations back to upstream"""
class ChatCompletionChunkChoiceDelta(BaseModel):
r"""Delta changes in streaming response"""
role: Optional[ChatCompletionChunkChoiceDeltaRole] = None
r"""The role of the message author"""
content: OptionalNullable[str] = UNSET
r"""Message content delta"""
reasoning: OptionalNullable[str] = UNSET
r"""Reasoning content delta"""
refusal: OptionalNullable[str] = UNSET
r"""Refusal message delta"""
tool_calls: Optional[List[ChatCompletionChunkChoiceDeltaToolCall]] = None
r"""Tool calls delta"""
reasoning_details: Optional[List[ReasoningDetail]] = None
r"""Reasoning details delta to send reasoning details back to upstream"""
annotations: Optional[List[AnnotationDetail]] = None
r"""Annotations delta to send annotations back to upstream"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"role",
"content",
"reasoning",
"refusal",
"tool_calls",
"reasoning_details",
"annotations",
]
nullable_fields = ["content", "reasoning", "refusal"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,61 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import BaseModel
from typing import Optional
from typing_extensions import NotRequired, TypedDict
class ChatCompletionChunkChoiceDeltaToolCallType(str, Enum):
r"""Tool call type"""
FUNCTION = "function"
class ChatCompletionChunkChoiceDeltaToolCallFunctionTypedDict(TypedDict):
r"""Function call details"""
name: NotRequired[str]
r"""Function name"""
arguments: NotRequired[str]
r"""Function arguments as JSON string"""
class ChatCompletionChunkChoiceDeltaToolCallFunction(BaseModel):
r"""Function call details"""
name: Optional[str] = None
r"""Function name"""
arguments: Optional[str] = None
r"""Function arguments as JSON string"""
class ChatCompletionChunkChoiceDeltaToolCallTypedDict(TypedDict):
r"""Tool call delta for streaming responses"""
index: float
r"""Tool call index in the array"""
id: NotRequired[str]
r"""Tool call identifier"""
type: NotRequired[ChatCompletionChunkChoiceDeltaToolCallType]
r"""Tool call type"""
function: NotRequired[ChatCompletionChunkChoiceDeltaToolCallFunctionTypedDict]
r"""Function call details"""
class ChatCompletionChunkChoiceDeltaToolCall(BaseModel):
r"""Tool call delta for streaming responses"""
index: float
r"""Tool call index in the array"""
id: Optional[str] = None
r"""Tool call identifier"""
type: Optional[ChatCompletionChunkChoiceDeltaToolCallType] = None
r"""Tool call type"""
function: Optional[ChatCompletionChunkChoiceDeltaToolCallFunction] = None
r"""Function call details"""
@@ -0,0 +1,41 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletioncontentpartaudio import (
ChatCompletionContentPartAudio,
ChatCompletionContentPartAudioTypedDict,
)
from .chatcompletioncontentpartimage import (
ChatCompletionContentPartImage,
ChatCompletionContentPartImageTypedDict,
)
from .chatcompletioncontentparttext import (
ChatCompletionContentPartText,
ChatCompletionContentPartTextTypedDict,
)
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from typing import Union
from typing_extensions import Annotated, TypeAliasType
ChatCompletionContentPartTypedDict = TypeAliasType(
"ChatCompletionContentPartTypedDict",
Union[
ChatCompletionContentPartTextTypedDict,
ChatCompletionContentPartImageTypedDict,
ChatCompletionContentPartAudioTypedDict,
],
)
r"""Content part for chat completion messages"""
ChatCompletionContentPart = Annotated[
Union[
Annotated[ChatCompletionContentPartText, Tag("text")],
Annotated[ChatCompletionContentPartImage, Tag("image_url")],
Annotated[ChatCompletionContentPartAudio, Tag("input_audio")],
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
]
r"""Content part for chat completion messages"""
@@ -0,0 +1,55 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import BaseModel
import pydantic
from typing_extensions import Annotated, TypedDict
class ChatCompletionContentPartAudioType(str, Enum):
INPUT_AUDIO = "input_audio"
class ChatCompletionContentPartAudioFormat(str, Enum):
r"""Audio format"""
WAV = "wav"
MP3 = "mp3"
FLAC = "flac"
M4A = "m4a"
OGG = "ogg"
PCM16 = "pcm16"
PCM24 = "pcm24"
class InputAudioTypedDict(TypedDict):
data: str
r"""Base64 encoded audio data"""
format_: ChatCompletionContentPartAudioFormat
r"""Audio format"""
class InputAudio(BaseModel):
data: str
r"""Base64 encoded audio data"""
format_: Annotated[
ChatCompletionContentPartAudioFormat, pydantic.Field(alias="format")
]
r"""Audio format"""
class ChatCompletionContentPartAudioTypedDict(TypedDict):
r"""Audio input content part"""
type: ChatCompletionContentPartAudioType
input_audio: InputAudioTypedDict
class ChatCompletionContentPartAudio(BaseModel):
r"""Audio input content part"""
type: ChatCompletionContentPartAudioType
input_audio: InputAudio
@@ -0,0 +1,49 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import BaseModel
from typing import Optional
from typing_extensions import NotRequired, TypedDict
class ChatCompletionContentPartImageType(str, Enum):
IMAGE_URL = "image_url"
class Detail(str, Enum):
r"""Image detail level for vision models"""
AUTO = "auto"
LOW = "low"
HIGH = "high"
class ChatCompletionContentPartImageImageURLTypedDict(TypedDict):
url: str
r"""URL of the image (data: URLs supported)"""
detail: NotRequired[Detail]
r"""Image detail level for vision models"""
class ChatCompletionContentPartImageImageURL(BaseModel):
url: str
r"""URL of the image (data: URLs supported)"""
detail: Optional[Detail] = None
r"""Image detail level for vision models"""
class ChatCompletionContentPartImageTypedDict(TypedDict):
r"""Image content part for vision models"""
type: ChatCompletionContentPartImageType
image_url: ChatCompletionContentPartImageImageURLTypedDict
class ChatCompletionContentPartImage(BaseModel):
r"""Image content part for vision models"""
type: ChatCompletionContentPartImageType
image_url: ChatCompletionContentPartImageImageURL
@@ -0,0 +1,25 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import BaseModel
from typing_extensions import TypedDict
class ChatCompletionContentPartTextType(str, Enum):
TEXT = "text"
class ChatCompletionContentPartTextTypedDict(TypedDict):
r"""Text content part"""
type: ChatCompletionContentPartTextType
text: str
class ChatCompletionContentPartText(BaseModel):
r"""Text content part"""
type: ChatCompletionContentPartTextType
text: str
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,57 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL
from pydantic import model_serializer
from typing_extensions import TypedDict
class ErrorTypedDict(TypedDict):
r"""Error object structure"""
code: Nullable[str]
message: str
param: Nullable[str]
type: str
class Error(BaseModel):
r"""Error object structure"""
code: Nullable[str]
message: str
param: Nullable[str]
type: str
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["code", "param"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,101 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .annotationdetail import AnnotationDetail, AnnotationDetailTypedDict
from .chatcompletionmessagetoolcall import (
ChatCompletionMessageToolCall,
ChatCompletionMessageToolCallTypedDict,
)
from .reasoningdetail import ReasoningDetail, ReasoningDetailTypedDict
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing import List, Optional
from typing_extensions import NotRequired, TypedDict
class ChatCompletionMessageRole(str, Enum):
ASSISTANT = "assistant"
class ChatCompletionMessageTypedDict(TypedDict):
r"""Assistant message in completion response"""
role: ChatCompletionMessageRole
content: Nullable[str]
r"""Message content"""
refusal: Nullable[str]
r"""Refusal message if content was refused"""
reasoning: NotRequired[Nullable[str]]
r"""Reasoning output"""
tool_calls: NotRequired[List[ChatCompletionMessageToolCallTypedDict]]
r"""Tool calls made by the assistant"""
reasoning_details: NotRequired[List[ReasoningDetailTypedDict]]
r"""Reasoning details delta to send reasoning details back to upstream"""
annotations: NotRequired[List[AnnotationDetailTypedDict]]
r"""Annotations delta to send annotations back to upstream"""
class ChatCompletionMessage(BaseModel):
r"""Assistant message in completion response"""
role: ChatCompletionMessageRole
content: Nullable[str]
r"""Message content"""
refusal: Nullable[str]
r"""Refusal message if content was refused"""
reasoning: OptionalNullable[str] = UNSET
r"""Reasoning output"""
tool_calls: Optional[List[ChatCompletionMessageToolCall]] = None
r"""Tool calls made by the assistant"""
reasoning_details: Optional[List[ReasoningDetail]] = None
r"""Reasoning details delta to send reasoning details back to upstream"""
annotations: Optional[List[AnnotationDetail]] = None
r"""Annotations delta to send annotations back to upstream"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = [
"reasoning",
"tool_calls",
"reasoning_details",
"annotations",
]
nullable_fields = ["content", "reasoning", "refusal"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,47 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletionassistantmessageparam import (
ChatCompletionAssistantMessageParam,
ChatCompletionAssistantMessageParamTypedDict,
)
from .chatcompletionsystemmessageparam import (
ChatCompletionSystemMessageParam,
ChatCompletionSystemMessageParamTypedDict,
)
from .chatcompletiontoolmessageparam import (
ChatCompletionToolMessageParam,
ChatCompletionToolMessageParamTypedDict,
)
from .chatcompletionusermessageparam import (
ChatCompletionUserMessageParam,
ChatCompletionUserMessageParamTypedDict,
)
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from typing import Union
from typing_extensions import Annotated, TypeAliasType
ChatCompletionMessageParamTypedDict = TypeAliasType(
"ChatCompletionMessageParamTypedDict",
Union[
ChatCompletionSystemMessageParamTypedDict,
ChatCompletionUserMessageParamTypedDict,
ChatCompletionToolMessageParamTypedDict,
ChatCompletionAssistantMessageParamTypedDict,
],
)
r"""Chat completion message with role-based discrimination"""
ChatCompletionMessageParam = Annotated[
Union[
Annotated[ChatCompletionSystemMessageParam, Tag("system")],
Annotated[ChatCompletionUserMessageParam, Tag("user")],
Annotated[ChatCompletionAssistantMessageParam, Tag("assistant")],
Annotated[ChatCompletionToolMessageParam, Tag("tool")],
],
Discriminator(lambda m: get_discriminator(m, "role", "role")),
]
r"""Chat completion message with role-based discrimination"""
@@ -0,0 +1,45 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import BaseModel
from typing_extensions import TypedDict
class ChatCompletionMessageToolCallType(str, Enum):
FUNCTION = "function"
class ChatCompletionMessageToolCallFunctionTypedDict(TypedDict):
name: str
r"""Function name to call"""
arguments: str
r"""Function arguments as JSON string"""
class ChatCompletionMessageToolCallFunction(BaseModel):
name: str
r"""Function name to call"""
arguments: str
r"""Function arguments as JSON string"""
class ChatCompletionMessageToolCallTypedDict(TypedDict):
r"""Tool call made by the assistant"""
id: str
r"""Tool call identifier"""
type: ChatCompletionMessageToolCallType
function: ChatCompletionMessageToolCallFunctionTypedDict
class ChatCompletionMessageToolCall(BaseModel):
r"""Tool call made by the assistant"""
id: str
r"""Tool call identifier"""
type: ChatCompletionMessageToolCallType
function: ChatCompletionMessageToolCallFunction
@@ -0,0 +1,35 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import BaseModel
from typing_extensions import TypedDict
class ChatCompletionNamedToolChoiceType(str, Enum):
FUNCTION = "function"
class ChatCompletionNamedToolChoiceFunctionTypedDict(TypedDict):
name: str
r"""Function name to call"""
class ChatCompletionNamedToolChoiceFunction(BaseModel):
name: str
r"""Function name to call"""
class ChatCompletionNamedToolChoiceTypedDict(TypedDict):
r"""Named tool choice for specific function"""
type: ChatCompletionNamedToolChoiceType
function: ChatCompletionNamedToolChoiceFunctionTypedDict
class ChatCompletionNamedToolChoice(BaseModel):
r"""Named tool choice for specific function"""
type: ChatCompletionNamedToolChoiceType
function: ChatCompletionNamedToolChoiceFunction
@@ -0,0 +1,51 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletioncontentparttext import (
ChatCompletionContentPartText,
ChatCompletionContentPartTextTypedDict,
)
from enum import Enum
from openrouter.types import BaseModel
from typing import List, Optional, Union
from typing_extensions import NotRequired, TypeAliasType, TypedDict
class ChatCompletionSystemMessageParamRole(str, Enum):
SYSTEM = "system"
ChatCompletionSystemMessageParamContentTypedDict = TypeAliasType(
"ChatCompletionSystemMessageParamContentTypedDict",
Union[str, List[ChatCompletionContentPartTextTypedDict]],
)
r"""System message content"""
ChatCompletionSystemMessageParamContent = TypeAliasType(
"ChatCompletionSystemMessageParamContent",
Union[str, List[ChatCompletionContentPartText]],
)
r"""System message content"""
class ChatCompletionSystemMessageParamTypedDict(TypedDict):
r"""System message for setting behavior"""
role: ChatCompletionSystemMessageParamRole
content: ChatCompletionSystemMessageParamContentTypedDict
r"""System message content"""
name: NotRequired[str]
r"""Optional name for the system message"""
class ChatCompletionSystemMessageParam(BaseModel):
r"""System message for setting behavior"""
role: ChatCompletionSystemMessageParamRole
content: ChatCompletionSystemMessageParamContent
r"""System message content"""
name: Optional[str] = None
r"""Optional name for the system message"""
@@ -0,0 +1,111 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL
import pydantic
from pydantic import model_serializer
from typing import List
from typing_extensions import Annotated, TypedDict
class TopLogprobTypedDict(TypedDict):
token: str
logprob: float
bytes_: Nullable[List[float]]
class TopLogprob(BaseModel):
token: str
logprob: float
bytes_: Annotated[Nullable[List[float]], pydantic.Field(alias="bytes")]
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["bytes"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
class ChatCompletionTokenLogprobTypedDict(TypedDict):
r"""Token log probability information"""
token: str
r"""The token"""
logprob: float
r"""Log probability of the token"""
bytes_: Nullable[List[float]]
r"""UTF-8 bytes of the token"""
top_logprobs: List[TopLogprobTypedDict]
r"""Top alternative tokens with probabilities"""
class ChatCompletionTokenLogprob(BaseModel):
r"""Token log probability information"""
token: str
r"""The token"""
logprob: float
r"""Log probability of the token"""
bytes_: Annotated[Nullable[List[float]], pydantic.Field(alias="bytes")]
r"""UTF-8 bytes of the token"""
top_logprobs: List[TopLogprob]
r"""Top alternative tokens with probabilities"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["bytes"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,60 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletiontokenlogprob import (
ChatCompletionTokenLogprob,
ChatCompletionTokenLogprobTypedDict,
)
from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL
from pydantic import model_serializer
from typing import List
from typing_extensions import TypedDict
class ChatCompletionTokenLogprobsTypedDict(TypedDict):
r"""Log probabilities for the completion"""
content: Nullable[List[ChatCompletionTokenLogprobTypedDict]]
r"""Log probabilities for content tokens"""
refusal: Nullable[List[ChatCompletionTokenLogprobTypedDict]]
r"""Log probabilities for refusal tokens"""
class ChatCompletionTokenLogprobs(BaseModel):
r"""Log probabilities for the completion"""
content: Nullable[List[ChatCompletionTokenLogprob]]
r"""Log probabilities for content tokens"""
refusal: Nullable[List[ChatCompletionTokenLogprob]]
r"""Log probabilities for refusal tokens"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = []
nullable_fields = ["content", "refusal"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
+102
View File
@@ -0,0 +1,102 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
from pydantic import model_serializer
from typing import Optional
from typing_extensions import NotRequired, TypedDict
class ChatCompletionToolType(str, Enum):
FUNCTION = "function"
class ParametersTypedDict(TypedDict):
r"""Function parameters as JSON Schema object"""
class Parameters(BaseModel):
r"""Function parameters as JSON Schema object"""
class ChatCompletionToolFunctionTypedDict(TypedDict):
r"""Function definition for tool calling"""
name: str
r"""Function name (a-z, A-Z, 0-9, underscores, dashes, max 64 chars)"""
description: NotRequired[str]
r"""Function description for the model"""
parameters: NotRequired[ParametersTypedDict]
r"""Function parameters as JSON Schema object"""
strict: NotRequired[Nullable[bool]]
r"""Enable strict schema adherence"""
class ChatCompletionToolFunction(BaseModel):
r"""Function definition for tool calling"""
name: str
r"""Function name (a-z, A-Z, 0-9, underscores, dashes, max 64 chars)"""
description: Optional[str] = None
r"""Function description for the model"""
parameters: Optional[Parameters] = None
r"""Function parameters as JSON Schema object"""
strict: OptionalNullable[bool] = UNSET
r"""Enable strict schema adherence"""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["description", "parameters", "strict"]
nullable_fields = ["strict"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
class ChatCompletionToolTypedDict(TypedDict):
r"""Tool definition for function calling"""
type: ChatCompletionToolType
function: ChatCompletionToolFunctionTypedDict
r"""Function definition for tool calling"""
class ChatCompletionTool(BaseModel):
r"""Tool definition for function calling"""
type: ChatCompletionToolType
function: ChatCompletionToolFunction
r"""Function definition for tool calling"""
@@ -0,0 +1,46 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletionnamedtoolchoice import (
ChatCompletionNamedToolChoice,
ChatCompletionNamedToolChoiceTypedDict,
)
from enum import Enum
from typing import Union
from typing_extensions import TypeAliasType
class ChatCompletionToolChoiceOptionRequired(str, Enum):
REQUIRED = "required"
class ChatCompletionToolChoiceOptionAuto(str, Enum):
AUTO = "auto"
class ChatCompletionToolChoiceOptionNone(str, Enum):
NONE = "none"
ChatCompletionToolChoiceOptionTypedDict = TypeAliasType(
"ChatCompletionToolChoiceOptionTypedDict",
Union[
ChatCompletionNamedToolChoiceTypedDict,
ChatCompletionToolChoiceOptionNone,
ChatCompletionToolChoiceOptionAuto,
ChatCompletionToolChoiceOptionRequired,
],
)
r"""Tool choice configuration"""
ChatCompletionToolChoiceOption = TypeAliasType(
"ChatCompletionToolChoiceOption",
Union[
ChatCompletionNamedToolChoice,
ChatCompletionToolChoiceOptionNone,
ChatCompletionToolChoiceOptionAuto,
ChatCompletionToolChoiceOptionRequired,
],
)
r"""Tool choice configuration"""
@@ -0,0 +1,50 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletioncontentpart import (
ChatCompletionContentPart,
ChatCompletionContentPartTypedDict,
)
from enum import Enum
from openrouter.types import BaseModel
from typing import List, Union
from typing_extensions import TypeAliasType, TypedDict
class ChatCompletionToolMessageParamRole(str, Enum):
TOOL = "tool"
ChatCompletionToolMessageParamContentTypedDict = TypeAliasType(
"ChatCompletionToolMessageParamContentTypedDict",
Union[str, List[ChatCompletionContentPartTypedDict]],
)
r"""Tool response content"""
ChatCompletionToolMessageParamContent = TypeAliasType(
"ChatCompletionToolMessageParamContent", Union[str, List[ChatCompletionContentPart]]
)
r"""Tool response content"""
class ChatCompletionToolMessageParamTypedDict(TypedDict):
r"""Tool response message"""
role: ChatCompletionToolMessageParamRole
content: ChatCompletionToolMessageParamContentTypedDict
r"""Tool response content"""
tool_call_id: str
r"""ID of the tool call this message responds to"""
class ChatCompletionToolMessageParam(BaseModel):
r"""Tool response message"""
role: ChatCompletionToolMessageParamRole
content: ChatCompletionToolMessageParamContent
r"""Tool response content"""
tool_call_id: str
r"""ID of the tool call this message responds to"""
@@ -0,0 +1,50 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletioncontentpart import (
ChatCompletionContentPart,
ChatCompletionContentPartTypedDict,
)
from enum import Enum
from openrouter.types import BaseModel
from typing import List, Optional, Union
from typing_extensions import NotRequired, TypeAliasType, TypedDict
class ChatCompletionUserMessageParamRole(str, Enum):
USER = "user"
ChatCompletionUserMessageParamContentTypedDict = TypeAliasType(
"ChatCompletionUserMessageParamContentTypedDict",
Union[str, List[ChatCompletionContentPartTypedDict]],
)
r"""User message content"""
ChatCompletionUserMessageParamContent = TypeAliasType(
"ChatCompletionUserMessageParamContent", Union[str, List[ChatCompletionContentPart]]
)
r"""User message content"""
class ChatCompletionUserMessageParamTypedDict(TypedDict):
r"""User message"""
role: ChatCompletionUserMessageParamRole
content: ChatCompletionUserMessageParamContentTypedDict
r"""User message content"""
name: NotRequired[str]
r"""Optional name for the user"""
class ChatCompletionUserMessageParam(BaseModel):
r"""User message"""
role: ChatCompletionUserMessageParamRole
content: ChatCompletionUserMessageParamContent
r"""User message content"""
name: Optional[str] = None
r"""Optional name for the user"""
File diff suppressed because it is too large Load Diff
+88
View File
@@ -0,0 +1,88 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from typing import Optional
from typing_extensions import NotRequired, TypedDict
class CompletionTokensDetailsTypedDict(TypedDict):
r"""Detailed completion token usage"""
reasoning_tokens: NotRequired[float]
r"""Tokens used for reasoning"""
audio_tokens: NotRequired[float]
r"""Tokens used for audio output"""
accepted_prediction_tokens: NotRequired[float]
r"""Accepted prediction tokens"""
rejected_prediction_tokens: NotRequired[float]
r"""Rejected prediction tokens"""
class CompletionTokensDetails(BaseModel):
r"""Detailed completion token usage"""
reasoning_tokens: Optional[float] = None
r"""Tokens used for reasoning"""
audio_tokens: Optional[float] = None
r"""Tokens used for audio output"""
accepted_prediction_tokens: Optional[float] = None
r"""Accepted prediction tokens"""
rejected_prediction_tokens: Optional[float] = None
r"""Rejected prediction tokens"""
class PromptTokensDetailsTypedDict(TypedDict):
r"""Detailed prompt token usage"""
cached_tokens: NotRequired[float]
r"""Cached prompt tokens"""
audio_tokens: NotRequired[float]
r"""Audio input tokens"""
class PromptTokensDetails(BaseModel):
r"""Detailed prompt token usage"""
cached_tokens: Optional[float] = None
r"""Cached prompt tokens"""
audio_tokens: Optional[float] = None
r"""Audio input tokens"""
class CompletionUsageTypedDict(TypedDict):
r"""Token usage statistics"""
completion_tokens: float
r"""Number of tokens in the completion"""
prompt_tokens: float
r"""Number of tokens in the prompt"""
total_tokens: float
r"""Total number of tokens"""
completion_tokens_details: NotRequired[CompletionTokensDetailsTypedDict]
r"""Detailed completion token usage"""
prompt_tokens_details: NotRequired[PromptTokensDetailsTypedDict]
r"""Detailed prompt token usage"""
class CompletionUsage(BaseModel):
r"""Token usage statistics"""
completion_tokens: float
r"""Number of tokens in the completion"""
prompt_tokens: float
r"""Number of tokens in the prompt"""
total_tokens: float
r"""Total number of tokens"""
completion_tokens_details: Optional[CompletionTokensDetails] = None
r"""Detailed completion token usage"""
prompt_tokens_details: Optional[PromptTokensDetails] = None
r"""Detailed prompt token usage"""
@@ -0,0 +1,89 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import BaseModel
from typing import List, Optional, Union
from typing_extensions import NotRequired, TypeAliasType, TypedDict
class TypeFile(str, Enum):
FILE = "file"
class ContentTypeImageURL(str, Enum):
IMAGE_URL = "image_url"
class FileAnnotationDetailImageURLTypedDict(TypedDict):
url: str
class FileAnnotationDetailImageURL(BaseModel):
url: str
class ContentImageURLTypedDict(TypedDict):
type: ContentTypeImageURL
image_url: FileAnnotationDetailImageURLTypedDict
class ContentImageURL(BaseModel):
type: ContentTypeImageURL
image_url: FileAnnotationDetailImageURL
class ContentTypeText(str, Enum):
TEXT = "text"
class ContentTextTypedDict(TypedDict):
type: ContentTypeText
text: str
class ContentText(BaseModel):
type: ContentTypeText
text: str
FileAnnotationDetailContentUnionTypedDict = TypeAliasType(
"FileAnnotationDetailContentUnionTypedDict",
Union[ContentTextTypedDict, ContentImageURLTypedDict],
)
FileAnnotationDetailContentUnion = TypeAliasType(
"FileAnnotationDetailContentUnion", Union[ContentText, ContentImageURL]
)
class FileTypedDict(TypedDict):
hash: str
content: List[FileAnnotationDetailContentUnionTypedDict]
name: NotRequired[str]
class File(BaseModel):
hash: str
content: List[FileAnnotationDetailContentUnion]
name: Optional[str] = None
class FileAnnotationDetailTypedDict(TypedDict):
r"""File annotation with content"""
type: TypeFile
file: FileTypedDict
class FileAnnotationDetail(BaseModel):
r"""File annotation with content"""
type: TypeFile
file: File
+38
View File
@@ -0,0 +1,38 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .reasoningdetailencrypted import (
ReasoningDetailEncrypted,
ReasoningDetailEncryptedTypedDict,
)
from .reasoningdetailsummary import (
ReasoningDetailSummary,
ReasoningDetailSummaryTypedDict,
)
from .reasoningdetailtext import ReasoningDetailText, ReasoningDetailTextTypedDict
from openrouter.utils import get_discriminator
from pydantic import Discriminator, Tag
from typing import Union
from typing_extensions import Annotated, TypeAliasType
ReasoningDetailTypedDict = TypeAliasType(
"ReasoningDetailTypedDict",
Union[
ReasoningDetailSummaryTypedDict,
ReasoningDetailEncryptedTypedDict,
ReasoningDetailTextTypedDict,
],
)
r"""Reasoning detail information"""
ReasoningDetail = Annotated[
Union[
Annotated[ReasoningDetailSummary, Tag("reasoning.summary")],
Annotated[ReasoningDetailEncrypted, Tag("reasoning.encrypted")],
Annotated[ReasoningDetailText, Tag("reasoning.text")],
],
Discriminator(lambda m: get_discriminator(m, "type", "type")),
]
r"""Reasoning detail information"""
@@ -0,0 +1,81 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
import pydantic
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict
class ReasoningDetailEncryptedType(str, Enum):
REASONING_ENCRYPTED = "reasoning.encrypted"
class ReasoningDetailEncryptedFormat(str, Enum):
UNKNOWN = "unknown"
OPENAI_RESPONSES_V1 = "openai-responses-v1"
ANTHROPIC_CLAUDE_V1 = "anthropic-claude-v1"
class ReasoningDetailEncryptedTypedDict(TypedDict):
r"""Encrypted reasoning detail"""
type: ReasoningDetailEncryptedType
data: str
id: NotRequired[Nullable[str]]
format_: NotRequired[Nullable[ReasoningDetailEncryptedFormat]]
index: NotRequired[float]
class ReasoningDetailEncrypted(BaseModel):
r"""Encrypted reasoning detail"""
type: ReasoningDetailEncryptedType
data: str
id: OptionalNullable[str] = UNSET
format_: Annotated[
OptionalNullable[ReasoningDetailEncryptedFormat], pydantic.Field(alias="format")
] = ReasoningDetailEncryptedFormat.ANTHROPIC_CLAUDE_V1
index: Optional[float] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["id", "format", "index"]
nullable_fields = ["id", "format"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,81 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
import pydantic
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict
class ReasoningDetailSummaryType(str, Enum):
REASONING_SUMMARY = "reasoning.summary"
class ReasoningDetailSummaryFormat(str, Enum):
UNKNOWN = "unknown"
OPENAI_RESPONSES_V1 = "openai-responses-v1"
ANTHROPIC_CLAUDE_V1 = "anthropic-claude-v1"
class ReasoningDetailSummaryTypedDict(TypedDict):
r"""Reasoning summary detail"""
type: ReasoningDetailSummaryType
summary: str
id: NotRequired[Nullable[str]]
format_: NotRequired[Nullable[ReasoningDetailSummaryFormat]]
index: NotRequired[float]
class ReasoningDetailSummary(BaseModel):
r"""Reasoning summary detail"""
type: ReasoningDetailSummaryType
summary: str
id: OptionalNullable[str] = UNSET
format_: Annotated[
OptionalNullable[ReasoningDetailSummaryFormat], pydantic.Field(alias="format")
] = ReasoningDetailSummaryFormat.ANTHROPIC_CLAUDE_V1
index: Optional[float] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["id", "format", "index"]
nullable_fields = ["id", "format"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,84 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import (
BaseModel,
Nullable,
OptionalNullable,
UNSET,
UNSET_SENTINEL,
)
import pydantic
from pydantic import model_serializer
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict
class ReasoningDetailTextType(str, Enum):
REASONING_TEXT = "reasoning.text"
class ReasoningDetailTextFormat(str, Enum):
UNKNOWN = "unknown"
OPENAI_RESPONSES_V1 = "openai-responses-v1"
ANTHROPIC_CLAUDE_V1 = "anthropic-claude-v1"
class ReasoningDetailTextTypedDict(TypedDict):
r"""Text reasoning detail"""
type: ReasoningDetailTextType
text: NotRequired[Nullable[str]]
signature: NotRequired[Nullable[str]]
id: NotRequired[Nullable[str]]
format_: NotRequired[Nullable[ReasoningDetailTextFormat]]
index: NotRequired[float]
class ReasoningDetailText(BaseModel):
r"""Text reasoning detail"""
type: ReasoningDetailTextType
text: OptionalNullable[str] = UNSET
signature: OptionalNullable[str] = UNSET
id: OptionalNullable[str] = UNSET
format_: Annotated[
OptionalNullable[ReasoningDetailTextFormat], pydantic.Field(alias="format")
] = ReasoningDetailTextFormat.ANTHROPIC_CLAUDE_V1
index: Optional[float] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = ["text", "signature", "id", "format", "index"]
nullable_fields = ["text", "signature", "id", "format"]
null_default_fields = []
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k)
serialized.pop(k, None)
optional_nullable = k in optional_fields and k in nullable_fields
is_set = (
self.__pydantic_fields_set__.intersection({n})
or k in null_default_fields
) # pylint: disable=no-member
if val is not None and val != UNSET_SENTINEL:
m[k] = val
elif val != UNSET_SENTINEL and (
not k in optional_fields or (optional_nullable and is_set)
):
m[k] = val
return m
@@ -0,0 +1,13 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from typing_extensions import TypedDict
class ResponseFormatJSONSchemaSchemaTypedDict(TypedDict):
r"""The schema for the response format, described as a JSON Schema object"""
class ResponseFormatJSONSchemaSchema(BaseModel):
r"""The schema for the response format, described as a JSON Schema object"""
+25
View File
@@ -0,0 +1,25 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from openrouter.types import BaseModel
from openrouter.utils import FieldMetadata, SecurityMetadata
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict
class SecurityTypedDict(TypedDict):
bearer_auth: NotRequired[str]
class Security(BaseModel):
bearer_auth: Annotated[
Optional[str],
FieldMetadata(
security=SecurityMetadata(
scheme=True,
scheme_type="http",
sub_type="bearer",
field_name="Authorization",
)
),
] = None
@@ -0,0 +1,20 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from .chatcompletionchunk import ChatCompletionChunk, ChatCompletionChunkTypedDict
from openrouter.types import BaseModel
from typing_extensions import TypedDict
class StreamChatCompletionResponseBodyTypedDict(TypedDict):
r"""Successful chat completion response"""
data: ChatCompletionChunkTypedDict
r"""Streaming chat completion chunk"""
class StreamChatCompletionResponseBody(BaseModel):
r"""Successful chat completion response"""
data: ChatCompletionChunk
r"""Streaming chat completion chunk"""
@@ -0,0 +1,46 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from enum import Enum
from openrouter.types import BaseModel
from typing import Optional
from typing_extensions import NotRequired, TypedDict
class URLCitationAnnotationDetailType(str, Enum):
URL_CITATION = "url_citation"
class URLCitationTypedDict(TypedDict):
end_index: float
start_index: float
title: str
url: str
content: NotRequired[str]
class URLCitation(BaseModel):
end_index: float
start_index: float
title: str
url: str
content: Optional[str] = None
class URLCitationAnnotationDetailTypedDict(TypedDict):
r"""URL citation annotation"""
type: URLCitationAnnotationDetailType
url_citation: URLCitationTypedDict
class URLCitationAnnotationDetail(BaseModel):
r"""URL citation annotation"""
type: URLCitationAnnotationDetailType
url_citation: URLCitation
+1
View File
@@ -0,0 +1 @@
# Marker file for PEP 561. The package enables type hints.
+174
View File
@@ -0,0 +1,174 @@
"""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
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,
bearer_auth: 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 bearer_auth: The bearer_auth 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(bearer_auth):
# pylint: disable=unnecessary-lambda-assignment
security = lambda: models.Security(bearer_auth=bearer_auth())
else:
security = models.Security(bearer_auth=bearer_auth)
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,
),
)
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 __getattr__(self, name: str):
if name in self._sub_sdk_map:
module_path, class_name = self._sub_sdk_map[name]
try:
module = importlib.import_module(module_path)
klass = getattr(module, class_name)
instance = klass(self.sdk_configuration)
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
+50
View File
@@ -0,0 +1,50 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from ._version import (
__gen_version__,
__openapi_doc_version__,
__user_agent__,
__version__,
)
from .httpclient import AsyncHttpClient, HttpClient
from .utils import Logger, RetryConfig, remove_suffix
from dataclasses import dataclass, field
from openrouter import models
from openrouter.types import OptionalNullable, UNSET
from pydantic import Field
from typing import Callable, Dict, List, Optional, Tuple, Union
SERVERS = [
"https://{provider_url}/api/v1",
# Production server
]
"""Contains the list of servers available to the SDK"""
@dataclass
class SDKConfiguration:
client: Union[HttpClient, None]
client_supplied: bool
async_client: Union[AsyncHttpClient, None]
async_client_supplied: bool
debug_logger: Logger
security: Optional[Union[models.Security, Callable[[], models.Security]]] = None
server_url: Optional[str] = ""
server_idx: Optional[int] = 0
server_defaults: List[Dict[str, str]] = field(default_factory=List)
language: str = "python"
openapi_doc_version: str = __openapi_doc_version__
sdk_version: str = __version__
gen_version: str = __gen_version__
user_agent: str = __user_agent__
retry_config: OptionalNullable[RetryConfig] = Field(default_factory=lambda: UNSET)
timeout_ms: Optional[int] = None
def get_server_details(self) -> Tuple[str, Dict[str, str]]:
if self.server_url is not None and self.server_url:
return remove_suffix(self.server_url, "/"), {}
if self.server_idx is None:
self.server_idx = 0
return SERVERS[self.server_idx], self.server_defaults[self.server_idx]
+21
View File
@@ -0,0 +1,21 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from .basemodel import (
BaseModel,
Nullable,
OptionalNullable,
UnrecognizedInt,
UnrecognizedStr,
UNSET,
UNSET_SENTINEL,
)
__all__ = [
"BaseModel",
"Nullable",
"OptionalNullable",
"UnrecognizedInt",
"UnrecognizedStr",
"UNSET",
"UNSET_SENTINEL",
]
+39
View File
@@ -0,0 +1,39 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from pydantic import ConfigDict, model_serializer
from pydantic import BaseModel as PydanticBaseModel
from typing import TYPE_CHECKING, Literal, Optional, TypeVar, Union
from typing_extensions import TypeAliasType, TypeAlias
class BaseModel(PydanticBaseModel):
model_config = ConfigDict(
populate_by_name=True, arbitrary_types_allowed=True, protected_namespaces=()
)
class Unset(BaseModel):
@model_serializer(mode="plain")
def serialize_model(self):
return UNSET_SENTINEL
def __bool__(self) -> Literal[False]:
return False
UNSET = Unset()
UNSET_SENTINEL = "~?~unset~?~sentinel~?~"
T = TypeVar("T")
if TYPE_CHECKING:
Nullable: TypeAlias = Union[T, None]
OptionalNullable: TypeAlias = Union[Optional[Nullable[T]], Unset]
else:
Nullable = TypeAliasType("Nullable", Union[T, None], type_params=(T,))
OptionalNullable = TypeAliasType(
"OptionalNullable", Union[Optional[Nullable[T]], Unset], type_params=(T,)
)
UnrecognizedInt: TypeAlias = int
UnrecognizedStr: TypeAlias = str
+188
View File
@@ -0,0 +1,188 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import TYPE_CHECKING
from importlib import import_module
import builtins
if TYPE_CHECKING:
from .annotations import get_discriminator
from .datetimes import parse_datetime
from .enums import OpenEnumMeta
from .headers import get_headers, get_response_headers
from .metadata import (
FieldMetadata,
find_metadata,
FormMetadata,
HeaderMetadata,
MultipartFormMetadata,
PathParamMetadata,
QueryParamMetadata,
RequestMetadata,
SecurityMetadata,
)
from .queryparams import get_query_params
from .retries import BackoffStrategy, Retries, retry, retry_async, RetryConfig
from .requestbodies import serialize_request_body, SerializedRequestBody
from .security import get_security, get_security_from_env
from .serializers import (
get_pydantic_model,
marshal_json,
unmarshal,
unmarshal_json,
serialize_decimal,
serialize_float,
serialize_int,
stream_to_text,
stream_to_text_async,
stream_to_bytes,
stream_to_bytes_async,
validate_const,
validate_decimal,
validate_float,
validate_int,
validate_open_enum,
)
from .url import generate_url, template_url, remove_suffix
from .values import (
get_global_from_env,
match_content_type,
match_status_codes,
match_response,
cast_partial,
)
from .logger import Logger, get_body_content, get_default_logger
__all__ = [
"BackoffStrategy",
"FieldMetadata",
"find_metadata",
"FormMetadata",
"generate_url",
"get_body_content",
"get_default_logger",
"get_discriminator",
"parse_datetime",
"get_global_from_env",
"get_headers",
"get_pydantic_model",
"get_query_params",
"get_response_headers",
"get_security",
"get_security_from_env",
"HeaderMetadata",
"Logger",
"marshal_json",
"match_content_type",
"match_status_codes",
"match_response",
"MultipartFormMetadata",
"OpenEnumMeta",
"PathParamMetadata",
"QueryParamMetadata",
"remove_suffix",
"Retries",
"retry",
"retry_async",
"RetryConfig",
"RequestMetadata",
"SecurityMetadata",
"serialize_decimal",
"serialize_float",
"serialize_int",
"serialize_request_body",
"SerializedRequestBody",
"stream_to_text",
"stream_to_text_async",
"stream_to_bytes",
"stream_to_bytes_async",
"template_url",
"unmarshal",
"unmarshal_json",
"validate_decimal",
"validate_const",
"validate_float",
"validate_int",
"validate_open_enum",
"cast_partial",
]
_dynamic_imports: dict[str, str] = {
"BackoffStrategy": ".retries",
"FieldMetadata": ".metadata",
"find_metadata": ".metadata",
"FormMetadata": ".metadata",
"generate_url": ".url",
"get_body_content": ".logger",
"get_default_logger": ".logger",
"get_discriminator": ".annotations",
"parse_datetime": ".datetimes",
"get_global_from_env": ".values",
"get_headers": ".headers",
"get_pydantic_model": ".serializers",
"get_query_params": ".queryparams",
"get_response_headers": ".headers",
"get_security": ".security",
"get_security_from_env": ".security",
"HeaderMetadata": ".metadata",
"Logger": ".logger",
"marshal_json": ".serializers",
"match_content_type": ".values",
"match_status_codes": ".values",
"match_response": ".values",
"MultipartFormMetadata": ".metadata",
"OpenEnumMeta": ".enums",
"PathParamMetadata": ".metadata",
"QueryParamMetadata": ".metadata",
"remove_suffix": ".url",
"Retries": ".retries",
"retry": ".retries",
"retry_async": ".retries",
"RetryConfig": ".retries",
"RequestMetadata": ".metadata",
"SecurityMetadata": ".metadata",
"serialize_decimal": ".serializers",
"serialize_float": ".serializers",
"serialize_int": ".serializers",
"serialize_request_body": ".requestbodies",
"SerializedRequestBody": ".requestbodies",
"stream_to_text": ".serializers",
"stream_to_text_async": ".serializers",
"stream_to_bytes": ".serializers",
"stream_to_bytes_async": ".serializers",
"template_url": ".url",
"unmarshal": ".serializers",
"unmarshal_json": ".serializers",
"validate_decimal": ".serializers",
"validate_const": ".serializers",
"validate_float": ".serializers",
"validate_int": ".serializers",
"validate_open_enum": ".serializers",
"cast_partial": ".values",
}
def __getattr__(attr_name: str) -> object:
module_name = _dynamic_imports.get(attr_name)
if module_name is None:
raise AttributeError(
f"no {attr_name} found in _dynamic_imports, module name -> {__name__} "
)
try:
module = import_module(module_name, __package__)
result = getattr(module, attr_name)
return result
except ImportError as e:
raise ImportError(
f"Failed to import {attr_name} from {module_name}: {e}"
) from e
except AttributeError as e:
raise AttributeError(
f"Failed to get {attr_name} from {module_name}: {e}"
) from e
def __dir__():
lazy_attrs = builtins.list(_dynamic_imports.keys())
return builtins.sorted(lazy_attrs)
+55
View File
@@ -0,0 +1,55 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from enum import Enum
from typing import Any, Optional
def get_discriminator(model: Any, fieldname: str, key: str) -> str:
"""
Recursively search for the discriminator attribute in a model.
Args:
model (Any): The model to search within.
fieldname (str): The name of the field to search for.
key (str): The key to search for in dictionaries.
Returns:
str: The name of the discriminator attribute.
Raises:
ValueError: If the discriminator attribute is not found.
"""
upper_fieldname = fieldname.upper()
def get_field_discriminator(field: Any) -> Optional[str]:
"""Search for the discriminator attribute in a given field."""
if isinstance(field, dict):
if key in field:
return f'{field[key]}'
if hasattr(field, fieldname):
attr = getattr(field, fieldname)
if isinstance(attr, Enum):
return f'{attr.value}'
return f'{attr}'
if hasattr(field, upper_fieldname):
attr = getattr(field, upper_fieldname)
if isinstance(attr, Enum):
return f'{attr.value}'
return f'{attr}'
return None
if isinstance(model, list):
for field in model:
discriminator = get_field_discriminator(field)
if discriminator is not None:
return discriminator
discriminator = get_field_discriminator(model)
if discriminator is not None:
return discriminator
raise ValueError(f'Could not find discriminator field {fieldname} in {model}')
+23
View File
@@ -0,0 +1,23 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from datetime import datetime
import sys
def parse_datetime(datetime_string: str) -> datetime:
"""
Convert a RFC 3339 / ISO 8601 formatted string into a datetime object.
Python versions 3.11 and later support parsing RFC 3339 directly with
datetime.fromisoformat(), but for earlier versions, this function
encapsulates the necessary extra logic.
"""
# Python 3.11 and later can parse RFC 3339 directly
if sys.version_info >= (3, 11):
return datetime.fromisoformat(datetime_string)
# For Python 3.10 and earlier, a common ValueError is trailing 'Z' suffix,
# so fix that upfront.
if datetime_string.endswith("Z"):
datetime_string = datetime_string[:-1] + "+00:00"
return datetime.fromisoformat(datetime_string)
+74
View File
@@ -0,0 +1,74 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import enum
import sys
class OpenEnumMeta(enum.EnumMeta):
# The __call__ method `boundary` kwarg was added in 3.11 and must be present
# for pyright. Refer also: https://github.com/pylint-dev/pylint/issues/9622
# pylint: disable=unexpected-keyword-arg
# The __call__ method `values` varg must be named for pyright.
# pylint: disable=keyword-arg-before-vararg
if sys.version_info >= (3, 11):
def __call__(
cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None
):
# The `type` kwarg also happens to be a built-in that pylint flags as
# redeclared. Safe to ignore this lint rule with this scope.
# pylint: disable=redefined-builtin
if names is not None:
return super().__call__(
value,
names=names,
*values,
module=module,
qualname=qualname,
type=type,
start=start,
boundary=boundary,
)
try:
return super().__call__(
value,
names=names, # pyright: ignore[reportArgumentType]
*values,
module=module,
qualname=qualname,
type=type,
start=start,
boundary=boundary,
)
except ValueError:
return value
else:
def __call__(
cls, value, names=None, *, module=None, qualname=None, type=None, start=1
):
# The `type` kwarg also happens to be a built-in that pylint flags as
# redeclared. Safe to ignore this lint rule with this scope.
# pylint: disable=redefined-builtin
if names is not None:
return super().__call__(
value,
names=names,
module=module,
qualname=qualname,
type=type,
start=start,
)
try:
return super().__call__(
value,
names=names, # pyright: ignore[reportArgumentType]
module=module,
qualname=qualname,
type=type,
start=start,
)
except ValueError:
return value
+238
View File
@@ -0,0 +1,238 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import re
import json
from typing import (
Callable,
Generic,
TypeVar,
Optional,
Generator,
AsyncGenerator,
Tuple,
)
import httpx
T = TypeVar("T")
class EventStream(Generic[T]):
response: httpx.Response
generator: Generator[T, None, None]
def __init__(
self,
response: httpx.Response,
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
):
self.response = response
self.generator = stream_events(response, decoder, sentinel)
def __iter__(self):
return self
def __next__(self):
return next(self.generator)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.response.close()
class EventStreamAsync(Generic[T]):
response: httpx.Response
generator: AsyncGenerator[T, None]
def __init__(
self,
response: httpx.Response,
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
):
self.response = response
self.generator = stream_events_async(response, decoder, sentinel)
def __aiter__(self):
return self
async def __anext__(self):
return await self.generator.__anext__()
async def __aenter__(self):
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.response.aclose()
class ServerEvent:
id: Optional[str] = None
event: Optional[str] = None
data: Optional[str] = None
retry: Optional[int] = None
MESSAGE_BOUNDARIES = [
b"\r\n\r\n",
b"\n\n",
b"\r\r",
]
async def stream_events_async(
response: httpx.Response,
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
) -> AsyncGenerator[T, None]:
buffer = bytearray()
position = 0
discard = False
async for chunk in response.aiter_bytes():
# We've encountered the sentinel value and should no longer process
# incoming data. Instead we throw new data away until the server closes
# the connection.
if discard:
continue
buffer += chunk
for i in range(position, len(buffer)):
char = buffer[i : i + 1]
seq: Optional[bytes] = None
if char in [b"\r", b"\n"]:
for boundary in MESSAGE_BOUNDARIES:
seq = _peek_sequence(i, buffer, boundary)
if seq is not None:
break
if seq is None:
continue
block = buffer[position:i]
position = i + len(seq)
event, discard = _parse_event(block, decoder, sentinel)
if event is not None:
yield event
if position > 0:
buffer = buffer[position:]
position = 0
event, discard = _parse_event(buffer, decoder, sentinel)
if event is not None:
yield event
def stream_events(
response: httpx.Response,
decoder: Callable[[str], T],
sentinel: Optional[str] = None,
) -> Generator[T, None, None]:
buffer = bytearray()
position = 0
discard = False
for chunk in response.iter_bytes():
# We've encountered the sentinel value and should no longer process
# incoming data. Instead we throw new data away until the server closes
# the connection.
if discard:
continue
buffer += chunk
for i in range(position, len(buffer)):
char = buffer[i : i + 1]
seq: Optional[bytes] = None
if char in [b"\r", b"\n"]:
for boundary in MESSAGE_BOUNDARIES:
seq = _peek_sequence(i, buffer, boundary)
if seq is not None:
break
if seq is None:
continue
block = buffer[position:i]
position = i + len(seq)
event, discard = _parse_event(block, decoder, sentinel)
if event is not None:
yield event
if position > 0:
buffer = buffer[position:]
position = 0
event, discard = _parse_event(buffer, decoder, sentinel)
if event is not None:
yield event
def _parse_event(
raw: bytearray, decoder: Callable[[str], T], sentinel: Optional[str] = None
) -> Tuple[Optional[T], bool]:
block = raw.decode()
lines = re.split(r"\r?\n|\r", block)
publish = False
event = ServerEvent()
data = ""
for line in lines:
if not line:
continue
delim = line.find(":")
if delim <= 0:
continue
field = line[0:delim]
value = line[delim + 1 :] if delim < len(line) - 1 else ""
if len(value) and value[0] == " ":
value = value[1:]
if field == "event":
event.event = value
publish = True
elif field == "data":
data += value + "\n"
publish = True
elif field == "id":
event.id = value
publish = True
elif field == "retry":
event.retry = int(value) if value.isdigit() else None
publish = True
if sentinel and data == f"{sentinel}\n":
return None, True
if data:
data = data[:-1]
event.data = data
data_is_primitive = (
data.isnumeric() or data == "true" or data == "false" or data == "null"
)
data_is_json = (
data.startswith("{") or data.startswith("[") or data.startswith('"')
)
if data_is_primitive or data_is_json:
try:
event.data = json.loads(data)
except Exception:
pass
out = None
if publish:
out = decoder(json.dumps(event.__dict__))
return out, False
def _peek_sequence(position: int, buffer: bytearray, sequence: bytes):
if len(sequence) > (len(buffer) - position):
return None
for i, seq in enumerate(sequence):
if buffer[position + i] != seq:
return None
return sequence
+223
View File
@@ -0,0 +1,223 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import (
Any,
Dict,
get_type_hints,
List,
Tuple,
)
from pydantic import BaseModel
from pydantic.fields import FieldInfo
from .serializers import marshal_json
from .metadata import (
FormMetadata,
MultipartFormMetadata,
find_field_metadata,
)
from .values import _is_set, _val_to_string
def _populate_form(
field_name: str,
explode: bool,
obj: Any,
delimiter: str,
form: Dict[str, List[str]],
):
if not _is_set(obj):
return form
if isinstance(obj, BaseModel):
items = []
obj_fields: Dict[str, FieldInfo] = obj.__class__.model_fields
for name in obj_fields:
obj_field = obj_fields[name]
obj_field_name = obj_field.alias if obj_field.alias is not None else name
if obj_field_name == "":
continue
val = getattr(obj, name)
if not _is_set(val):
continue
if explode:
form[obj_field_name] = [_val_to_string(val)]
else:
items.append(f"{obj_field_name}{delimiter}{_val_to_string(val)}")
if len(items) > 0:
form[field_name] = [delimiter.join(items)]
elif isinstance(obj, Dict):
items = []
for key, value in obj.items():
if not _is_set(value):
continue
if explode:
form[key] = [_val_to_string(value)]
else:
items.append(f"{key}{delimiter}{_val_to_string(value)}")
if len(items) > 0:
form[field_name] = [delimiter.join(items)]
elif isinstance(obj, List):
items = []
for value in obj:
if not _is_set(value):
continue
if explode:
if not field_name in form:
form[field_name] = []
form[field_name].append(_val_to_string(value))
else:
items.append(_val_to_string(value))
if len(items) > 0:
form[field_name] = [delimiter.join([str(item) for item in items])]
else:
form[field_name] = [_val_to_string(obj)]
return form
def _extract_file_properties(file_obj: Any) -> Tuple[str, Any, Any]:
"""Extract file name, content, and content type from a file object."""
file_fields: Dict[str, FieldInfo] = file_obj.__class__.model_fields
file_name = ""
content = None
content_type = None
for file_field_name in file_fields:
file_field = file_fields[file_field_name]
file_metadata = find_field_metadata(file_field, MultipartFormMetadata)
if file_metadata is None:
continue
if file_metadata.content:
content = getattr(file_obj, file_field_name, None)
elif file_field_name == "content_type":
content_type = getattr(file_obj, file_field_name, None)
else:
file_name = getattr(file_obj, file_field_name)
if file_name == "" or content is None:
raise ValueError("invalid multipart/form-data file")
return file_name, content, content_type
def serialize_multipart_form(
media_type: str, request: Any
) -> Tuple[str, Dict[str, Any], List[Tuple[str, Any]]]:
form: Dict[str, Any] = {}
files: List[Tuple[str, Any]] = []
if not isinstance(request, BaseModel):
raise TypeError("invalid request body type")
request_fields: Dict[str, FieldInfo] = request.__class__.model_fields
request_field_types = get_type_hints(request.__class__)
for name in request_fields:
field = request_fields[name]
val = getattr(request, name)
if not _is_set(val):
continue
field_metadata = find_field_metadata(field, MultipartFormMetadata)
if not field_metadata:
continue
f_name = field.alias if field.alias else name
if field_metadata.file:
if isinstance(val, List):
# Handle array of files
for file_obj in val:
if not _is_set(file_obj):
continue
file_name, content, content_type = _extract_file_properties(file_obj)
if content_type is not None:
files.append((f_name + "[]", (file_name, content, content_type)))
else:
files.append((f_name + "[]", (file_name, content)))
else:
# Handle single file
file_name, content, content_type = _extract_file_properties(val)
if content_type is not None:
files.append((f_name, (file_name, content, content_type)))
else:
files.append((f_name, (file_name, content)))
elif field_metadata.json:
files.append((f_name, (
None,
marshal_json(val, request_field_types[name]),
"application/json",
)))
else:
if isinstance(val, List):
values = []
for value in val:
if not _is_set(value):
continue
values.append(_val_to_string(value))
form[f_name + "[]"] = values
else:
form[f_name] = _val_to_string(val)
return media_type, form, files
def serialize_form_data(data: Any) -> Dict[str, Any]:
form: Dict[str, List[str]] = {}
if isinstance(data, BaseModel):
data_fields: Dict[str, FieldInfo] = data.__class__.model_fields
data_field_types = get_type_hints(data.__class__)
for name in data_fields:
field = data_fields[name]
val = getattr(data, name)
if not _is_set(val):
continue
metadata = find_field_metadata(field, FormMetadata)
if metadata is None:
continue
f_name = field.alias if field.alias is not None else name
if metadata.json:
form[f_name] = [marshal_json(val, data_field_types[name])]
else:
if metadata.style == "form":
_populate_form(
f_name,
metadata.explode,
val,
",",
form,
)
else:
raise ValueError(f"Invalid form style for field {name}")
elif isinstance(data, Dict):
for key, value in data.items():
if _is_set(value):
form[key] = [_val_to_string(value)]
else:
raise TypeError(f"Invalid request body type {type(data)} for form data")
return form
+136
View File
@@ -0,0 +1,136 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import (
Any,
Dict,
List,
Optional,
)
from httpx import Headers
from pydantic import BaseModel
from pydantic.fields import FieldInfo
from .metadata import (
HeaderMetadata,
find_field_metadata,
)
from .values import _is_set, _populate_from_globals, _val_to_string
def get_headers(headers_params: Any, gbls: Optional[Any] = None) -> Dict[str, str]:
headers: Dict[str, str] = {}
globals_already_populated = []
if _is_set(headers_params):
globals_already_populated = _populate_headers(headers_params, gbls, headers, [])
if _is_set(gbls):
_populate_headers(gbls, None, headers, globals_already_populated)
return headers
def _populate_headers(
headers_params: Any,
gbls: Any,
header_values: Dict[str, str],
skip_fields: List[str],
) -> List[str]:
globals_already_populated: List[str] = []
if not isinstance(headers_params, BaseModel):
return globals_already_populated
param_fields: Dict[str, FieldInfo] = headers_params.__class__.model_fields
for name in param_fields:
if name in skip_fields:
continue
field = param_fields[name]
f_name = field.alias if field.alias is not None else name
metadata = find_field_metadata(field, HeaderMetadata)
if metadata is None:
continue
value, global_found = _populate_from_globals(
name, getattr(headers_params, name), HeaderMetadata, gbls
)
if global_found:
globals_already_populated.append(name)
value = _serialize_header(metadata.explode, value)
if value != "":
header_values[f_name] = value
return globals_already_populated
def _serialize_header(explode: bool, obj: Any) -> str:
if not _is_set(obj):
return ""
if isinstance(obj, BaseModel):
items = []
obj_fields: Dict[str, FieldInfo] = obj.__class__.model_fields
for name in obj_fields:
obj_field = obj_fields[name]
obj_param_metadata = find_field_metadata(obj_field, HeaderMetadata)
if not obj_param_metadata:
continue
f_name = obj_field.alias if obj_field.alias is not None else name
val = getattr(obj, name)
if not _is_set(val):
continue
if explode:
items.append(f"{f_name}={_val_to_string(val)}")
else:
items.append(f_name)
items.append(_val_to_string(val))
if len(items) > 0:
return ",".join(items)
elif isinstance(obj, Dict):
items = []
for key, value in obj.items():
if not _is_set(value):
continue
if explode:
items.append(f"{key}={_val_to_string(value)}")
else:
items.append(key)
items.append(_val_to_string(value))
if len(items) > 0:
return ",".join([str(item) for item in items])
elif isinstance(obj, List):
items = []
for value in obj:
if not _is_set(value):
continue
items.append(_val_to_string(value))
if len(items) > 0:
return ",".join(items)
elif _is_set(obj):
return f"{_val_to_string(obj)}"
return ""
def get_response_headers(headers: Headers) -> Dict[str, List[str]]:
res: Dict[str, List[str]] = {}
for k, v in headers.items():
if not k in res:
res[k] = []
res[k].append(v)
return res
+27
View File
@@ -0,0 +1,27 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import httpx
import logging
import os
from typing import Any, Protocol
class Logger(Protocol):
def debug(self, msg: str, *args: Any, **kwargs: Any) -> None:
pass
class NoOpLogger:
def debug(self, msg: str, *args: Any, **kwargs: Any) -> None:
pass
def get_body_content(req: httpx.Request) -> str:
return "<streaming body>" if not hasattr(req, "_content") else str(req.content)
def get_default_logger() -> Logger:
if os.getenv("OPENROUTER_DEBUG"):
logging.basicConfig(level=logging.DEBUG)
return logging.getLogger("openrouter")
return NoOpLogger()
+118
View File
@@ -0,0 +1,118 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import Optional, Type, TypeVar, Union
from dataclasses import dataclass
from pydantic.fields import FieldInfo
T = TypeVar("T")
@dataclass
class SecurityMetadata:
option: bool = False
scheme: bool = False
scheme_type: Optional[str] = None
sub_type: Optional[str] = None
field_name: Optional[str] = None
def get_field_name(self, default: str) -> str:
return self.field_name or default
@dataclass
class ParamMetadata:
serialization: Optional[str] = None
style: str = "simple"
explode: bool = False
@dataclass
class PathParamMetadata(ParamMetadata):
pass
@dataclass
class QueryParamMetadata(ParamMetadata):
style: str = "form"
explode: bool = True
@dataclass
class HeaderMetadata(ParamMetadata):
pass
@dataclass
class RequestMetadata:
media_type: str = "application/octet-stream"
@dataclass
class MultipartFormMetadata:
file: bool = False
content: bool = False
json: bool = False
@dataclass
class FormMetadata:
json: bool = False
style: str = "form"
explode: bool = True
class FieldMetadata:
security: Optional[SecurityMetadata] = None
path: Optional[PathParamMetadata] = None
query: Optional[QueryParamMetadata] = None
header: Optional[HeaderMetadata] = None
request: Optional[RequestMetadata] = None
form: Optional[FormMetadata] = None
multipart: Optional[MultipartFormMetadata] = None
def __init__(
self,
security: Optional[SecurityMetadata] = None,
path: Optional[Union[PathParamMetadata, bool]] = None,
query: Optional[Union[QueryParamMetadata, bool]] = None,
header: Optional[Union[HeaderMetadata, bool]] = None,
request: Optional[Union[RequestMetadata, bool]] = None,
form: Optional[Union[FormMetadata, bool]] = None,
multipart: Optional[Union[MultipartFormMetadata, bool]] = None,
):
self.security = security
self.path = PathParamMetadata() if isinstance(path, bool) else path
self.query = QueryParamMetadata() if isinstance(query, bool) else query
self.header = HeaderMetadata() if isinstance(header, bool) else header
self.request = RequestMetadata() if isinstance(request, bool) else request
self.form = FormMetadata() if isinstance(form, bool) else form
self.multipart = (
MultipartFormMetadata() if isinstance(multipart, bool) else multipart
)
def find_field_metadata(field_info: FieldInfo, metadata_type: Type[T]) -> Optional[T]:
metadata = find_metadata(field_info, FieldMetadata)
if not metadata:
return None
fields = metadata.__dict__
for field in fields:
if isinstance(fields[field], metadata_type):
return fields[field]
return None
def find_metadata(field_info: FieldInfo, metadata_type: Type[T]) -> Optional[T]:
metadata = field_info.metadata
if not metadata:
return None
for md in metadata:
if isinstance(md, metadata_type):
return md
return None
+205
View File
@@ -0,0 +1,205 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import (
Any,
Dict,
get_type_hints,
List,
Optional,
)
from pydantic import BaseModel
from pydantic.fields import FieldInfo
from .metadata import (
QueryParamMetadata,
find_field_metadata,
)
from .values import (
_get_serialized_params,
_is_set,
_populate_from_globals,
_val_to_string,
)
from .forms import _populate_form
def get_query_params(
query_params: Any,
gbls: Optional[Any] = None,
) -> Dict[str, List[str]]:
params: Dict[str, List[str]] = {}
globals_already_populated = _populate_query_params(query_params, gbls, params, [])
if _is_set(gbls):
_populate_query_params(gbls, None, params, globals_already_populated)
return params
def _populate_query_params(
query_params: Any,
gbls: Any,
query_param_values: Dict[str, List[str]],
skip_fields: List[str],
) -> List[str]:
globals_already_populated: List[str] = []
if not isinstance(query_params, BaseModel):
return globals_already_populated
param_fields: Dict[str, FieldInfo] = query_params.__class__.model_fields
param_field_types = get_type_hints(query_params.__class__)
for name in param_fields:
if name in skip_fields:
continue
field = param_fields[name]
metadata = find_field_metadata(field, QueryParamMetadata)
if not metadata:
continue
value = getattr(query_params, name) if _is_set(query_params) else None
value, global_found = _populate_from_globals(
name, value, QueryParamMetadata, gbls
)
if global_found:
globals_already_populated.append(name)
f_name = field.alias if field.alias is not None else name
serialization = metadata.serialization
if serialization is not None:
serialized_parms = _get_serialized_params(
metadata, f_name, value, param_field_types[name]
)
for key, value in serialized_parms.items():
if key in query_param_values:
query_param_values[key].extend(value)
else:
query_param_values[key] = [value]
else:
style = metadata.style
if style == "deepObject":
_populate_deep_object_query_params(f_name, value, query_param_values)
elif style == "form":
_populate_delimited_query_params(
metadata, f_name, value, ",", query_param_values
)
elif style == "pipeDelimited":
_populate_delimited_query_params(
metadata, f_name, value, "|", query_param_values
)
else:
raise NotImplementedError(
f"query param style {style} not yet supported"
)
return globals_already_populated
def _populate_deep_object_query_params(
field_name: str,
obj: Any,
params: Dict[str, List[str]],
):
if not _is_set(obj):
return
if isinstance(obj, BaseModel):
_populate_deep_object_query_params_basemodel(field_name, obj, params)
elif isinstance(obj, Dict):
_populate_deep_object_query_params_dict(field_name, obj, params)
def _populate_deep_object_query_params_basemodel(
prior_params_key: str,
obj: Any,
params: Dict[str, List[str]],
):
if not _is_set(obj) or not isinstance(obj, BaseModel):
return
obj_fields: Dict[str, FieldInfo] = obj.__class__.model_fields
for name in obj_fields:
obj_field = obj_fields[name]
f_name = obj_field.alias if obj_field.alias is not None else name
params_key = f"{prior_params_key}[{f_name}]"
obj_param_metadata = find_field_metadata(obj_field, QueryParamMetadata)
if not _is_set(obj_param_metadata):
continue
obj_val = getattr(obj, name)
if not _is_set(obj_val):
continue
if isinstance(obj_val, BaseModel):
_populate_deep_object_query_params_basemodel(params_key, obj_val, params)
elif isinstance(obj_val, Dict):
_populate_deep_object_query_params_dict(params_key, obj_val, params)
elif isinstance(obj_val, List):
_populate_deep_object_query_params_list(params_key, obj_val, params)
else:
params[params_key] = [_val_to_string(obj_val)]
def _populate_deep_object_query_params_dict(
prior_params_key: str,
value: Dict,
params: Dict[str, List[str]],
):
if not _is_set(value):
return
for key, val in value.items():
if not _is_set(val):
continue
params_key = f"{prior_params_key}[{key}]"
if isinstance(val, BaseModel):
_populate_deep_object_query_params_basemodel(params_key, val, params)
elif isinstance(val, Dict):
_populate_deep_object_query_params_dict(params_key, val, params)
elif isinstance(val, List):
_populate_deep_object_query_params_list(params_key, val, params)
else:
params[params_key] = [_val_to_string(val)]
def _populate_deep_object_query_params_list(
params_key: str,
value: List,
params: Dict[str, List[str]],
):
if not _is_set(value):
return
for val in value:
if not _is_set(val):
continue
if params.get(params_key) is None:
params[params_key] = []
params[params_key].append(_val_to_string(val))
def _populate_delimited_query_params(
metadata: QueryParamMetadata,
field_name: str,
obj: Any,
delimiter: str,
query_param_values: Dict[str, List[str]],
):
_populate_form(
field_name,
metadata.explode,
obj,
delimiter,
query_param_values,
)
+66
View File
@@ -0,0 +1,66 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import io
from dataclasses import dataclass
import re
from typing import (
Any,
Optional,
)
from .forms import serialize_form_data, serialize_multipart_form
from .serializers import marshal_json
SERIALIZATION_METHOD_TO_CONTENT_TYPE = {
"json": "application/json",
"form": "application/x-www-form-urlencoded",
"multipart": "multipart/form-data",
"raw": "application/octet-stream",
"string": "text/plain",
}
@dataclass
class SerializedRequestBody:
media_type: Optional[str] = None
content: Optional[Any] = None
data: Optional[Any] = None
files: Optional[Any] = None
def serialize_request_body(
request_body: Any,
nullable: bool,
optional: bool,
serialization_method: str,
request_body_type,
) -> Optional[SerializedRequestBody]:
if request_body is None:
if not nullable and optional:
return None
media_type = SERIALIZATION_METHOD_TO_CONTENT_TYPE[serialization_method]
serialized_request_body = SerializedRequestBody(media_type)
if re.match(r"(application|text)\/.*?\+*json.*", media_type) is not None:
serialized_request_body.content = marshal_json(request_body, request_body_type)
elif re.match(r"multipart\/.*", media_type) is not None:
(
serialized_request_body.media_type,
serialized_request_body.data,
serialized_request_body.files,
) = serialize_multipart_form(media_type, request_body)
elif re.match(r"application\/x-www-form-urlencoded.*", media_type) is not None:
serialized_request_body.data = serialize_form_data(request_body)
elif isinstance(request_body, (bytes, bytearray, io.BytesIO, io.BufferedReader)):
serialized_request_body.content = request_body
elif isinstance(request_body, str):
serialized_request_body.content = request_body
else:
raise TypeError(
f"invalid request body type {type(request_body)} for mediaType {media_type}"
)
return serialized_request_body
+217
View File
@@ -0,0 +1,217 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import asyncio
import random
import time
from typing import List
import httpx
class BackoffStrategy:
initial_interval: int
max_interval: int
exponent: float
max_elapsed_time: int
def __init__(
self,
initial_interval: int,
max_interval: int,
exponent: float,
max_elapsed_time: int,
):
self.initial_interval = initial_interval
self.max_interval = max_interval
self.exponent = exponent
self.max_elapsed_time = max_elapsed_time
class RetryConfig:
strategy: str
backoff: BackoffStrategy
retry_connection_errors: bool
def __init__(
self, strategy: str, backoff: BackoffStrategy, retry_connection_errors: bool
):
self.strategy = strategy
self.backoff = backoff
self.retry_connection_errors = retry_connection_errors
class Retries:
config: RetryConfig
status_codes: List[str]
def __init__(self, config: RetryConfig, status_codes: List[str]):
self.config = config
self.status_codes = status_codes
class TemporaryError(Exception):
response: httpx.Response
def __init__(self, response: httpx.Response):
self.response = response
class PermanentError(Exception):
inner: Exception
def __init__(self, inner: Exception):
self.inner = inner
def retry(func, retries: Retries):
if retries.config.strategy == "backoff":
def do_request() -> httpx.Response:
res: httpx.Response
try:
res = func()
for code in retries.status_codes:
if "X" in code.upper():
code_range = int(code[0])
status_major = res.status_code / 100
if code_range <= status_major < code_range + 1:
raise TemporaryError(res)
else:
parsed_code = int(code)
if res.status_code == parsed_code:
raise TemporaryError(res)
except httpx.ConnectError as exception:
if retries.config.retry_connection_errors:
raise
raise PermanentError(exception) from exception
except httpx.TimeoutException as exception:
if retries.config.retry_connection_errors:
raise
raise PermanentError(exception) from exception
except TemporaryError:
raise
except Exception as exception:
raise PermanentError(exception) from exception
return res
return retry_with_backoff(
do_request,
retries.config.backoff.initial_interval,
retries.config.backoff.max_interval,
retries.config.backoff.exponent,
retries.config.backoff.max_elapsed_time,
)
return func()
async def retry_async(func, retries: Retries):
if retries.config.strategy == "backoff":
async def do_request() -> httpx.Response:
res: httpx.Response
try:
res = await func()
for code in retries.status_codes:
if "X" in code.upper():
code_range = int(code[0])
status_major = res.status_code / 100
if code_range <= status_major < code_range + 1:
raise TemporaryError(res)
else:
parsed_code = int(code)
if res.status_code == parsed_code:
raise TemporaryError(res)
except httpx.ConnectError as exception:
if retries.config.retry_connection_errors:
raise
raise PermanentError(exception) from exception
except httpx.TimeoutException as exception:
if retries.config.retry_connection_errors:
raise
raise PermanentError(exception) from exception
except TemporaryError:
raise
except Exception as exception:
raise PermanentError(exception) from exception
return res
return await retry_with_backoff_async(
do_request,
retries.config.backoff.initial_interval,
retries.config.backoff.max_interval,
retries.config.backoff.exponent,
retries.config.backoff.max_elapsed_time,
)
return await func()
def retry_with_backoff(
func,
initial_interval=500,
max_interval=60000,
exponent=1.5,
max_elapsed_time=3600000,
):
start = round(time.time() * 1000)
retries = 0
while True:
try:
return func()
except PermanentError as exception:
raise exception.inner
except Exception as exception: # pylint: disable=broad-exception-caught
now = round(time.time() * 1000)
if now - start > max_elapsed_time:
if isinstance(exception, TemporaryError):
return exception.response
raise
sleep = (initial_interval / 1000) * exponent**retries + random.uniform(0, 1)
sleep = min(sleep, max_interval / 1000)
time.sleep(sleep)
retries += 1
async def retry_with_backoff_async(
func,
initial_interval=500,
max_interval=60000,
exponent=1.5,
max_elapsed_time=3600000,
):
start = round(time.time() * 1000)
retries = 0
while True:
try:
return await func()
except PermanentError as exception:
raise exception.inner
except Exception as exception: # pylint: disable=broad-exception-caught
now = round(time.time() * 1000)
if now - start > max_elapsed_time:
if isinstance(exception, TemporaryError):
return exception.response
raise
sleep = (initial_interval / 1000) * exponent**retries + random.uniform(0, 1)
sleep = min(sleep, max_interval / 1000)
await asyncio.sleep(sleep)
retries += 1
+192
View File
@@ -0,0 +1,192 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
import base64
from typing import (
Any,
Dict,
List,
Optional,
Tuple,
)
from pydantic import BaseModel
from pydantic.fields import FieldInfo
from .metadata import (
SecurityMetadata,
find_field_metadata,
)
import os
def get_security(security: Any) -> Tuple[Dict[str, str], Dict[str, List[str]]]:
headers: Dict[str, str] = {}
query_params: Dict[str, List[str]] = {}
if security is None:
return headers, query_params
if not isinstance(security, BaseModel):
raise TypeError("security must be a pydantic model")
sec_fields: Dict[str, FieldInfo] = security.__class__.model_fields
for name in sec_fields:
sec_field = sec_fields[name]
value = getattr(security, name)
if value is None:
continue
metadata = find_field_metadata(sec_field, SecurityMetadata)
if metadata is None:
continue
if metadata.option:
_parse_security_option(headers, query_params, value)
return headers, query_params
if metadata.scheme:
# Special case for basic auth or custom auth which could be a flattened model
if metadata.sub_type in ["basic", "custom"] and not isinstance(
value, BaseModel
):
_parse_security_scheme(headers, query_params, metadata, name, security)
else:
_parse_security_scheme(headers, query_params, metadata, name, value)
return headers, query_params
def get_security_from_env(security: Any, security_class: Any) -> Optional[BaseModel]:
if security is not None:
return security
if not issubclass(security_class, BaseModel):
raise TypeError("security_class must be a pydantic model class")
security_dict: Any = {}
if os.getenv("OPENROUTER_BEARER_AUTH"):
security_dict["bearer_auth"] = os.getenv("OPENROUTER_BEARER_AUTH")
return security_class(**security_dict) if security_dict else None
def _parse_security_option(
headers: Dict[str, str], query_params: Dict[str, List[str]], option: Any
):
if not isinstance(option, BaseModel):
raise TypeError("security option must be a pydantic model")
opt_fields: Dict[str, FieldInfo] = option.__class__.model_fields
for name in opt_fields:
opt_field = opt_fields[name]
metadata = find_field_metadata(opt_field, SecurityMetadata)
if metadata is None or not metadata.scheme:
continue
_parse_security_scheme(
headers, query_params, metadata, name, getattr(option, name)
)
def _parse_security_scheme(
headers: Dict[str, str],
query_params: Dict[str, List[str]],
scheme_metadata: SecurityMetadata,
field_name: str,
scheme: Any,
):
scheme_type = scheme_metadata.scheme_type
sub_type = scheme_metadata.sub_type
if isinstance(scheme, BaseModel):
if scheme_type == "http":
if sub_type == "basic":
_parse_basic_auth_scheme(headers, scheme)
return
if sub_type == "custom":
return
scheme_fields: Dict[str, FieldInfo] = scheme.__class__.model_fields
for name in scheme_fields:
scheme_field = scheme_fields[name]
metadata = find_field_metadata(scheme_field, SecurityMetadata)
if metadata is None or metadata.field_name is None:
continue
value = getattr(scheme, name)
_parse_security_scheme_value(
headers, query_params, scheme_metadata, metadata, name, value
)
else:
_parse_security_scheme_value(
headers, query_params, scheme_metadata, scheme_metadata, field_name, scheme
)
def _parse_security_scheme_value(
headers: Dict[str, str],
query_params: Dict[str, List[str]],
scheme_metadata: SecurityMetadata,
security_metadata: SecurityMetadata,
field_name: str,
value: Any,
):
scheme_type = scheme_metadata.scheme_type
sub_type = scheme_metadata.sub_type
header_name = security_metadata.get_field_name(field_name)
if scheme_type == "apiKey":
if sub_type == "header":
headers[header_name] = value
elif sub_type == "query":
query_params[header_name] = [value]
else:
raise ValueError("sub type {sub_type} not supported")
elif scheme_type == "openIdConnect":
headers[header_name] = _apply_bearer(value)
elif scheme_type == "oauth2":
if sub_type != "client_credentials":
headers[header_name] = _apply_bearer(value)
elif scheme_type == "http":
if sub_type == "bearer":
headers[header_name] = _apply_bearer(value)
elif sub_type == "custom":
return
else:
raise ValueError("sub type {sub_type} not supported")
else:
raise ValueError("scheme type {scheme_type} not supported")
def _apply_bearer(token: str) -> str:
return token.lower().startswith("bearer ") and token or f"Bearer {token}"
def _parse_basic_auth_scheme(headers: Dict[str, str], scheme: Any):
username = ""
password = ""
if not isinstance(scheme, BaseModel):
raise TypeError("basic auth scheme must be a pydantic model")
scheme_fields: Dict[str, FieldInfo] = scheme.__class__.model_fields
for name in scheme_fields:
scheme_field = scheme_fields[name]
metadata = find_field_metadata(scheme_field, SecurityMetadata)
if metadata is None or metadata.field_name is None:
continue
field_name = metadata.field_name
value = getattr(scheme, name)
if field_name == "username":
username = value
if field_name == "password":
password = value
data = f"{username}:{password}".encode()
headers["Authorization"] = f"Basic {base64.b64encode(data).decode()}"
+249
View File
@@ -0,0 +1,249 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from decimal import Decimal
import functools
import json
import typing
from typing import Any, Dict, List, Tuple, Union, get_args
import typing_extensions
from typing_extensions import get_origin
import httpx
from pydantic import ConfigDict, create_model
from pydantic_core import from_json
from ..types.basemodel import BaseModel, Nullable, OptionalNullable, Unset
def serialize_decimal(as_str: bool):
def serialize(d):
# Optional[T] is a Union[T, None]
if is_union(type(d)) and type(None) in get_args(type(d)) and d is None:
return None
if isinstance(d, Unset):
return d
if not isinstance(d, Decimal):
raise ValueError("Expected Decimal object")
return str(d) if as_str else float(d)
return serialize
def validate_decimal(d):
if d is None:
return None
if isinstance(d, (Decimal, Unset)):
return d
if not isinstance(d, (str, int, float)):
raise ValueError("Expected string, int or float")
return Decimal(str(d))
def serialize_float(as_str: bool):
def serialize(f):
# Optional[T] is a Union[T, None]
if is_union(type(f)) and type(None) in get_args(type(f)) and f is None:
return None
if isinstance(f, Unset):
return f
if not isinstance(f, float):
raise ValueError("Expected float")
return str(f) if as_str else f
return serialize
def validate_float(f):
if f is None:
return None
if isinstance(f, (float, Unset)):
return f
if not isinstance(f, str):
raise ValueError("Expected string")
return float(f)
def serialize_int(as_str: bool):
def serialize(i):
# Optional[T] is a Union[T, None]
if is_union(type(i)) and type(None) in get_args(type(i)) and i is None:
return None
if isinstance(i, Unset):
return i
if not isinstance(i, int):
raise ValueError("Expected int")
return str(i) if as_str else i
return serialize
def validate_int(b):
if b is None:
return None
if isinstance(b, (int, Unset)):
return b
if not isinstance(b, str):
raise ValueError("Expected string")
return int(b)
def validate_open_enum(is_int: bool):
def validate(e):
if e is None:
return None
if isinstance(e, Unset):
return e
if is_int:
if not isinstance(e, int):
raise ValueError("Expected int")
else:
if not isinstance(e, str):
raise ValueError("Expected string")
return e
return validate
def validate_const(v):
def validate(c):
# Optional[T] is a Union[T, None]
if is_union(type(c)) and type(None) in get_args(type(c)) and c is None:
return None
if v != c:
raise ValueError(f"Expected {v}")
return c
return validate
def unmarshal_json(raw, typ: Any) -> Any:
return unmarshal(from_json(raw), typ)
def unmarshal(val, typ: Any) -> Any:
unmarshaller = create_model(
"Unmarshaller",
body=(typ, ...),
__config__=ConfigDict(populate_by_name=True, arbitrary_types_allowed=True),
)
m = unmarshaller(body=val)
# pyright: ignore[reportAttributeAccessIssue]
return m.body # type: ignore
def marshal_json(val, typ):
if is_nullable(typ) and val is None:
return "null"
marshaller = create_model(
"Marshaller",
body=(typ, ...),
__config__=ConfigDict(populate_by_name=True, arbitrary_types_allowed=True),
)
m = marshaller(body=val)
d = m.model_dump(by_alias=True, mode="json", exclude_none=True)
if len(d) == 0:
return ""
return json.dumps(d[next(iter(d))], separators=(",", ":"))
def is_nullable(field):
origin = get_origin(field)
if origin is Nullable or origin is OptionalNullable:
return True
if not origin is Union or type(None) not in get_args(field):
return False
for arg in get_args(field):
if get_origin(arg) is Nullable or get_origin(arg) is OptionalNullable:
return True
return False
def is_union(obj: object) -> bool:
"""
Returns True if the given object is a typing.Union or typing_extensions.Union.
"""
return any(
obj is typing_obj for typing_obj in _get_typing_objects_by_name_of("Union")
)
def stream_to_text(stream: httpx.Response) -> str:
return "".join(stream.iter_text())
async def stream_to_text_async(stream: httpx.Response) -> str:
return "".join([chunk async for chunk in stream.aiter_text()])
def stream_to_bytes(stream: httpx.Response) -> bytes:
return stream.content
async def stream_to_bytes_async(stream: httpx.Response) -> bytes:
return await stream.aread()
def get_pydantic_model(data: Any, typ: Any) -> Any:
if not _contains_pydantic_model(data):
return unmarshal(data, typ)
return data
def _contains_pydantic_model(data: Any) -> bool:
if isinstance(data, BaseModel):
return True
if isinstance(data, List):
return any(_contains_pydantic_model(item) for item in data)
if isinstance(data, Dict):
return any(_contains_pydantic_model(value) for value in data.values())
return False
@functools.cache
def _get_typing_objects_by_name_of(name: str) -> Tuple[Any, ...]:
"""
Get typing objects by name from typing and typing_extensions.
Reference: https://typing-extensions.readthedocs.io/en/latest/#runtime-use-of-types
"""
result = tuple(
getattr(module, name)
for module in (typing, typing_extensions)
if hasattr(module, name)
)
if not result:
raise ValueError(
f"Neither typing nor typing_extensions has an object called {name!r}"
)
return result
@@ -0,0 +1,24 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from typing import Any, Optional
import httpx
from .serializers import unmarshal_json
from openrouter import errors
def unmarshal_json_response(
typ: Any, http_res: httpx.Response, body: Optional[str] = None
) -> Any:
if body is None:
body = http_res.text
try:
return unmarshal_json(body, typ)
except Exception as e:
raise errors.ResponseValidationError(
"Response validation failed",
http_res,
e,
body,
) from e
+155
View File
@@ -0,0 +1,155 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from decimal import Decimal
from typing import (
Any,
Dict,
get_type_hints,
List,
Optional,
Union,
get_args,
get_origin,
)
from pydantic import BaseModel
from pydantic.fields import FieldInfo
from .metadata import (
PathParamMetadata,
find_field_metadata,
)
from .values import (
_get_serialized_params,
_is_set,
_populate_from_globals,
_val_to_string,
)
def generate_url(
server_url: str,
path: str,
path_params: Any,
gbls: Optional[Any] = None,
) -> str:
path_param_values: Dict[str, str] = {}
globals_already_populated = _populate_path_params(
path_params, gbls, path_param_values, []
)
if _is_set(gbls):
_populate_path_params(gbls, None, path_param_values, globals_already_populated)
for key, value in path_param_values.items():
path = path.replace("{" + key + "}", value, 1)
return remove_suffix(server_url, "/") + path
def _populate_path_params(
path_params: Any,
gbls: Any,
path_param_values: Dict[str, str],
skip_fields: List[str],
) -> List[str]:
globals_already_populated: List[str] = []
if not isinstance(path_params, BaseModel):
return globals_already_populated
path_param_fields: Dict[str, FieldInfo] = path_params.__class__.model_fields
path_param_field_types = get_type_hints(path_params.__class__)
for name in path_param_fields:
if name in skip_fields:
continue
field = path_param_fields[name]
param_metadata = find_field_metadata(field, PathParamMetadata)
if param_metadata is None:
continue
param = getattr(path_params, name) if _is_set(path_params) else None
param, global_found = _populate_from_globals(
name, param, PathParamMetadata, gbls
)
if global_found:
globals_already_populated.append(name)
if not _is_set(param):
continue
f_name = field.alias if field.alias is not None else name
serialization = param_metadata.serialization
if serialization is not None:
serialized_params = _get_serialized_params(
param_metadata, f_name, param, path_param_field_types[name]
)
for key, value in serialized_params.items():
path_param_values[key] = value
else:
pp_vals: List[str] = []
if param_metadata.style == "simple":
if isinstance(param, List):
for pp_val in param:
if not _is_set(pp_val):
continue
pp_vals.append(_val_to_string(pp_val))
path_param_values[f_name] = ",".join(pp_vals)
elif isinstance(param, Dict):
for pp_key in param:
if not _is_set(param[pp_key]):
continue
if param_metadata.explode:
pp_vals.append(f"{pp_key}={_val_to_string(param[pp_key])}")
else:
pp_vals.append(f"{pp_key},{_val_to_string(param[pp_key])}")
path_param_values[f_name] = ",".join(pp_vals)
elif not isinstance(param, (str, int, float, complex, bool, Decimal)):
param_fields: Dict[str, FieldInfo] = param.__class__.model_fields
for name in param_fields:
param_field = param_fields[name]
param_value_metadata = find_field_metadata(
param_field, PathParamMetadata
)
if param_value_metadata is None:
continue
param_name = (
param_field.alias if param_field.alias is not None else name
)
param_field_val = getattr(param, name)
if not _is_set(param_field_val):
continue
if param_metadata.explode:
pp_vals.append(
f"{param_name}={_val_to_string(param_field_val)}"
)
else:
pp_vals.append(
f"{param_name},{_val_to_string(param_field_val)}"
)
path_param_values[f_name] = ",".join(pp_vals)
elif _is_set(param):
path_param_values[f_name] = _val_to_string(param)
return globals_already_populated
def is_optional(field):
return get_origin(field) is Union and type(None) in get_args(field)
def template_url(url_with_params: str, params: Dict[str, str]) -> str:
for key, value in params.items():
url_with_params = url_with_params.replace("{" + key + "}", value)
return url_with_params
def remove_suffix(input_string, suffix):
if suffix and input_string.endswith(suffix):
return input_string[: -len(suffix)]
return input_string
+137
View File
@@ -0,0 +1,137 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from datetime import datetime
from enum import Enum
from email.message import Message
from functools import partial
import os
from typing import Any, Callable, Dict, List, Optional, Tuple, TypeVar, Union, cast
from httpx import Response
from pydantic import BaseModel
from pydantic.fields import FieldInfo
from ..types.basemodel import Unset
from .serializers import marshal_json
from .metadata import ParamMetadata, find_field_metadata
def match_content_type(content_type: str, pattern: str) -> bool:
if pattern in (content_type, "*", "*/*"):
return True
msg = Message()
msg["content-type"] = content_type
media_type = msg.get_content_type()
if media_type == pattern:
return True
parts = media_type.split("/")
if len(parts) == 2:
if pattern in (f"{parts[0]}/*", f"*/{parts[1]}"):
return True
return False
def match_status_codes(status_codes: List[str], status_code: int) -> bool:
if "default" in status_codes:
return True
for code in status_codes:
if code == str(status_code):
return True
if code.endswith("XX") and code.startswith(str(status_code)[:1]):
return True
return False
T = TypeVar("T")
def cast_partial(typ):
return partial(cast, typ)
def get_global_from_env(
value: Optional[T], env_key: str, type_cast: Callable[[str], T]
) -> Optional[T]:
if value is not None:
return value
env_value = os.getenv(env_key)
if env_value is not None:
try:
return type_cast(env_value)
except ValueError:
pass
return None
def match_response(
response: Response, code: Union[str, List[str]], content_type: str
) -> bool:
codes = code if isinstance(code, list) else [code]
return match_status_codes(codes, response.status_code) and match_content_type(
response.headers.get("content-type", "application/octet-stream"), content_type
)
def _populate_from_globals(
param_name: str, value: Any, param_metadata_type: type, gbls: Any
) -> Tuple[Any, bool]:
if gbls is None:
return value, False
if not isinstance(gbls, BaseModel):
raise TypeError("globals must be a pydantic model")
global_fields: Dict[str, FieldInfo] = gbls.__class__.model_fields
found = False
for name in global_fields:
field = global_fields[name]
if name is not param_name:
continue
found = True
if value is not None:
return value, True
global_value = getattr(gbls, name)
param_metadata = find_field_metadata(field, param_metadata_type)
if param_metadata is None:
return value, True
return global_value, True
return value, found
def _val_to_string(val) -> str:
if isinstance(val, bool):
return str(val).lower()
if isinstance(val, datetime):
return str(val.isoformat().replace("+00:00", "Z"))
if isinstance(val, Enum):
return str(val.value)
return str(val)
def _get_serialized_params(
metadata: ParamMetadata, field_name: str, obj: Any, typ: type
) -> Dict[str, str]:
params: Dict[str, str] = {}
serialization = metadata.serialization
if serialization == "json":
params[field_name] = marshal_json(obj, typ)
return params
def _is_set(value: Any) -> bool:
return value is not None and not isinstance(value, Unset)