Files
AI-System/.venv/lib/python3.11/site-packages/google/genai/_gaos/basesdk.py
T
2026-07-04 14:31:50 +02:00

578 lines
20 KiB
Python

# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# pyformat: disable
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from . import errors, types, utils
from ._hooks import (
AfterErrorContext,
AfterSuccessContext,
BeforeRequestContext,
HookContext,
)
from .sdkconfiguration import SDKConfiguration
from .utils import RetryConfig, SerializedRequestBody, get_body_content
import httpx
from typing import Any, Callable, List, Mapping, Optional, Tuple
from urllib.parse import parse_qs, urlparse
class BaseSDK:
sdk_configuration: SDKConfiguration
parent_ref: Optional[object] = None
"""
Reference to the root SDK instance, if any. This will prevent it from
being garbage collected while there are active streams.
"""
def __init__(
self,
sdk_config: SDKConfiguration,
parent_ref: Optional[object] = None,
) -> None:
self.sdk_configuration = sdk_config
self.parent_ref = parent_ref
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 _coerce_timeout_ms(self, timeout: Optional[Any]) -> Optional[int]:
if timeout is None:
return None
if isinstance(timeout, (int, float)):
return int(timeout * 1000)
if isinstance(timeout, httpx.Timeout):
values = [timeout.connect, timeout.read, timeout.write, timeout.pool]
finite_values = [value for value in values if value is not None]
if not finite_values:
return None
return int(max(finite_values) * 1000)
raise TypeError("timeout must be a float, int, httpx.Timeout, or None")
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,
extra_query_params: Optional[Mapping[str, Any]] = None,
allow_empty_value: Optional[List[str]] = None,
allowed_fields: Optional[List[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,
extra_query_params,
allow_empty_value,
allowed_fields,
)
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,
extra_query_params: Optional[Mapping[str, Any]] = None,
allow_empty_value: Optional[List[str]] = None,
allowed_fields: Optional[List[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,
allow_empty_value,
)
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, types.Security)
if security is not None:
security_headers, security_query_params = utils.get_security(
security, allowed_fields
)
headers = {**headers, **security_headers}
query_params = {**query_params, **security_query_params}
if extra_query_params is not None:
for name, value in extra_query_params.items():
if value is None:
continue
if isinstance(value, (list, tuple)):
query_params[name] = [str(v) for v in value]
else:
query_params[name] = [str(value)]
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 if timeout is not None else httpx.USE_CLIENT_DEFAULT,
)
def do_request(
self,
hook_ctx: HookContext,
request: httpx.Request,
is_error_status_code: Callable[[int], bool],
stream: bool = 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(_attempt: int = 0):
http_res = None
try:
req = hooks.before_request(BeforeRequestContext(hook_ctx), request)
if "timeout" in request.extensions and "timeout" not in req.extensions:
req.extensions["timeout"] = request.extensions["timeout"]
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,
)
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 is_error_status_code(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.GenAiDefaultError("Unexpected error occurred", http_res)
else:
http_res = hooks.after_success(AfterSuccessContext(hook_ctx), http_res)
return http_res
class AsyncBaseSDK:
sdk_configuration: SDKConfiguration
parent_ref: Optional[object] = None
"""
Reference to the root SDK instance, if any. This will prevent it from
being garbage collected while there are active streams.
"""
def __init__(
self,
sdk_config: SDKConfiguration,
parent_ref: Optional[object] = None,
) -> None:
self.sdk_configuration = sdk_config
self.parent_ref = parent_ref
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 _coerce_timeout_ms(self, timeout: Optional[Any]) -> Optional[int]:
if timeout is None:
return None
if isinstance(timeout, (int, float)):
return int(timeout * 1000)
if isinstance(timeout, httpx.Timeout):
values = [timeout.connect, timeout.read, timeout.write, timeout.pool]
finite_values = [value for value in values if value is not None]
if not finite_values:
return None
return int(max(finite_values) * 1000)
raise TypeError("timeout must be a float, int, httpx.Timeout, or None")
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,
extra_query_params: Optional[Mapping[str, Any]] = None,
allow_empty_value: Optional[List[str]] = None,
allowed_fields: Optional[List[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,
extra_query_params,
allow_empty_value,
allowed_fields,
)
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,
extra_query_params: Optional[Mapping[str, Any]] = None,
allow_empty_value: Optional[List[str]] = None,
allowed_fields: Optional[List[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,
allow_empty_value,
)
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, types.Security)
if security is not None:
security_headers, security_query_params = utils.get_security(
security, allowed_fields
)
headers = {**headers, **security_headers}
query_params = {**query_params, **security_query_params}
if extra_query_params is not None:
for name, value in extra_query_params.items():
if value is None:
continue
if isinstance(value, (list, tuple)):
query_params[name] = [str(v) for v in value]
else:
query_params[name] = [str(value)]
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 if timeout is not None else httpx.USE_CLIENT_DEFAULT,
)
async def do_request_async(
self,
hook_ctx: HookContext,
request: httpx.Request,
is_error_status_code: Callable[[int], bool],
stream: bool = False,
retry_config: Optional[Tuple[RetryConfig, List[str]]] = None,
) -> httpx.Response:
client = self.sdk_configuration.async_client
logger = self.sdk_configuration.debug_logger
async_hooks = self.sdk_configuration.__dict__["_async_hooks"]
async def do(_attempt: int = 0):
http_res = None
try:
req = await async_hooks.before_request(
BeforeRequestContext(hook_ctx), request
)
if "timeout" in request.extensions and "timeout" not in req.extensions:
req.extensions["timeout"] = request.extensions["timeout"]
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 = await async_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,
)
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 is_error_status_code(http_res.status_code):
result, err = await async_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.GenAiDefaultError("Unexpected error occurred", http_res)
else:
http_res = await async_hooks.after_success(
AfterSuccessContext(hook_ctx), http_res
)
return http_res