From 4588adbf0188fb9c3aee86c9882644b2820d137e Mon Sep 17 00:00:00 2001 From: Mark Daoust Date: Thu, 6 Aug 2026 12:34:02 -0700 Subject: [PATCH] feat: implement listInteractions for Vertex. PiperOrigin-RevId: 960446774 --- google/genai/_gaos/interactions.py | 327 ++++++++++++++++++ google/genai/_gaos/models/__init__.py | 26 ++ google/genai/_gaos/models/listinteractions.py | 150 ++++++++ .../_gaos/types/interactions/__init__.py | 19 + .../types/interactions/interactionmetadata.py | 92 +++++ .../interactions/listinteractionsresponse.py | 59 ++++ google/genai/tests/interactions/test_paths.py | 14 + 7 files changed, 687 insertions(+) create mode 100644 google/genai/_gaos/models/listinteractions.py create mode 100644 google/genai/_gaos/types/interactions/interactionmetadata.py create mode 100644 google/genai/_gaos/types/interactions/listinteractionsresponse.py diff --git a/google/genai/_gaos/interactions.py b/google/genai/_gaos/interactions.py index 52fe581f6..71647543e 100644 --- a/google/genai/_gaos/interactions.py +++ b/google/genai/_gaos/interactions.py @@ -1203,6 +1203,163 @@ def _speakeasy_parse_response(http_res): parse_exc_, ) + def list( + self, + *, + page_size: Optional[int] = None, + page_token: Optional[str] = None, + api_version: Optional[str] = None, + extra_headers: Optional[Mapping[str, str]] = None, + extra_query: Optional[Mapping[str, Any]] = None, + timeout: Optional[Union[float, httpx.Timeout]] = None, + ) -> models.ListInteractionsResponse: + r"""List interactions. + + :param page_size: Optional. The maximum number of `Interactions` to return (per page). + :param page_token: Optional. A page token, received from a previous `ListInteractions` call. + :param api_version: Which version of the API to use. + :param extra_headers: Additional headers to set or replace on requests. + :param extra_query: Additional query parameters to append to requests. + :param timeout: Override the default request timeout configuration for this method in seconds + """ + base_url = None + url_variables = None + retries: OptionalNullable[utils.RetryConfig] = UNSET + server_url = None + http_headers = extra_headers + timeout_ms = self._coerce_timeout_ms(timeout) + 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.ListInteractionsRequest( + page_size=page_size, + page_token=page_token, + api_version=api_version, + ) + + _speakeasy_response_mode, http_headers = response_helpers.consume_response_mode( + http_headers + ) + req = self._build_request( + method="GET", + path="/{api_version}/interactions:list", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + extra_query_params=extra_query, + _globals=models.ListInteractionsGlobals( + api_version=self.sdk_configuration.globals.api_version, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "attempt-count-backoff", + utils.BackoffStrategy(500, 8000, 2, 30000), + True, + max_retries=4, + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["408", "409", "429", "5XX"]) + + def _speakeasy_parse_response(http_res): + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response( + interactions.ListInteractionsResponse, http_res, validate=False + ) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = utils.stream_to_text(http_res) + raise errors.GenAiDefaultError( + "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.GenAiDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "default", "application/json"): + return unmarshal_json_response( + models.ListInteractionsResponseBody, http_res, validate=False + ) + + raise errors.GenAiDefaultError("Unexpected response received", http_res) + + _speakeasy_hook_ctx = HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="listInteractions", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, types.Security + ), + tags=None, + extensions=None, + response=ResponseContext(mode=_speakeasy_response_mode, execution="sync"), + ) + http_res = self.do_request( + hook_ctx=_speakeasy_hook_ctx, + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + stream=_speakeasy_response_mode == "streaming", + retry_config=retry_config, + ) + if _speakeasy_response_mode != "parsed": + if utils.match_status_codes(["4XX", "5XX"], http_res.status_code): + http_res.read() + try: + _speakeasy_parse_response(http_res) + except Exception as parse_exc_: + response_helpers.raise_parse_error( + self.sdk_configuration.__dict__["_hooks"], + AfterParseErrorContext(_speakeasy_hook_ctx), + http_res, + parse_exc_, + ) + _speakeasy_response_cls = ( + response_helpers.StreamedAPIResponse + if _speakeasy_response_mode == "streaming" + else response_helpers.APIResponse + ) + return cast( + Any, + _speakeasy_response_cls( + raw=http_res, + parser=_speakeasy_parse_response, + mode="buffered", + client_ref=self, + hook_ctx=AfterParseErrorContext(_speakeasy_hook_ctx), + hooks=self.sdk_configuration.__dict__.get("_hooks"), + ), + ) + try: + return _speakeasy_parse_response(http_res) + except Exception as parse_exc_: + response_helpers.raise_parse_error( + self.sdk_configuration.__dict__["_hooks"], + AfterParseErrorContext(_speakeasy_hook_ctx), + http_res, + parse_exc_, + ) + def cancel( self, id: str, @@ -1403,6 +1560,7 @@ def __init__(self, sdk: Interactions) -> None: self.delete = response_helpers.to_raw_response_wrapper( sdk.delete, "extra_headers" ) + self.list = response_helpers.to_raw_response_wrapper(sdk.list, "extra_headers") self.cancel = response_helpers.to_raw_response_wrapper( sdk.cancel, "extra_headers" ) @@ -1420,6 +1578,9 @@ def __init__(self, sdk: Interactions) -> None: self.delete = response_helpers.to_streamed_response_wrapper( sdk.delete, "extra_headers" ) + self.list = response_helpers.to_streamed_response_wrapper( + sdk.list, "extra_headers" + ) self.cancel = response_helpers.to_streamed_response_wrapper( sdk.cancel, "extra_headers" ) @@ -2610,6 +2771,166 @@ async def _speakeasy_parse_response(http_res): parse_exc_, ) + async def list( + self, + *, + page_size: Optional[int] = None, + page_token: Optional[str] = None, + api_version: Optional[str] = None, + extra_headers: Optional[Mapping[str, str]] = None, + extra_query: Optional[Mapping[str, Any]] = None, + timeout: Optional[Union[float, httpx.Timeout]] = None, + ) -> models.ListInteractionsResponse: + r"""List interactions. + + :param page_size: Optional. The maximum number of `Interactions` to return (per page). + :param page_token: Optional. A page token, received from a previous `ListInteractions` call. + :param api_version: Which version of the API to use. + :param extra_headers: Additional headers to set or replace on requests. + :param extra_query: Additional query parameters to append to requests. + :param timeout: Override the default request timeout configuration for this method in seconds + """ + base_url = None + url_variables = None + retries: OptionalNullable[utils.RetryConfig] = UNSET + server_url = None + http_headers = extra_headers + timeout_ms = self._coerce_timeout_ms(timeout) + 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.ListInteractionsRequest( + page_size=page_size, + page_token=page_token, + api_version=api_version, + ) + + _speakeasy_response_mode, http_headers = response_helpers.consume_response_mode( + http_headers + ) + req = self._build_request_async( + method="GET", + path="/{api_version}/interactions:list", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + http_headers=http_headers, + extra_query_params=extra_query, + _globals=models.ListInteractionsGlobals( + api_version=self.sdk_configuration.globals.api_version, + ), + security=self.sdk_configuration.security, + allow_empty_value=None, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + else: + retries = utils.RetryConfig( + "attempt-count-backoff", + utils.BackoffStrategy(500, 8000, 2, 30000), + True, + max_retries=4, + ) + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["408", "409", "429", "5XX"]) + + async def _speakeasy_parse_response(http_res): + if utils.match_response(http_res, "200", "application/json"): + return unmarshal_json_response( + interactions.ListInteractionsResponse, http_res, validate=False + ) + if utils.match_response(http_res, "4XX", "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise errors.GenAiDefaultError( + "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.GenAiDefaultError( + "API error occurred", http_res, http_res_text + ) + if utils.match_response(http_res, "default", "application/json"): + return unmarshal_json_response( + models.ListInteractionsResponseBody, http_res, validate=False + ) + + raise errors.GenAiDefaultError("Unexpected response received", http_res) + + _speakeasy_hook_ctx = HookContext( + config=self.sdk_configuration, + base_url=base_url or "", + operation_id="listInteractions", + oauth2_scopes=None, + security_source=get_security_from_env( + self.sdk_configuration.security, types.Security + ), + tags=None, + extensions=None, + response=ResponseContext(mode=_speakeasy_response_mode, execution="async"), + ) + http_res = await self.do_request_async( + hook_ctx=_speakeasy_hook_ctx, + request=req, + is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c), + stream=_speakeasy_response_mode == "streaming", + retry_config=retry_config, + ) + if _speakeasy_response_mode != "parsed": + if utils.match_status_codes(["4XX", "5XX"], http_res.status_code): + await http_res.aread() + try: + await _speakeasy_parse_response(http_res) + except Exception as parse_exc_: + await response_helpers.raise_parse_error_async( + self.sdk_configuration.__dict__.get("_async_hooks"), + self.sdk_configuration.__dict__.get("_hooks"), + AfterParseErrorContext(_speakeasy_hook_ctx), + http_res, + parse_exc_, + ) + _speakeasy_response_cls = ( + response_helpers.AsyncStreamedAPIResponse + if _speakeasy_response_mode == "streaming" + else response_helpers.AsyncAPIResponse + ) + return cast( + Any, + _speakeasy_response_cls( + raw=http_res, + parser=_speakeasy_parse_response, + mode="buffered", + client_ref=self, + hook_ctx=AfterParseErrorContext(_speakeasy_hook_ctx), + hooks=self.sdk_configuration.__dict__.get("_hooks"), + async_hooks=self.sdk_configuration.__dict__.get("_async_hooks"), + ), + ) + try: + return await _speakeasy_parse_response(http_res) + except Exception as parse_exc_: + await response_helpers.raise_parse_error_async( + self.sdk_configuration.__dict__.get("_async_hooks"), + self.sdk_configuration.__dict__.get("_hooks"), + AfterParseErrorContext(_speakeasy_hook_ctx), + http_res, + parse_exc_, + ) + async def cancel( self, id: str, @@ -2815,6 +3136,9 @@ def __init__(self, sdk: AsyncInteractions) -> None: self.delete = response_helpers.async_to_raw_response_wrapper( sdk.delete, "extra_headers" ) + self.list = response_helpers.async_to_raw_response_wrapper( + sdk.list, "extra_headers" + ) self.cancel = response_helpers.async_to_raw_response_wrapper( sdk.cancel, "extra_headers" ) @@ -2832,6 +3156,9 @@ def __init__(self, sdk: AsyncInteractions) -> None: self.delete = response_helpers.async_to_streamed_response_wrapper( sdk.delete, "extra_headers" ) + self.list = response_helpers.async_to_streamed_response_wrapper( + sdk.list, "extra_headers" + ) self.cancel = response_helpers.async_to_streamed_response_wrapper( sdk.cancel, "extra_headers" ) diff --git a/google/genai/_gaos/models/__init__.py b/google/genai/_gaos/models/__init__.py index 024cabd61..bdb52cdfa 100644 --- a/google/genai/_gaos/models/__init__.py +++ b/google/genai/_gaos/models/__init__.py @@ -135,6 +135,16 @@ ListEnvironmentsRequest, ListEnvironmentsRequestParam, ) + from .listinteractions import ( + ListInteractionsGlobals, + ListInteractionsGlobalsTypedDict, + ListInteractionsRequest, + ListInteractionsRequestParam, + ListInteractionsResponse, + ListInteractionsResponseBody, + ListInteractionsResponseBodyTypedDict, + ListInteractionsResponseTypedDict, + ) from .listtriggerexecutions import ( ListTriggerExecutionsGlobals, ListTriggerExecutionsGlobalsTypedDict, @@ -264,6 +274,14 @@ "ListEnvironmentsGlobalsTypedDict", "ListEnvironmentsRequest", "ListEnvironmentsRequestParam", + "ListInteractionsGlobals", + "ListInteractionsGlobalsTypedDict", + "ListInteractionsRequest", + "ListInteractionsRequestParam", + "ListInteractionsResponse", + "ListInteractionsResponseBody", + "ListInteractionsResponseBodyTypedDict", + "ListInteractionsResponseTypedDict", "ListTriggerExecutionsGlobals", "ListTriggerExecutionsGlobalsTypedDict", "ListTriggerExecutionsRequest", @@ -377,6 +395,14 @@ "ListEnvironmentsGlobalsTypedDict": ".listenvironments", "ListEnvironmentsRequest": ".listenvironments", "ListEnvironmentsRequestParam": ".listenvironments", + "ListInteractionsGlobals": ".listinteractions", + "ListInteractionsGlobalsTypedDict": ".listinteractions", + "ListInteractionsRequest": ".listinteractions", + "ListInteractionsRequestParam": ".listinteractions", + "ListInteractionsResponse": ".listinteractions", + "ListInteractionsResponseBody": ".listinteractions", + "ListInteractionsResponseBodyTypedDict": ".listinteractions", + "ListInteractionsResponseTypedDict": ".listinteractions", "ListTriggerExecutionsGlobals": ".listtriggerexecutions", "ListTriggerExecutionsGlobalsTypedDict": ".listtriggerexecutions", "ListTriggerExecutionsRequest": ".listtriggerexecutions", diff --git a/google/genai/_gaos/models/listinteractions.py b/google/genai/_gaos/models/listinteractions.py new file mode 100644 index 000000000..bdc4ef10b --- /dev/null +++ b/google/genai/_gaos/models/listinteractions.py @@ -0,0 +1,150 @@ +# 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 __future__ import annotations +from ..types import BaseModel, UNSET_SENTINEL +from ..types.interactions import ( + error as interactions_error, + listinteractionsresponse as interactions_listinteractionsresponse, +) +from ..utils import FieldMetadata, PathParamMetadata, QueryParamMetadata +from pydantic import model_serializer +from typing import Optional, Union +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict + + +class ListInteractionsGlobalsTypedDict(TypedDict): + api_version: NotRequired[str] + r"""Which version of the API to use.""" + + +class ListInteractionsGlobals(BaseModel): + api_version: Annotated[ + Optional[str], + FieldMetadata(path=PathParamMetadata(style="simple", explode=False)), + ] = None + r"""Which version of the API to use.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["api_version"]) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class ListInteractionsRequestParam(TypedDict): + page_size: NotRequired[int] + r"""Optional. The maximum number of `Interactions` to return (per page).""" + page_token: NotRequired[str] + r"""Optional. A page token, received from a previous `ListInteractions` call.""" + api_version: NotRequired[str] + r"""Which version of the API to use.""" + + +class ListInteractionsRequest(BaseModel): + page_size: Annotated[ + Optional[int], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = None + r"""Optional. The maximum number of `Interactions` to return (per page).""" + + page_token: Annotated[ + Optional[str], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = None + r"""Optional. A page token, received from a previous `ListInteractions` call.""" + + api_version: Annotated[ + Optional[str], + FieldMetadata(path=PathParamMetadata(style="simple", explode=False)), + ] = None + r"""Which version of the API to use.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["page_size", "page_token", "api_version"]) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +class ListInteractionsResponseBodyTypedDict(TypedDict): + r"""Error listing interactions""" + + error: NotRequired[interactions_error.ErrorTypedDict] + r"""Error message from an interaction.""" + + +class ListInteractionsResponseBody(BaseModel): + r"""Error listing interactions""" + + error: Optional[interactions_error.Error] = None + r"""Error message from an interaction.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["error"]) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m + + +ListInteractionsResponseTypedDict = TypeAliasType( + "ListInteractionsResponseTypedDict", + Union[ + ListInteractionsResponseBodyTypedDict, + interactions_listinteractionsresponse.ListInteractionsResponseTypedDict, + ], +) + + +ListInteractionsResponse = TypeAliasType( + "ListInteractionsResponse", + Union[ + ListInteractionsResponseBody, + interactions_listinteractionsresponse.ListInteractionsResponse, + ], +) diff --git a/google/genai/_gaos/types/interactions/__init__.py b/google/genai/_gaos/types/interactions/__init__.py index 28882c2ea..05ca7e6cc 100644 --- a/google/genai/_gaos/types/interactions/__init__.py +++ b/google/genai/_gaos/types/interactions/__init__.py @@ -250,6 +250,11 @@ InteractionCreatedEvent, InteractionCreatedEventTypedDict, ) + from .interactionmetadata import ( + InteractionMetadata, + InteractionMetadataStatus, + InteractionMetadataTypedDict, + ) from .interactionsinput import InteractionsInput, InteractionsInputParam from .interactionsseevent import ( InteractionSSEEvent, @@ -270,6 +275,10 @@ InteractionStatusUpdateStatus, InteractionStatusUpdateTypedDict, ) + from .listinteractionsresponse import ( + ListInteractionsResponse, + ListInteractionsResponseTypedDict, + ) from .mcpserver import MCPServer, MCPServerParam from .mcpservertoolcalldelta import ( MCPServerToolCallDelta, @@ -592,6 +601,9 @@ "InteractionCreatedEventTypedDict", "InteractionEnvironment", "InteractionEnvironmentTypedDict", + "InteractionMetadata", + "InteractionMetadataStatus", + "InteractionMetadataTypedDict", "InteractionResponseFormat", "InteractionResponseFormatTypedDict", "InteractionSSEEvent", @@ -609,6 +621,8 @@ "InteractionsInput", "InteractionsInputParam", "Language", + "ListInteractionsResponse", + "ListInteractionsResponseTypedDict", "MCPServer", "MCPServerParam", "MCPServerToolCallDelta", @@ -989,6 +1003,9 @@ "InteractionCompletedEventTypedDict": ".interactioncompletedevent", "InteractionCreatedEvent": ".interactioncreatedevent", "InteractionCreatedEventTypedDict": ".interactioncreatedevent", + "InteractionMetadata": ".interactionmetadata", + "InteractionMetadataStatus": ".interactionmetadata", + "InteractionMetadataTypedDict": ".interactionmetadata", "InteractionsInput": ".interactionsinput", "InteractionsInputParam": ".interactionsinput", "InteractionSSEEvent": ".interactionsseevent", @@ -1002,6 +1019,8 @@ "InteractionStatusUpdate": ".interactionstatusupdate", "InteractionStatusUpdateStatus": ".interactionstatusupdate", "InteractionStatusUpdateTypedDict": ".interactionstatusupdate", + "ListInteractionsResponse": ".listinteractionsresponse", + "ListInteractionsResponseTypedDict": ".listinteractionsresponse", "MCPServer": ".mcpserver", "MCPServerParam": ".mcpserver", "MCPServerToolCallDelta": ".mcpservertoolcalldelta", diff --git a/google/genai/_gaos/types/interactions/interactionmetadata.py b/google/genai/_gaos/types/interactions/interactionmetadata.py new file mode 100644 index 000000000..5096c7488 --- /dev/null +++ b/google/genai/_gaos/types/interactions/interactionmetadata.py @@ -0,0 +1,92 @@ +# 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 __future__ import annotations +from .. import BaseModel, UNSET_SENTINEL, UnrecognizedStr +from pydantic import model_serializer +from typing import Literal, Optional, Union +from typing_extensions import NotRequired, TypedDict + + +InteractionMetadataStatus = Union[ + Literal[ + "in_progress", + "requires_action", + "completed", + "failed", + "cancelled", + "incomplete", + "budget_exceeded", + "queued", + ], + UnrecognizedStr, +] +r"""Output only. The status of the interaction.""" + + +class InteractionMetadataTypedDict(TypedDict): + r"""Metadata for an interaction, used for listing interactions.""" + + created: NotRequired[str] + r"""Output only. The time at which the response was created in ISO 8601 format + (YYYY-MM-DDThh:mm:ssZ). + """ + id: NotRequired[str] + r"""Output only. A unique identifier for the interaction completion.""" + status: NotRequired[InteractionMetadataStatus] + r"""Output only. The status of the interaction.""" + updated: NotRequired[str] + r"""Output only. The time at which the response was last updated in ISO 8601 format + (YYYY-MM-DDThh:mm:ssZ). + """ + + +class InteractionMetadata(BaseModel): + r"""Metadata for an interaction, used for listing interactions.""" + + created: Optional[str] = None + r"""Output only. The time at which the response was created in ISO 8601 format + (YYYY-MM-DDThh:mm:ssZ). + """ + + id: Optional[str] = None + r"""Output only. A unique identifier for the interaction completion.""" + + status: Optional[InteractionMetadataStatus] = None + r"""Output only. The status of the interaction.""" + + updated: Optional[str] = None + r"""Output only. The time at which the response was last updated in ISO 8601 format + (YYYY-MM-DDThh:mm:ssZ). + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["created", "id", "status", "updated"]) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/google/genai/_gaos/types/interactions/listinteractionsresponse.py b/google/genai/_gaos/types/interactions/listinteractionsresponse.py new file mode 100644 index 000000000..db2567ba5 --- /dev/null +++ b/google/genai/_gaos/types/interactions/listinteractionsresponse.py @@ -0,0 +1,59 @@ +# 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 __future__ import annotations +from .. import BaseModel, UNSET_SENTINEL +from .interactionmetadata import InteractionMetadata, InteractionMetadataTypedDict +from pydantic import model_serializer +from typing import List, Optional +from typing_extensions import NotRequired, TypedDict + + +class ListInteractionsResponseTypedDict(TypedDict): + interaction_metadatas: NotRequired[List[InteractionMetadataTypedDict]] + r"""The `InteractionMetadata` from the specified collection.""" + next_page_token: NotRequired[str] + r"""A token, which can be sent as `page_token` to retrieve the next page. + If this field is omitted, there are no subsequent pages. + """ + + +class ListInteractionsResponse(BaseModel): + interaction_metadatas: Optional[List[InteractionMetadata]] = None + r"""The `InteractionMetadata` from the specified collection.""" + + next_page_token: Optional[str] = None + r"""A token, which can be sent as `page_token` to retrieve the next page. + If this field is omitted, there are no subsequent pages. + """ + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["interaction_metadatas", "next_page_token"]) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/google/genai/tests/interactions/test_paths.py b/google/genai/tests/interactions/test_paths.py index 118a8e62d..b7f22004d 100644 --- a/google/genai/tests/interactions/test_paths.py +++ b/google/genai/tests/interactions/test_paths.py @@ -65,6 +65,13 @@ def test_interactions_paths(mock_auth_default, client): request = mock_send.call_args[0][0] assert str(request.url) == f'{expected_base_url}/interactions/{interaction_id}' + mock_send.reset_mock() + mock_send.return_value = Response(200, request=Request('GET', ''), headers={'content-type': 'application/json'}, content='{"interaction_metadatas": []}') + client.interactions.list(page_size=10, page_token='token-123') + mock_send.assert_called_once() + request = mock_send.call_args[0][0] + assert str(request.url) == f'{expected_base_url}/interactions:list?page_size=10&page_token=token-123' + @pytest.mark.asyncio @mock.patch.object(google.auth, "default", autospec=True) async def test_async_interactions_paths(mock_auth_default, client): @@ -106,6 +113,13 @@ async def test_async_interactions_paths(mock_auth_default, client): request = mock_send.call_args[0][0] assert str(request.url) == f'{expected_base_url}/interactions/{interaction_id}' + mock_send.reset_mock() + mock_send.return_value = Response(200, request=Request('GET', ''), headers={'content-type': 'application/json'}, content='{"interaction_metadatas": []}') + await client.aio.interactions.list(page_size=10, page_token='token-123') + mock_send.assert_called_once() + request = mock_send.call_args[0][0] + assert str(request.url) == f'{expected_base_url}/interactions:list?page_size=10&page_token=token-123' + pytestmark = pytest_helper.setup( file=__file__, globals_for_file=globals(),