diff --git a/packages/google-cloud-dialogflow-cx/CONTRIBUTING.rst b/packages/google-cloud-dialogflow-cx/CONTRIBUTING.rst index edca94cc39b8..7404d8b0a2cd 100644 --- a/packages/google-cloud-dialogflow-cx/CONTRIBUTING.rst +++ b/packages/google-cloud-dialogflow-cx/CONTRIBUTING.rst @@ -143,12 +143,12 @@ Running System Tests $ nox -s system # Run a single system test - $ nox -s system- -- -k + $ nox -s system-3.11 -- -k .. note:: - System tests are only configured to run under Python. + System tests are only configured to run under Python 3.8, 3.9, 3.10 and 3.11. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx/__init__.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx/__init__.py index 5954cfbe8fe4..e4e9b452dd7a 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx/__init__.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx/__init__.py @@ -196,10 +196,17 @@ from google.cloud.dialogflowcx_v3.types.gcs import GcsDestination from google.cloud.dialogflowcx_v3.types.generative_settings import GenerativeSettings from google.cloud.dialogflowcx_v3.types.import_strategy import ImportStrategy +from google.cloud.dialogflowcx_v3.types.inline import InlineDestination, InlineSource from google.cloud.dialogflowcx_v3.types.intent import ( CreateIntentRequest, DeleteIntentRequest, + ExportIntentsMetadata, + ExportIntentsRequest, + ExportIntentsResponse, GetIntentRequest, + ImportIntentsMetadata, + ImportIntentsRequest, + ImportIntentsResponse, Intent, IntentView, ListIntentsRequest, @@ -466,9 +473,17 @@ "GcsDestination", "GenerativeSettings", "ImportStrategy", + "InlineDestination", + "InlineSource", "CreateIntentRequest", "DeleteIntentRequest", + "ExportIntentsMetadata", + "ExportIntentsRequest", + "ExportIntentsResponse", "GetIntentRequest", + "ImportIntentsMetadata", + "ImportIntentsRequest", + "ImportIntentsResponse", "Intent", "ListIntentsRequest", "ListIntentsResponse", diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx/gapic_version.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx/gapic_version.py index 6972597de6c2..360a0d13ebdd 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx/gapic_version.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.27.1" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/__init__.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/__init__.py index ba7a88c5d5c9..8896c397d569 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/__init__.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/__init__.py @@ -154,10 +154,17 @@ from .types.gcs import GcsDestination from .types.generative_settings import GenerativeSettings from .types.import_strategy import ImportStrategy +from .types.inline import InlineDestination, InlineSource from .types.intent import ( CreateIntentRequest, DeleteIntentRequest, + ExportIntentsMetadata, + ExportIntentsRequest, + ExportIntentsResponse, GetIntentRequest, + ImportIntentsMetadata, + ImportIntentsRequest, + ImportIntentsResponse, Intent, IntentView, ListIntentsRequest, @@ -376,6 +383,9 @@ "ExportAgentResponse", "ExportFlowRequest", "ExportFlowResponse", + "ExportIntentsMetadata", + "ExportIntentsRequest", + "ExportIntentsResponse", "ExportTestCasesMetadata", "ExportTestCasesRequest", "ExportTestCasesResponse", @@ -410,10 +420,15 @@ "GetWebhookRequest", "ImportFlowRequest", "ImportFlowResponse", + "ImportIntentsMetadata", + "ImportIntentsRequest", + "ImportIntentsResponse", "ImportStrategy", "ImportTestCasesMetadata", "ImportTestCasesRequest", "ImportTestCasesResponse", + "InlineDestination", + "InlineSource", "InputAudioConfig", "Intent", "IntentCoverage", diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/gapic_metadata.json b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/gapic_metadata.json index 17c042151b36..a6d6e72ea387 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/gapic_metadata.json +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/gapic_metadata.json @@ -843,11 +843,21 @@ "delete_intent" ] }, + "ExportIntents": { + "methods": [ + "export_intents" + ] + }, "GetIntent": { "methods": [ "get_intent" ] }, + "ImportIntents": { + "methods": [ + "import_intents" + ] + }, "ListIntents": { "methods": [ "list_intents" @@ -873,11 +883,21 @@ "delete_intent" ] }, + "ExportIntents": { + "methods": [ + "export_intents" + ] + }, "GetIntent": { "methods": [ "get_intent" ] }, + "ImportIntents": { + "methods": [ + "import_intents" + ] + }, "ListIntents": { "methods": [ "list_intents" @@ -903,11 +923,21 @@ "delete_intent" ] }, + "ExportIntents": { + "methods": [ + "export_intents" + ] + }, "GetIntent": { "methods": [ "get_intent" ] }, + "ImportIntents": { + "methods": [ + "import_intents" + ] + }, "ListIntents": { "methods": [ "list_intents" diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/gapic_version.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/gapic_version.py index 6972597de6c2..360a0d13ebdd 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/gapic_version.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.27.1" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/async_client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/async_client.py index a7bddb9405a8..0f539f37fdba 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/async_client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/async_client.py @@ -52,6 +52,7 @@ from google.protobuf import timestamp_pb2 # type: ignore from google.cloud.dialogflowcx_v3.services.flows import pagers +from google.cloud.dialogflowcx_v3.types import advanced_settings from google.cloud.dialogflowcx_v3.types import flow from google.cloud.dialogflowcx_v3.types import flow as gcdc_flow from google.cloud.dialogflowcx_v3.types import page, validation_message diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/client.py index 91eb1e763c0e..72e253b4382a 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/client.py @@ -56,6 +56,7 @@ from google.protobuf import timestamp_pb2 # type: ignore from google.cloud.dialogflowcx_v3.services.flows import pagers +from google.cloud.dialogflowcx_v3.types import advanced_settings from google.cloud.dialogflowcx_v3.types import flow from google.cloud.dialogflowcx_v3.types import flow as gcdc_flow from google.cloud.dialogflowcx_v3.types import page, validation_message diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/async_client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/async_client.py index b68cb35976f9..c67b7ccfe0f6 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/async_client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/async_client.py @@ -42,6 +42,8 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore @@ -780,6 +782,217 @@ async def sample_delete_intent(): metadata=metadata, ) + async def import_intents( + self, + request: Optional[Union[intent.ImportIntentsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Imports the specified intents into the agent. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ImportIntentsMetadata][google.cloud.dialogflow.cx.v3.ImportIntentsMetadata] + - ``response``: + [ImportIntentsResponse][google.cloud.dialogflow.cx.v3.ImportIntentsResponse] + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflowcx_v3 + + async def sample_import_intents(): + # Create a client + client = dialogflowcx_v3.IntentsAsyncClient() + + # Initialize request argument(s) + request = dialogflowcx_v3.ImportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + ) + + # Make the request + operation = client.import_intents(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflowcx_v3.types.ImportIntentsRequest, dict]]): + The request object. The request message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3.Intents.ImportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.dialogflowcx_v3.types.ImportIntentsResponse` The response message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3.Intents.ImportIntents]. + + """ + # Create or coerce a protobuf request object. + request = intent.ImportIntentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_intents, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + intent.ImportIntentsResponse, + metadata_type=intent.ImportIntentsMetadata, + ) + + # Done; return the response. + return response + + async def export_intents( + self, + request: Optional[Union[intent.ExportIntentsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Exports the selected intents. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ExportIntentsMetadata][google.cloud.dialogflow.cx.v3.ExportIntentsMetadata] + - ``response``: + [ExportIntentsResponse][google.cloud.dialogflow.cx.v3.ExportIntentsResponse] + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflowcx_v3 + + async def sample_export_intents(): + # Create a client + client = dialogflowcx_v3.IntentsAsyncClient() + + # Initialize request argument(s) + request = dialogflowcx_v3.ExportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + intents=['intents_value1', 'intents_value2'], + ) + + # Make the request + operation = client.export_intents(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflowcx_v3.types.ExportIntentsRequest, dict]]): + The request object. The request message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3.Intents.ExportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.dialogflowcx_v3.types.ExportIntentsResponse` The response message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3.Intents.ExportIntents]. + + """ + # Create or coerce a protobuf request object. + request = intent.ExportIntentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.export_intents, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + intent.ExportIntentsResponse, + metadata_type=intent.ExportIntentsMetadata, + ) + + # Done; return the response. + return response + async def list_operations( self, request: Optional[operations_pb2.ListOperationsRequest] = None, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/client.py index 138b88b1273e..981e6dbed62d 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/client.py @@ -46,6 +46,8 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore @@ -1039,6 +1041,219 @@ def sample_delete_intent(): metadata=metadata, ) + def import_intents( + self, + request: Optional[Union[intent.ImportIntentsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Imports the specified intents into the agent. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ImportIntentsMetadata][google.cloud.dialogflow.cx.v3.ImportIntentsMetadata] + - ``response``: + [ImportIntentsResponse][google.cloud.dialogflow.cx.v3.ImportIntentsResponse] + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflowcx_v3 + + def sample_import_intents(): + # Create a client + client = dialogflowcx_v3.IntentsClient() + + # Initialize request argument(s) + request = dialogflowcx_v3.ImportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + ) + + # Make the request + operation = client.import_intents(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dialogflowcx_v3.types.ImportIntentsRequest, dict]): + The request object. The request message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3.Intents.ImportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.dialogflowcx_v3.types.ImportIntentsResponse` The response message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3.Intents.ImportIntents]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a intent.ImportIntentsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, intent.ImportIntentsRequest): + request = intent.ImportIntentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_intents] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + intent.ImportIntentsResponse, + metadata_type=intent.ImportIntentsMetadata, + ) + + # Done; return the response. + return response + + def export_intents( + self, + request: Optional[Union[intent.ExportIntentsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Exports the selected intents. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ExportIntentsMetadata][google.cloud.dialogflow.cx.v3.ExportIntentsMetadata] + - ``response``: + [ExportIntentsResponse][google.cloud.dialogflow.cx.v3.ExportIntentsResponse] + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflowcx_v3 + + def sample_export_intents(): + # Create a client + client = dialogflowcx_v3.IntentsClient() + + # Initialize request argument(s) + request = dialogflowcx_v3.ExportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + intents=['intents_value1', 'intents_value2'], + ) + + # Make the request + operation = client.export_intents(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dialogflowcx_v3.types.ExportIntentsRequest, dict]): + The request object. The request message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3.Intents.ExportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.dialogflowcx_v3.types.ExportIntentsResponse` The response message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3.Intents.ExportIntents]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a intent.ExportIntentsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, intent.ExportIntentsRequest): + request = intent.ExportIntentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.export_intents] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + intent.ExportIntentsResponse, + metadata_type=intent.ExportIntentsMetadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "IntentsClient": return self diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/base.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/base.py index 964064444612..14c97de933bb 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/base.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/base.py @@ -18,7 +18,7 @@ import google.api_core from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 +from google.api_core import gapic_v1, operations_v1 from google.api_core import retry as retries import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore @@ -154,6 +154,16 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.import_intents: gapic_v1.method.wrap_method( + self.import_intents, + default_timeout=None, + client_info=client_info, + ), + self.export_intents: gapic_v1.method.wrap_method( + self.export_intents, + default_timeout=None, + client_info=client_info, + ), } def close(self): @@ -165,6 +175,11 @@ def close(self): """ raise NotImplementedError() + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + @property def list_intents( self, @@ -208,6 +223,24 @@ def delete_intent( ]: raise NotImplementedError() + @property + def import_intents( + self, + ) -> Callable[ + [intent.ImportIntentsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def export_intents( + self, + ) -> Callable[ + [intent.ExportIntentsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + @property def list_operations( self, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/grpc.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/grpc.py index 4ff2b2d2ecd9..7ab9c5d2c6e7 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/grpc.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/grpc.py @@ -16,7 +16,7 @@ from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, grpc_helpers +from google.api_core import gapic_v1, grpc_helpers, operations_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -115,6 +115,7 @@ def __init__( self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None if api_mtls_endpoint: warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) @@ -233,6 +234,20 @@ def grpc_channel(self) -> grpc.Channel: """Return the channel designed to connect to this service.""" return self._grpc_channel + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) + + # Return the client from cache. + return self._operations_client + @property def list_intents( self, @@ -372,6 +387,78 @@ def delete_intent(self) -> Callable[[intent.DeleteIntentRequest], empty_pb2.Empt ) return self._stubs["delete_intent"] + @property + def import_intents( + self, + ) -> Callable[[intent.ImportIntentsRequest], operations_pb2.Operation]: + r"""Return a callable for the import intents method over gRPC. + + Imports the specified intents into the agent. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ImportIntentsMetadata][google.cloud.dialogflow.cx.v3.ImportIntentsMetadata] + - ``response``: + [ImportIntentsResponse][google.cloud.dialogflow.cx.v3.ImportIntentsResponse] + + Returns: + Callable[[~.ImportIntentsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "import_intents" not in self._stubs: + self._stubs["import_intents"] = self.grpc_channel.unary_unary( + "/google.cloud.dialogflow.cx.v3.Intents/ImportIntents", + request_serializer=intent.ImportIntentsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["import_intents"] + + @property + def export_intents( + self, + ) -> Callable[[intent.ExportIntentsRequest], operations_pb2.Operation]: + r"""Return a callable for the export intents method over gRPC. + + Exports the selected intents. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ExportIntentsMetadata][google.cloud.dialogflow.cx.v3.ExportIntentsMetadata] + - ``response``: + [ExportIntentsResponse][google.cloud.dialogflow.cx.v3.ExportIntentsResponse] + + Returns: + Callable[[~.ExportIntentsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "export_intents" not in self._stubs: + self._stubs["export_intents"] = self.grpc_channel.unary_unary( + "/google.cloud.dialogflow.cx.v3.Intents/ExportIntents", + request_serializer=intent.ExportIntentsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["export_intents"] + def close(self): self.grpc_channel.close() diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/grpc_asyncio.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/grpc_asyncio.py index 54f3ce27c1c6..92231fe4aebc 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/grpc_asyncio.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/grpc_asyncio.py @@ -16,7 +16,7 @@ from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, grpc_helpers_async +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.cloud.location import locations_pb2 # type: ignore @@ -161,6 +161,7 @@ def __init__( self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None if api_mtls_endpoint: warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) @@ -236,6 +237,22 @@ def grpc_channel(self) -> aio.Channel: # Return the channel from cache. return self._grpc_channel + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + @property def list_intents( self, @@ -379,6 +396,78 @@ def delete_intent( ) return self._stubs["delete_intent"] + @property + def import_intents( + self, + ) -> Callable[[intent.ImportIntentsRequest], Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import intents method over gRPC. + + Imports the specified intents into the agent. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ImportIntentsMetadata][google.cloud.dialogflow.cx.v3.ImportIntentsMetadata] + - ``response``: + [ImportIntentsResponse][google.cloud.dialogflow.cx.v3.ImportIntentsResponse] + + Returns: + Callable[[~.ImportIntentsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "import_intents" not in self._stubs: + self._stubs["import_intents"] = self.grpc_channel.unary_unary( + "/google.cloud.dialogflow.cx.v3.Intents/ImportIntents", + request_serializer=intent.ImportIntentsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["import_intents"] + + @property + def export_intents( + self, + ) -> Callable[[intent.ExportIntentsRequest], Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the export intents method over gRPC. + + Exports the selected intents. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ExportIntentsMetadata][google.cloud.dialogflow.cx.v3.ExportIntentsMetadata] + - ``response``: + [ExportIntentsResponse][google.cloud.dialogflow.cx.v3.ExportIntentsResponse] + + Returns: + Callable[[~.ExportIntentsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "export_intents" not in self._stubs: + self._stubs["export_intents"] = self.grpc_channel.unary_unary( + "/google.cloud.dialogflow.cx.v3.Intents/ExportIntents", + request_serializer=intent.ExportIntentsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["export_intents"] + def close(self): return self.grpc_channel.close() diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/rest.py index f7a8306e7811..aebf7ad075ce 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/intents/transports/rest.py @@ -20,7 +20,13 @@ from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming +from google.api_core import ( + gapic_v1, + operations_v1, + path_template, + rest_helpers, + rest_streaming, +) from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore @@ -80,6 +86,14 @@ def pre_delete_intent(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata + def pre_export_intents(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_export_intents(self, response): + logging.log(f"Received response: {response}") + return response + def pre_get_intent(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -88,6 +102,14 @@ def post_get_intent(self, response): logging.log(f"Received response: {response}") return response + def pre_import_intents(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_intents(self, response): + logging.log(f"Received response: {response}") + return response + def pre_list_intents(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -141,6 +163,27 @@ def pre_delete_intent( """ return request, metadata + def pre_export_intents( + self, request: intent.ExportIntentsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[intent.ExportIntentsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for export_intents + + Override in a subclass to manipulate the request or metadata + before they are sent to the Intents server. + """ + return request, metadata + + def post_export_intents( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for export_intents + + Override in a subclass to manipulate the response + after it is returned by the Intents server but before + it is returned to user code. + """ + return response + def pre_get_intent( self, request: intent.GetIntentRequest, metadata: Sequence[Tuple[str, str]] ) -> Tuple[intent.GetIntentRequest, Sequence[Tuple[str, str]]]: @@ -160,6 +203,27 @@ def post_get_intent(self, response: intent.Intent) -> intent.Intent: """ return response + def pre_import_intents( + self, request: intent.ImportIntentsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[intent.ImportIntentsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_intents + + Override in a subclass to manipulate the request or metadata + before they are sent to the Intents server. + """ + return request, metadata + + def post_import_intents( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for import_intents + + Override in a subclass to manipulate the response + after it is returned by the Intents server but before + it is returned to user code. + """ + return response + def pre_list_intents( self, request: intent.ListIntentsRequest, metadata: Sequence[Tuple[str, str]] ) -> Tuple[intent.ListIntentsRequest, Sequence[Tuple[str, str]]]: @@ -408,11 +472,70 @@ def __init__( self._session = AuthorizedSession( self._credentials, default_host=self.DEFAULT_HOST ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None if client_cert_source_for_mtls: self._session.configure_mtls_channel(client_cert_source_for_mtls) self._interceptor = interceptor or IntentsRestInterceptor() self._prep_wrapped_messages(client_info) + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.CancelOperation": [ + { + "method": "post", + "uri": "/v3/{name=projects/*/operations/*}:cancel", + }, + { + "method": "post", + "uri": "/v3/{name=projects/*/locations/*/operations/*}:cancel", + }, + ], + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v3/{name=projects/*/operations/*}", + }, + { + "method": "get", + "uri": "/v3/{name=projects/*/locations/*/operations/*}", + }, + ], + "google.longrunning.Operations.ListOperations": [ + { + "method": "get", + "uri": "/v3/{name=projects/*}/operations", + }, + { + "method": "get", + "uri": "/v3/{name=projects/*/locations/*}/operations", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v3", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + class _CreateIntent(IntentsRestStub): def __hash__(self): return hash("CreateIntent") @@ -591,6 +714,103 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) + class _ExportIntents(IntentsRestStub): + def __hash__(self): + return hash("ExportIntents") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: intent.ExportIntentsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the export intents method over HTTP. + + Args: + request (~.intent.ExportIntentsRequest): + The request object. The request message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3.Intents.ExportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v3/{parent=projects/*/locations/*/agents/*}/intents:export", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_export_intents(request, metadata) + pb_request = intent.ExportIntentsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_export_intents(resp) + return resp + class _GetIntent(IntentsRestStub): def __hash__(self): return hash("GetIntent") @@ -685,6 +905,103 @@ def __call__( resp = self._interceptor.post_get_intent(resp) return resp + class _ImportIntents(IntentsRestStub): + def __hash__(self): + return hash("ImportIntents") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: intent.ImportIntentsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the import intents method over HTTP. + + Args: + request (~.intent.ImportIntentsRequest): + The request object. The request message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3.Intents.ImportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v3/{parent=projects/*/locations/*/agents/*}/intents:import", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_import_intents(request, metadata) + pb_request = intent.ImportIntentsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_import_intents(resp) + return resp + class _ListIntents(IntentsRestStub): def __hash__(self): return hash("ListIntents") @@ -891,12 +1208,28 @@ def delete_intent(self) -> Callable[[intent.DeleteIntentRequest], empty_pb2.Empt # In C++ this would require a dynamic_cast return self._DeleteIntent(self._session, self._host, self._interceptor) # type: ignore + @property + def export_intents( + self, + ) -> Callable[[intent.ExportIntentsRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ExportIntents(self._session, self._host, self._interceptor) # type: ignore + @property def get_intent(self) -> Callable[[intent.GetIntentRequest], intent.Intent]: # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. # In C++ this would require a dynamic_cast return self._GetIntent(self._session, self._host, self._interceptor) # type: ignore + @property + def import_intents( + self, + ) -> Callable[[intent.ImportIntentsRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ImportIntents(self._session, self._host, self._interceptor) # type: ignore + @property def list_intents( self, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/async_client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/async_client.py index a78e97d96db0..65209968eff5 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/async_client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/async_client.py @@ -47,7 +47,7 @@ from google.protobuf import field_mask_pb2 # type: ignore from google.cloud.dialogflowcx_v3.services.pages import pagers -from google.cloud.dialogflowcx_v3.types import fulfillment +from google.cloud.dialogflowcx_v3.types import advanced_settings, fulfillment from google.cloud.dialogflowcx_v3.types import page from google.cloud.dialogflowcx_v3.types import page as gcdc_page diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/client.py index 0b21f84f1d24..4000f1bc8edb 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/client.py @@ -51,7 +51,7 @@ from google.protobuf import field_mask_pb2 # type: ignore from google.cloud.dialogflowcx_v3.services.pages import pagers -from google.cloud.dialogflowcx_v3.types import fulfillment +from google.cloud.dialogflowcx_v3.types import advanced_settings, fulfillment from google.cloud.dialogflowcx_v3.types import page from google.cloud.dialogflowcx_v3.types import page as gcdc_page diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/__init__.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/__init__.py index b72780f5f9f7..e0a0c814015a 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/__init__.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/__init__.py @@ -123,10 +123,17 @@ from .fulfillment import Fulfillment from .gcs import GcsDestination from .generative_settings import GenerativeSettings +from .inline import InlineDestination, InlineSource from .intent import ( CreateIntentRequest, DeleteIntentRequest, + ExportIntentsMetadata, + ExportIntentsRequest, + ExportIntentsResponse, GetIntentRequest, + ImportIntentsMetadata, + ImportIntentsRequest, + ImportIntentsResponse, Intent, IntentView, ListIntentsRequest, @@ -358,9 +365,17 @@ "GcsDestination", "GenerativeSettings", "ImportStrategy", + "InlineDestination", + "InlineSource", "CreateIntentRequest", "DeleteIntentRequest", + "ExportIntentsMetadata", + "ExportIntentsRequest", + "ExportIntentsResponse", "GetIntentRequest", + "ImportIntentsMetadata", + "ImportIntentsRequest", + "ImportIntentsResponse", "Intent", "ListIntentsRequest", "ListIntentsResponse", diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/advanced_settings.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/advanced_settings.py index 83e5ca206895..0e342928663c 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/advanced_settings.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/advanced_settings.py @@ -52,6 +52,14 @@ class AdvancedSettings(proto.Message): - Agent level - Flow level + dtmf_settings (google.cloud.dialogflowcx_v3.types.AdvancedSettings.DtmfSettings): + Settings for DTMF. + Exposed at the following levels: + + - Agent level + - Flow level + - Page level + - Parameter level. logging_settings (google.cloud.dialogflowcx_v3.types.AdvancedSettings.LoggingSettings): Settings for logging. Settings for Dialogflow History, Contact Center @@ -61,6 +69,39 @@ class AdvancedSettings(proto.Message): - Agent level. """ + class DtmfSettings(proto.Message): + r"""Define behaviors for DTMF (dual tone multi frequency). + + Attributes: + enabled (bool): + If true, incoming audio is processed for DTMF + (dual tone multi frequency) events. For example, + if the caller presses a button on their + telephone keypad and DTMF processing is enabled, + Dialogflow will detect the event (e.g. a "3" was + pressed) in the incoming audio and pass the + event to the bot to drive business logic (e.g. + when 3 is pressed, return the account balance). + max_digits (int): + Max length of DTMF digits. + finish_digit (str): + The digit that terminates a DTMF digit + sequence. + """ + + enabled: bool = proto.Field( + proto.BOOL, + number=1, + ) + max_digits: int = proto.Field( + proto.INT32, + number=2, + ) + finish_digit: str = proto.Field( + proto.STRING, + number=3, + ) + class LoggingSettings(proto.Message): r"""Define behaviors on logging. @@ -87,6 +128,11 @@ class LoggingSettings(proto.Message): number=2, message=gcs.GcsDestination, ) + dtmf_settings: DtmfSettings = proto.Field( + proto.MESSAGE, + number=5, + message=DtmfSettings, + ) logging_settings: LoggingSettings = proto.Field( proto.MESSAGE, number=6, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/flow.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/flow.py index 88755b20e9ba..a5efea2ae1c3 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/flow.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/flow.py @@ -22,6 +22,9 @@ import proto # type: ignore from google.cloud.dialogflowcx_v3.types import import_strategy, page, validation_message +from google.cloud.dialogflowcx_v3.types import ( + advanced_settings as gcdc_advanced_settings, +) __protobuf__ = proto.module( package="google.cloud.dialogflow.cx.v3", @@ -198,6 +201,11 @@ class Flow(proto.Message): for agent-level groups. nlu_settings (google.cloud.dialogflowcx_v3.types.NluSettings): NLU related settings of the flow. + advanced_settings (google.cloud.dialogflowcx_v3.types.AdvancedSettings): + Hierarchical advanced settings for this flow. + The settings exposed at the lower level + overrides the settings exposed at the higher + level. knowledge_connector_settings (google.cloud.dialogflowcx_v3.types.KnowledgeConnectorSettings): Optional. Knowledge connector configuration. """ @@ -233,6 +241,11 @@ class Flow(proto.Message): number=11, message="NluSettings", ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=14, + message=gcdc_advanced_settings.AdvancedSettings, + ) knowledge_connector_settings: page.KnowledgeConnectorSettings = proto.Field( proto.MESSAGE, number=18, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/fulfillment.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/fulfillment.py index e477b5abc3f5..44b36a87fbee 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/fulfillment.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/fulfillment.py @@ -20,6 +20,9 @@ from google.protobuf import struct_pb2 # type: ignore import proto # type: ignore +from google.cloud.dialogflowcx_v3.types import ( + advanced_settings as gcdc_advanced_settings, +) from google.cloud.dialogflowcx_v3.types import response_message __protobuf__ = proto.module( @@ -85,6 +88,18 @@ class Fulfillment(proto.Message): webhook. conditional_cases (MutableSequence[google.cloud.dialogflowcx_v3.types.Fulfillment.ConditionalCases]): Conditional cases for this fulfillment. + advanced_settings (google.cloud.dialogflowcx_v3.types.AdvancedSettings): + Hierarchical advanced settings for this + fulfillment. The settings exposed at the lower + level overrides the settings exposed at the + higher level. + enable_generative_fallback (bool): + If the flag is true, the agent will utilize LLM to generate + a text response. If LLM generation fails, the defined + [responses][google.cloud.dialogflow.cx.v3.Fulfillment.messages] + in the fulfillment will be respected. This flag is only + useful for fulfillments associated with no-match event + handlers. """ class SetParameterAction(proto.Message): @@ -218,6 +233,15 @@ class CaseContent(proto.Message): number=5, message=ConditionalCases, ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=7, + message=gcdc_advanced_settings.AdvancedSettings, + ) + enable_generative_fallback: bool = proto.Field( + proto.BOOL, + number=12, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/inline.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/inline.py new file mode 100644 index 000000000000..ec169fec3a6f --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/inline.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.dialogflow.cx.v3", + manifest={ + "InlineDestination", + "InlineSource", + }, +) + + +class InlineDestination(proto.Message): + r"""Inline destination for a Dialogflow operation that writes or exports + objects (e.g. [intents][google.cloud.dialogflow.cx.v3.Intent]) + outside of Dialogflow. + + Attributes: + content (bytes): + Output only. The uncompressed byte content + for the objects. Only populated in responses. + """ + + content: bytes = proto.Field( + proto.BYTES, + number=1, + ) + + +class InlineSource(proto.Message): + r"""Inline source for a Dialogflow operation that reads or imports + objects (e.g. [intents][google.cloud.dialogflow.cx.v3.Intent]) into + Dialogflow. + + Attributes: + content (bytes): + The uncompressed byte content for the + objects. + """ + + content: bytes = proto.Field( + proto.BYTES, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/intent.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/intent.py index 3cae590ad252..0b4159716a98 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/intent.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/intent.py @@ -20,6 +20,8 @@ from google.protobuf import field_mask_pb2 # type: ignore import proto # type: ignore +from google.cloud.dialogflowcx_v3.types import inline + __protobuf__ = proto.module( package="google.cloud.dialogflow.cx.v3", manifest={ @@ -31,6 +33,12 @@ "CreateIntentRequest", "UpdateIntentRequest", "DeleteIntentRequest", + "ImportIntentsRequest", + "ImportIntentsResponse", + "ImportIntentsMetadata", + "ExportIntentsRequest", + "ExportIntentsResponse", + "ExportIntentsMetadata", }, ) @@ -484,4 +492,289 @@ class DeleteIntentRequest(proto.Message): ) +class ImportIntentsRequest(proto.Message): + r"""The request message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3.Intents.ImportIntents]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + parent (str): + Required. The agent to import the intents into. Format: + ``projects//locations//agents/``. + intents_uri (str): + The `Google Cloud + Storage `__ URI to + import intents from. The format of this URI must be + ``gs:///``. + + Dialogflow performs a read operation for the Cloud Storage + object on the caller's behalf, so your request + authentication must have read permissions for the object. + For more information, see `Dialogflow access + control `__. + + This field is a member of `oneof`_ ``intents``. + intents_content (google.cloud.dialogflowcx_v3.types.InlineSource): + Uncompressed byte content of intents. + + This field is a member of `oneof`_ ``intents``. + merge_option (google.cloud.dialogflowcx_v3.types.ImportIntentsRequest.MergeOption): + Merge option for importing intents. If not specified, + ``REJECT`` is assumed. + """ + + class MergeOption(proto.Enum): + r"""Merge option when display name conflicts exist during import. + + Values: + MERGE_OPTION_UNSPECIFIED (0): + Unspecified. Should not be used. + REJECT (1): + DEPRECATED: Please use + [REPORT_CONFLICT][ImportIntentsRequest.REPORT_CONFLICT] + instead. Fail the request if there are intents whose display + names conflict with the display names of intents in the + agent. + REPLACE (2): + Replace the original intent in the agent with + the new intent when display name conflicts + exist. + MERGE (3): + Merge the original intent with the new intent + when display name conflicts exist. + RENAME (4): + Create new intents with new display names to + differentiate them from the existing intents + when display name conflicts exist. + REPORT_CONFLICT (5): + Report conflict information if display names + conflict is detected. Otherwise, import intents. + KEEP (6): + Keep the original intent and discard the + conflicting new intent when display name + conflicts exist. + """ + MERGE_OPTION_UNSPECIFIED = 0 + REJECT = 1 + REPLACE = 2 + MERGE = 3 + RENAME = 4 + REPORT_CONFLICT = 5 + KEEP = 6 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + intents_uri: str = proto.Field( + proto.STRING, + number=2, + oneof="intents", + ) + intents_content: inline.InlineSource = proto.Field( + proto.MESSAGE, + number=3, + oneof="intents", + message=inline.InlineSource, + ) + merge_option: MergeOption = proto.Field( + proto.ENUM, + number=4, + enum=MergeOption, + ) + + +class ImportIntentsResponse(proto.Message): + r"""The response message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3.Intents.ImportIntents]. + + Attributes: + intents (MutableSequence[str]): + The unique identifier of the imported intents. Format: + ``projects//locations//agents//intents/``. + conflicting_resources (google.cloud.dialogflowcx_v3.types.ImportIntentsResponse.ConflictingResources): + Info which resources have conflicts when + [REPORT_CONFLICT][ImportIntentsResponse.REPORT_CONFLICT] + merge_option is set in ImportIntentsRequest. + """ + + class ConflictingResources(proto.Message): + r"""Conflicting resources detected during the import process. Only + filled when [REPORT_CONFLICT][ImportIntentsResponse.REPORT_CONFLICT] + is set in the request and there are conflicts in the display names. + + Attributes: + intent_display_names (MutableSequence[str]): + Display names of conflicting intents. + entity_display_names (MutableSequence[str]): + Display names of conflicting entities. + """ + + intent_display_names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + entity_display_names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + intents: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + conflicting_resources: ConflictingResources = proto.Field( + proto.MESSAGE, + number=2, + message=ConflictingResources, + ) + + +class ImportIntentsMetadata(proto.Message): + r"""Metadata returned for the + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3.Intents.ImportIntents] + long running operation. + + """ + + +class ExportIntentsRequest(proto.Message): + r"""The request message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3.Intents.ExportIntents]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + parent (str): + Required. The name of the parent agent to export intents. + Format: + ``projects//locations//agents/``. + intents (MutableSequence[str]): + Required. The name of the intents to export. Format: + ``projects//locations//agents//intents/``. + intents_uri (str): + Optional. The `Google Cloud + Storage `__ URI to + export the intents to. The format of this URI must be + ``gs:///``. + + Dialogflow performs a write operation for the Cloud Storage + object on the caller's behalf, so your request + authentication must have write permissions for the object. + For more information, see `Dialogflow access + control `__. + + This field is a member of `oneof`_ ``destination``. + intents_content_inline (bool): + Optional. The option to return the serialized + intents inline. + + This field is a member of `oneof`_ ``destination``. + data_format (google.cloud.dialogflowcx_v3.types.ExportIntentsRequest.DataFormat): + Optional. The data format of the exported intents. If not + specified, ``BLOB`` is assumed. + """ + + class DataFormat(proto.Enum): + r"""Data format of the exported intents. + + Values: + DATA_FORMAT_UNSPECIFIED (0): + Unspecified format. Treated as ``BLOB``. + BLOB (1): + Intents will be exported as raw bytes. + JSON (2): + Intents will be exported in JSON format. + CSV (3): + Intents will be exported in CSV format. + """ + DATA_FORMAT_UNSPECIFIED = 0 + BLOB = 1 + JSON = 2 + CSV = 3 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + intents: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + intents_uri: str = proto.Field( + proto.STRING, + number=3, + oneof="destination", + ) + intents_content_inline: bool = proto.Field( + proto.BOOL, + number=4, + oneof="destination", + ) + data_format: DataFormat = proto.Field( + proto.ENUM, + number=5, + enum=DataFormat, + ) + + +class ExportIntentsResponse(proto.Message): + r"""The response message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3.Intents.ExportIntents]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + intents_uri (str): + The URI to a file containing the exported intents. This + field is populated only if ``intents_uri`` is specified in + [ExportIntentsRequest][google.cloud.dialogflow.cx.v3.ExportIntentsRequest]. + + This field is a member of `oneof`_ ``intents``. + intents_content (google.cloud.dialogflowcx_v3.types.InlineDestination): + Uncompressed byte content for intents. This field is + populated only if ``intents_content_inline`` is set to true + in + [ExportIntentsRequest][google.cloud.dialogflow.cx.v3.ExportIntentsRequest]. + + This field is a member of `oneof`_ ``intents``. + """ + + intents_uri: str = proto.Field( + proto.STRING, + number=1, + oneof="intents", + ) + intents_content: inline.InlineDestination = proto.Field( + proto.MESSAGE, + number=2, + oneof="intents", + message=inline.InlineDestination, + ) + + +class ExportIntentsMetadata(proto.Message): + r"""Metadata returned for the + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3.Intents.ExportIntents] + long running operation. + + """ + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/page.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/page.py index 323551e02028..0ba9da1be3bc 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/page.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/page.py @@ -22,6 +22,9 @@ import proto # type: ignore from google.cloud.dialogflowcx_v3.types import data_store_connection, fulfillment +from google.cloud.dialogflowcx_v3.types import ( + advanced_settings as gcdc_advanced_settings, +) __protobuf__ = proto.module( package="google.cloud.dialogflow.cx.v3", @@ -127,6 +130,11 @@ class Page(proto.Message): Handlers associated with the page to handle events such as webhook errors, no match or no input. + advanced_settings (google.cloud.dialogflowcx_v3.types.AdvancedSettings): + Hierarchical advanced settings for this page. + The settings exposed at the lower level + overrides the settings exposed at the higher + level. knowledge_connector_settings (google.cloud.dialogflowcx_v3.types.KnowledgeConnectorSettings): Optional. Knowledge connector configuration. """ @@ -163,6 +171,11 @@ class Page(proto.Message): number=10, message="EventHandler", ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=13, + message=gcdc_advanced_settings.AdvancedSettings, + ) knowledge_connector_settings: "KnowledgeConnectorSettings" = proto.Field( proto.MESSAGE, number=18, @@ -223,6 +236,11 @@ class Parameter(proto.Message): parameter level redaction or [entity type level redaction][google.cloud.dialogflow.cx.v3.EntityType.redact] is enabled. + advanced_settings (google.cloud.dialogflowcx_v3.types.AdvancedSettings): + Hierarchical advanced settings for this + parameter. The settings exposed at the lower + level overrides the settings exposed at the + higher level. """ class FillBehavior(proto.Message): @@ -317,6 +335,11 @@ class FillBehavior(proto.Message): proto.BOOL, number=11, ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=12, + message=gcdc_advanced_settings.AdvancedSettings, + ) parameters: MutableSequence[Parameter] = proto.RepeatedField( proto.MESSAGE, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/session.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/session.py index 37545db5a8d8..252ff7f13679 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/session.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/types/session.py @@ -28,6 +28,9 @@ response_message, session_entity_type, ) +from google.cloud.dialogflowcx_v3.types import ( + advanced_settings as gcdc_advanced_settings, +) from google.cloud.dialogflowcx_v3.types import audio_config from google.cloud.dialogflowcx_v3.types import intent as gcdc_intent @@ -1071,6 +1074,16 @@ class QueryResult(proto.Message): [``analyze_query_text_sentiment``] [google.cloud.dialogflow.cx.v3.QueryParameters.analyze_query_text_sentiment], specified in the request. + advanced_settings (google.cloud.dialogflowcx_v3.types.AdvancedSettings): + Returns the current advanced settings + including IVR settings. Even though the + operations configured by these settings are + performed by Dialogflow, the client may need to + perform special logic at the moment. For + example, if Dialogflow exports audio to Google + Cloud Storage, then the client may need to wait + for the resulting object to appear in the bucket + before proceeding. """ text: str = proto.Field( @@ -1154,6 +1167,11 @@ class QueryResult(proto.Message): number=17, message="SentimentAnalysisResult", ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=21, + message=gcdc_advanced_settings.AdvancedSettings, + ) class TextInput(proto.Message): diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/__init__.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/__init__.py index 772ad9d4aeda..248882ae6c8a 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/__init__.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/__init__.py @@ -154,10 +154,17 @@ from .types.gcs import GcsDestination from .types.generative_settings import GenerativeSettings from .types.import_strategy import ImportStrategy +from .types.inline import InlineDestination, InlineSource from .types.intent import ( CreateIntentRequest, DeleteIntentRequest, + ExportIntentsMetadata, + ExportIntentsRequest, + ExportIntentsResponse, GetIntentRequest, + ImportIntentsMetadata, + ImportIntentsRequest, + ImportIntentsResponse, Intent, IntentView, ListIntentsRequest, @@ -376,6 +383,9 @@ "ExportAgentResponse", "ExportFlowRequest", "ExportFlowResponse", + "ExportIntentsMetadata", + "ExportIntentsRequest", + "ExportIntentsResponse", "ExportTestCasesMetadata", "ExportTestCasesRequest", "ExportTestCasesResponse", @@ -410,10 +420,15 @@ "GetWebhookRequest", "ImportFlowRequest", "ImportFlowResponse", + "ImportIntentsMetadata", + "ImportIntentsRequest", + "ImportIntentsResponse", "ImportStrategy", "ImportTestCasesMetadata", "ImportTestCasesRequest", "ImportTestCasesResponse", + "InlineDestination", + "InlineSource", "InputAudioConfig", "Intent", "IntentCoverage", diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/gapic_metadata.json b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/gapic_metadata.json index 9c839facf225..aed58c497bdb 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/gapic_metadata.json +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/gapic_metadata.json @@ -843,11 +843,21 @@ "delete_intent" ] }, + "ExportIntents": { + "methods": [ + "export_intents" + ] + }, "GetIntent": { "methods": [ "get_intent" ] }, + "ImportIntents": { + "methods": [ + "import_intents" + ] + }, "ListIntents": { "methods": [ "list_intents" @@ -873,11 +883,21 @@ "delete_intent" ] }, + "ExportIntents": { + "methods": [ + "export_intents" + ] + }, "GetIntent": { "methods": [ "get_intent" ] }, + "ImportIntents": { + "methods": [ + "import_intents" + ] + }, "ListIntents": { "methods": [ "list_intents" @@ -903,11 +923,21 @@ "delete_intent" ] }, + "ExportIntents": { + "methods": [ + "export_intents" + ] + }, "GetIntent": { "methods": [ "get_intent" ] }, + "ImportIntents": { + "methods": [ + "import_intents" + ] + }, "ListIntents": { "methods": [ "list_intents" diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/gapic_version.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/gapic_version.py index 6972597de6c2..360a0d13ebdd 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/gapic_version.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.27.1" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/async_client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/async_client.py index bbece6914630..fb1a66abd5ac 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/async_client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/async_client.py @@ -52,6 +52,7 @@ from google.protobuf import timestamp_pb2 # type: ignore from google.cloud.dialogflowcx_v3beta1.services.flows import pagers +from google.cloud.dialogflowcx_v3beta1.types import advanced_settings from google.cloud.dialogflowcx_v3beta1.types import flow from google.cloud.dialogflowcx_v3beta1.types import flow as gcdc_flow from google.cloud.dialogflowcx_v3beta1.types import page, validation_message diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/client.py index 348c66c13077..99b6def70a66 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/client.py @@ -56,6 +56,7 @@ from google.protobuf import timestamp_pb2 # type: ignore from google.cloud.dialogflowcx_v3beta1.services.flows import pagers +from google.cloud.dialogflowcx_v3beta1.types import advanced_settings from google.cloud.dialogflowcx_v3beta1.types import flow from google.cloud.dialogflowcx_v3beta1.types import flow as gcdc_flow from google.cloud.dialogflowcx_v3beta1.types import page, validation_message diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/async_client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/async_client.py index dbc38d9b5217..563d1da4ada7 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/async_client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/async_client.py @@ -42,6 +42,8 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore @@ -780,6 +782,217 @@ async def sample_delete_intent(): metadata=metadata, ) + async def import_intents( + self, + request: Optional[Union[intent.ImportIntentsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Imports the specified intents into the agent. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ImportIntentsMetadata][google.cloud.dialogflow.cx.v3beta1.ImportIntentsMetadata] + - ``response``: + [ImportIntentsResponse][google.cloud.dialogflow.cx.v3beta1.ImportIntentsResponse] + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflowcx_v3beta1 + + async def sample_import_intents(): + # Create a client + client = dialogflowcx_v3beta1.IntentsAsyncClient() + + # Initialize request argument(s) + request = dialogflowcx_v3beta1.ImportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + ) + + # Make the request + operation = client.import_intents(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflowcx_v3beta1.types.ImportIntentsRequest, dict]]): + The request object. The request message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.dialogflowcx_v3beta1.types.ImportIntentsResponse` The response message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents]. + + """ + # Create or coerce a protobuf request object. + request = intent.ImportIntentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.import_intents, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + intent.ImportIntentsResponse, + metadata_type=intent.ImportIntentsMetadata, + ) + + # Done; return the response. + return response + + async def export_intents( + self, + request: Optional[Union[intent.ExportIntentsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Exports the selected intents. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ExportIntentsMetadata][google.cloud.dialogflow.cx.v3beta1.ExportIntentsMetadata] + - ``response``: + [ExportIntentsResponse][google.cloud.dialogflow.cx.v3beta1.ExportIntentsResponse] + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflowcx_v3beta1 + + async def sample_export_intents(): + # Create a client + client = dialogflowcx_v3beta1.IntentsAsyncClient() + + # Initialize request argument(s) + request = dialogflowcx_v3beta1.ExportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + intents=['intents_value1', 'intents_value2'], + ) + + # Make the request + operation = client.export_intents(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.dialogflowcx_v3beta1.types.ExportIntentsRequest, dict]]): + The request object. The request message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.dialogflowcx_v3beta1.types.ExportIntentsResponse` The response message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents]. + + """ + # Create or coerce a protobuf request object. + request = intent.ExportIntentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.export_intents, + default_timeout=None, + client_info=DEFAULT_CLIENT_INFO, + ) + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + intent.ExportIntentsResponse, + metadata_type=intent.ExportIntentsMetadata, + ) + + # Done; return the response. + return response + async def list_operations( self, request: Optional[operations_pb2.ListOperationsRequest] = None, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/client.py index ea9e503b9e15..e790305b3e36 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/client.py @@ -46,6 +46,8 @@ except AttributeError: # pragma: NO COVER OptionalRetry = Union[retries.Retry, object] # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore from google.cloud.location import locations_pb2 # type: ignore from google.longrunning import operations_pb2 # type: ignore from google.protobuf import field_mask_pb2 # type: ignore @@ -1039,6 +1041,219 @@ def sample_delete_intent(): metadata=metadata, ) + def import_intents( + self, + request: Optional[Union[intent.ImportIntentsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Imports the specified intents into the agent. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ImportIntentsMetadata][google.cloud.dialogflow.cx.v3beta1.ImportIntentsMetadata] + - ``response``: + [ImportIntentsResponse][google.cloud.dialogflow.cx.v3beta1.ImportIntentsResponse] + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflowcx_v3beta1 + + def sample_import_intents(): + # Create a client + client = dialogflowcx_v3beta1.IntentsClient() + + # Initialize request argument(s) + request = dialogflowcx_v3beta1.ImportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + ) + + # Make the request + operation = client.import_intents(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dialogflowcx_v3beta1.types.ImportIntentsRequest, dict]): + The request object. The request message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.dialogflowcx_v3beta1.types.ImportIntentsResponse` The response message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a intent.ImportIntentsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, intent.ImportIntentsRequest): + request = intent.ImportIntentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_intents] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + intent.ImportIntentsResponse, + metadata_type=intent.ImportIntentsMetadata, + ) + + # Done; return the response. + return response + + def export_intents( + self, + request: Optional[Union[intent.ExportIntentsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Exports the selected intents. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ExportIntentsMetadata][google.cloud.dialogflow.cx.v3beta1.ExportIntentsMetadata] + - ``response``: + [ExportIntentsResponse][google.cloud.dialogflow.cx.v3beta1.ExportIntentsResponse] + + .. code-block:: python + + # This snippet has been automatically generated and should be regarded as a + # code template only. + # It will require modifications to work: + # - It may require correct/in-range values for request initialization. + # - It may require specifying regional endpoints when creating the service + # client as shown in: + # https://googleapis.dev/python/google-api-core/latest/client_options.html + from google.cloud import dialogflowcx_v3beta1 + + def sample_export_intents(): + # Create a client + client = dialogflowcx_v3beta1.IntentsClient() + + # Initialize request argument(s) + request = dialogflowcx_v3beta1.ExportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + intents=['intents_value1', 'intents_value2'], + ) + + # Make the request + operation = client.export_intents(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.dialogflowcx_v3beta1.types.ExportIntentsRequest, dict]): + The request object. The request message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.dialogflowcx_v3beta1.types.ExportIntentsResponse` The response message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a intent.ExportIntentsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, intent.ExportIntentsRequest): + request = intent.ExportIntentsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.export_intents] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata((("parent", request.parent),)), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + intent.ExportIntentsResponse, + metadata_type=intent.ExportIntentsMetadata, + ) + + # Done; return the response. + return response + def __enter__(self) -> "IntentsClient": return self diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/base.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/base.py index e88dbc0a0148..400ba3f5f4d4 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/base.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/base.py @@ -18,7 +18,7 @@ import google.api_core from google.api_core import exceptions as core_exceptions -from google.api_core import gapic_v1 +from google.api_core import gapic_v1, operations_v1 from google.api_core import retry as retries import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore @@ -154,6 +154,16 @@ def _prep_wrapped_messages(self, client_info): default_timeout=None, client_info=client_info, ), + self.import_intents: gapic_v1.method.wrap_method( + self.import_intents, + default_timeout=None, + client_info=client_info, + ), + self.export_intents: gapic_v1.method.wrap_method( + self.export_intents, + default_timeout=None, + client_info=client_info, + ), } def close(self): @@ -165,6 +175,11 @@ def close(self): """ raise NotImplementedError() + @property + def operations_client(self): + """Return the client designed to process long-running operations.""" + raise NotImplementedError() + @property def list_intents( self, @@ -208,6 +223,24 @@ def delete_intent( ]: raise NotImplementedError() + @property + def import_intents( + self, + ) -> Callable[ + [intent.ImportIntentsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def export_intents( + self, + ) -> Callable[ + [intent.ExportIntentsRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + @property def list_operations( self, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/grpc.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/grpc.py index 39cdbd690906..f355df54da12 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/grpc.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/grpc.py @@ -16,7 +16,7 @@ from typing import Callable, Dict, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, grpc_helpers +from google.api_core import gapic_v1, grpc_helpers, operations_v1 import google.auth # type: ignore from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore @@ -115,6 +115,7 @@ def __init__( self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsClient] = None if api_mtls_endpoint: warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) @@ -233,6 +234,20 @@ def grpc_channel(self) -> grpc.Channel: """Return the channel designed to connect to this service.""" return self._grpc_channel + @property + def operations_client(self) -> operations_v1.OperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsClient(self.grpc_channel) + + # Return the client from cache. + return self._operations_client + @property def list_intents( self, @@ -372,6 +387,78 @@ def delete_intent(self) -> Callable[[intent.DeleteIntentRequest], empty_pb2.Empt ) return self._stubs["delete_intent"] + @property + def import_intents( + self, + ) -> Callable[[intent.ImportIntentsRequest], operations_pb2.Operation]: + r"""Return a callable for the import intents method over gRPC. + + Imports the specified intents into the agent. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ImportIntentsMetadata][google.cloud.dialogflow.cx.v3beta1.ImportIntentsMetadata] + - ``response``: + [ImportIntentsResponse][google.cloud.dialogflow.cx.v3beta1.ImportIntentsResponse] + + Returns: + Callable[[~.ImportIntentsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "import_intents" not in self._stubs: + self._stubs["import_intents"] = self.grpc_channel.unary_unary( + "/google.cloud.dialogflow.cx.v3beta1.Intents/ImportIntents", + request_serializer=intent.ImportIntentsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["import_intents"] + + @property + def export_intents( + self, + ) -> Callable[[intent.ExportIntentsRequest], operations_pb2.Operation]: + r"""Return a callable for the export intents method over gRPC. + + Exports the selected intents. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ExportIntentsMetadata][google.cloud.dialogflow.cx.v3beta1.ExportIntentsMetadata] + - ``response``: + [ExportIntentsResponse][google.cloud.dialogflow.cx.v3beta1.ExportIntentsResponse] + + Returns: + Callable[[~.ExportIntentsRequest], + ~.Operation]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "export_intents" not in self._stubs: + self._stubs["export_intents"] = self.grpc_channel.unary_unary( + "/google.cloud.dialogflow.cx.v3beta1.Intents/ExportIntents", + request_serializer=intent.ExportIntentsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["export_intents"] + def close(self): self.grpc_channel.close() diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/grpc_asyncio.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/grpc_asyncio.py index 5da41716dfcb..7f76d42b0ca1 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/grpc_asyncio.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/grpc_asyncio.py @@ -16,7 +16,7 @@ from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, grpc_helpers_async +from google.api_core import gapic_v1, grpc_helpers_async, operations_v1 from google.auth import credentials as ga_credentials # type: ignore from google.auth.transport.grpc import SslCredentials # type: ignore from google.cloud.location import locations_pb2 # type: ignore @@ -161,6 +161,7 @@ def __init__( self._grpc_channel = None self._ssl_channel_credentials = ssl_channel_credentials self._stubs: Dict[str, Callable] = {} + self._operations_client: Optional[operations_v1.OperationsAsyncClient] = None if api_mtls_endpoint: warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) @@ -236,6 +237,22 @@ def grpc_channel(self) -> aio.Channel: # Return the channel from cache. return self._grpc_channel + @property + def operations_client(self) -> operations_v1.OperationsAsyncClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Quick check: Only create a new client if we do not already have one. + if self._operations_client is None: + self._operations_client = operations_v1.OperationsAsyncClient( + self.grpc_channel + ) + + # Return the client from cache. + return self._operations_client + @property def list_intents( self, @@ -379,6 +396,78 @@ def delete_intent( ) return self._stubs["delete_intent"] + @property + def import_intents( + self, + ) -> Callable[[intent.ImportIntentsRequest], Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import intents method over gRPC. + + Imports the specified intents into the agent. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ImportIntentsMetadata][google.cloud.dialogflow.cx.v3beta1.ImportIntentsMetadata] + - ``response``: + [ImportIntentsResponse][google.cloud.dialogflow.cx.v3beta1.ImportIntentsResponse] + + Returns: + Callable[[~.ImportIntentsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "import_intents" not in self._stubs: + self._stubs["import_intents"] = self.grpc_channel.unary_unary( + "/google.cloud.dialogflow.cx.v3beta1.Intents/ImportIntents", + request_serializer=intent.ImportIntentsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["import_intents"] + + @property + def export_intents( + self, + ) -> Callable[[intent.ExportIntentsRequest], Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the export intents method over gRPC. + + Exports the selected intents. + + This method is a `long-running + operation `__. + The returned ``Operation`` type has the following + method-specific fields: + + - ``metadata``: + [ExportIntentsMetadata][google.cloud.dialogflow.cx.v3beta1.ExportIntentsMetadata] + - ``response``: + [ExportIntentsResponse][google.cloud.dialogflow.cx.v3beta1.ExportIntentsResponse] + + Returns: + Callable[[~.ExportIntentsRequest], + Awaitable[~.Operation]]: + A function that, when called, will call the underlying RPC + on the server. + """ + # Generate a "stub function" on-the-fly which will actually make + # the request. + # gRPC handles serialization and deserialization, so we just need + # to pass in the functions for each. + if "export_intents" not in self._stubs: + self._stubs["export_intents"] = self.grpc_channel.unary_unary( + "/google.cloud.dialogflow.cx.v3beta1.Intents/ExportIntents", + request_serializer=intent.ExportIntentsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["export_intents"] + def close(self): return self.grpc_channel.close() diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/rest.py index 1174d82bd7c5..a903f40f6537 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/intents/transports/rest.py @@ -20,7 +20,13 @@ from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union import warnings -from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming +from google.api_core import ( + gapic_v1, + operations_v1, + path_template, + rest_helpers, + rest_streaming, +) from google.api_core import exceptions as core_exceptions from google.api_core import retry as retries from google.auth import credentials as ga_credentials # type: ignore @@ -80,6 +86,14 @@ def pre_delete_intent(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata + def pre_export_intents(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_export_intents(self, response): + logging.log(f"Received response: {response}") + return response + def pre_get_intent(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -88,6 +102,14 @@ def post_get_intent(self, response): logging.log(f"Received response: {response}") return response + def pre_import_intents(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_intents(self, response): + logging.log(f"Received response: {response}") + return response + def pre_list_intents(self, request, metadata): logging.log(f"Received request: {request}") return request, metadata @@ -141,6 +163,27 @@ def pre_delete_intent( """ return request, metadata + def pre_export_intents( + self, request: intent.ExportIntentsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[intent.ExportIntentsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for export_intents + + Override in a subclass to manipulate the request or metadata + before they are sent to the Intents server. + """ + return request, metadata + + def post_export_intents( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for export_intents + + Override in a subclass to manipulate the response + after it is returned by the Intents server but before + it is returned to user code. + """ + return response + def pre_get_intent( self, request: intent.GetIntentRequest, metadata: Sequence[Tuple[str, str]] ) -> Tuple[intent.GetIntentRequest, Sequence[Tuple[str, str]]]: @@ -160,6 +203,27 @@ def post_get_intent(self, response: intent.Intent) -> intent.Intent: """ return response + def pre_import_intents( + self, request: intent.ImportIntentsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[intent.ImportIntentsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_intents + + Override in a subclass to manipulate the request or metadata + before they are sent to the Intents server. + """ + return request, metadata + + def post_import_intents( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for import_intents + + Override in a subclass to manipulate the response + after it is returned by the Intents server but before + it is returned to user code. + """ + return response + def pre_list_intents( self, request: intent.ListIntentsRequest, metadata: Sequence[Tuple[str, str]] ) -> Tuple[intent.ListIntentsRequest, Sequence[Tuple[str, str]]]: @@ -408,11 +472,70 @@ def __init__( self._session = AuthorizedSession( self._credentials, default_host=self.DEFAULT_HOST ) + self._operations_client: Optional[operations_v1.AbstractOperationsClient] = None if client_cert_source_for_mtls: self._session.configure_mtls_channel(client_cert_source_for_mtls) self._interceptor = interceptor or IntentsRestInterceptor() self._prep_wrapped_messages(client_info) + @property + def operations_client(self) -> operations_v1.AbstractOperationsClient: + """Create the client designed to process long-running operations. + + This property caches on the instance; repeated calls return the same + client. + """ + # Only create a new client if we do not already have one. + if self._operations_client is None: + http_options: Dict[str, List[Dict[str, str]]] = { + "google.longrunning.Operations.CancelOperation": [ + { + "method": "post", + "uri": "/v3beta1/{name=projects/*/operations/*}:cancel", + }, + { + "method": "post", + "uri": "/v3beta1/{name=projects/*/locations/*/operations/*}:cancel", + }, + ], + "google.longrunning.Operations.GetOperation": [ + { + "method": "get", + "uri": "/v3beta1/{name=projects/*/operations/*}", + }, + { + "method": "get", + "uri": "/v3beta1/{name=projects/*/locations/*/operations/*}", + }, + ], + "google.longrunning.Operations.ListOperations": [ + { + "method": "get", + "uri": "/v3beta1/{name=projects/*}/operations", + }, + { + "method": "get", + "uri": "/v3beta1/{name=projects/*/locations/*}/operations", + }, + ], + } + + rest_transport = operations_v1.OperationsRestTransport( + host=self._host, + # use the credentials which are saved + credentials=self._credentials, + scopes=self._scopes, + http_options=http_options, + path_prefix="v3beta1", + ) + + self._operations_client = operations_v1.AbstractOperationsClient( + transport=rest_transport + ) + + # Return the client from cache. + return self._operations_client + class _CreateIntent(IntentsRestStub): def __hash__(self): return hash("CreateIntent") @@ -591,6 +714,103 @@ def __call__( if response.status_code >= 400: raise core_exceptions.from_http_response(response) + class _ExportIntents(IntentsRestStub): + def __hash__(self): + return hash("ExportIntents") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: intent.ExportIntentsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the export intents method over HTTP. + + Args: + request (~.intent.ExportIntentsRequest): + The request object. The request message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v3beta1/{parent=projects/*/locations/*/agents/*}/intents:export", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_export_intents(request, metadata) + pb_request = intent.ExportIntentsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_export_intents(resp) + return resp + class _GetIntent(IntentsRestStub): def __hash__(self): return hash("GetIntent") @@ -685,6 +905,103 @@ def __call__( resp = self._interceptor.post_get_intent(resp) return resp + class _ImportIntents(IntentsRestStub): + def __hash__(self): + return hash("ImportIntents") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = {} + + @classmethod + def _get_unset_required_fields(cls, message_dict): + return { + k: v + for k, v in cls.__REQUIRED_FIELDS_DEFAULT_VALUES.items() + if k not in message_dict + } + + def __call__( + self, + request: intent.ImportIntentsRequest, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Optional[float] = None, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Call the import intents method over HTTP. + + Args: + request (~.intent.ImportIntentsRequest): + The request object. The request message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents]. + retry (google.api_core.retry.Retry): Designation of what errors, if any, + should be retried. + timeout (float): The timeout for this request. + metadata (Sequence[Tuple[str, str]]): Strings which should be + sent along with the request as metadata. + + Returns: + ~.operations_pb2.Operation: + This resource represents a + long-running operation that is the + result of a network API call. + + """ + + http_options: List[Dict[str, str]] = [ + { + "method": "post", + "uri": "/v3beta1/{parent=projects/*/locations/*/agents/*}/intents:import", + "body": "*", + }, + ] + request, metadata = self._interceptor.pre_import_intents(request, metadata) + pb_request = intent.ImportIntentsRequest.pb(request) + transcoded_request = path_template.transcode(http_options, pb_request) + + # Jsonify the request body + + body = json_format.MessageToJson( + transcoded_request["body"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + uri = transcoded_request["uri"] + method = transcoded_request["method"] + + # Jsonify the query params + query_params = json.loads( + json_format.MessageToJson( + transcoded_request["query_params"], + including_default_value_fields=False, + use_integers_for_enums=True, + ) + ) + query_params.update(self._get_unset_required_fields(query_params)) + + query_params["$alt"] = "json;enum-encoding=int" + + # Send the request + headers = dict(metadata) + headers["Content-Type"] = "application/json" + response = getattr(self._session, method)( + "{host}{uri}".format(host=self._host, uri=uri), + timeout=timeout, + headers=headers, + params=rest_helpers.flatten_query_params(query_params, strict=True), + data=body, + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + # Return the response + resp = operations_pb2.Operation() + json_format.Parse(response.content, resp, ignore_unknown_fields=True) + resp = self._interceptor.post_import_intents(resp) + return resp + class _ListIntents(IntentsRestStub): def __hash__(self): return hash("ListIntents") @@ -891,12 +1208,28 @@ def delete_intent(self) -> Callable[[intent.DeleteIntentRequest], empty_pb2.Empt # In C++ this would require a dynamic_cast return self._DeleteIntent(self._session, self._host, self._interceptor) # type: ignore + @property + def export_intents( + self, + ) -> Callable[[intent.ExportIntentsRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ExportIntents(self._session, self._host, self._interceptor) # type: ignore + @property def get_intent(self) -> Callable[[intent.GetIntentRequest], intent.Intent]: # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. # In C++ this would require a dynamic_cast return self._GetIntent(self._session, self._host, self._interceptor) # type: ignore + @property + def import_intents( + self, + ) -> Callable[[intent.ImportIntentsRequest], operations_pb2.Operation]: + # The return type is fine, but mypy isn't sophisticated enough to determine what's going on here. + # In C++ this would require a dynamic_cast + return self._ImportIntents(self._session, self._host, self._interceptor) # type: ignore + @property def list_intents( self, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/async_client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/async_client.py index e074ed3624c4..6430d5ed26ae 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/async_client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/async_client.py @@ -47,7 +47,7 @@ from google.protobuf import field_mask_pb2 # type: ignore from google.cloud.dialogflowcx_v3beta1.services.pages import pagers -from google.cloud.dialogflowcx_v3beta1.types import fulfillment +from google.cloud.dialogflowcx_v3beta1.types import advanced_settings, fulfillment from google.cloud.dialogflowcx_v3beta1.types import page from google.cloud.dialogflowcx_v3beta1.types import page as gcdc_page diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/client.py index 1d0159dd1dae..23e6c82ea146 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/client.py @@ -51,7 +51,7 @@ from google.protobuf import field_mask_pb2 # type: ignore from google.cloud.dialogflowcx_v3beta1.services.pages import pagers -from google.cloud.dialogflowcx_v3beta1.types import fulfillment +from google.cloud.dialogflowcx_v3beta1.types import advanced_settings, fulfillment from google.cloud.dialogflowcx_v3beta1.types import page from google.cloud.dialogflowcx_v3beta1.types import page as gcdc_page diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/__init__.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/__init__.py index b72780f5f9f7..e0a0c814015a 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/__init__.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/__init__.py @@ -123,10 +123,17 @@ from .fulfillment import Fulfillment from .gcs import GcsDestination from .generative_settings import GenerativeSettings +from .inline import InlineDestination, InlineSource from .intent import ( CreateIntentRequest, DeleteIntentRequest, + ExportIntentsMetadata, + ExportIntentsRequest, + ExportIntentsResponse, GetIntentRequest, + ImportIntentsMetadata, + ImportIntentsRequest, + ImportIntentsResponse, Intent, IntentView, ListIntentsRequest, @@ -358,9 +365,17 @@ "GcsDestination", "GenerativeSettings", "ImportStrategy", + "InlineDestination", + "InlineSource", "CreateIntentRequest", "DeleteIntentRequest", + "ExportIntentsMetadata", + "ExportIntentsRequest", + "ExportIntentsResponse", "GetIntentRequest", + "ImportIntentsMetadata", + "ImportIntentsRequest", + "ImportIntentsResponse", "Intent", "ListIntentsRequest", "ListIntentsResponse", diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/advanced_settings.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/advanced_settings.py index 5a4e23cc4a97..d46db404496e 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/advanced_settings.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/advanced_settings.py @@ -52,6 +52,14 @@ class AdvancedSettings(proto.Message): - Agent level - Flow level + dtmf_settings (google.cloud.dialogflowcx_v3beta1.types.AdvancedSettings.DtmfSettings): + Settings for DTMF. + Exposed at the following levels: + + - Agent level + - Flow level + - Page level + - Parameter level. logging_settings (google.cloud.dialogflowcx_v3beta1.types.AdvancedSettings.LoggingSettings): Settings for logging. Settings for Dialogflow History, Contact Center @@ -61,6 +69,39 @@ class AdvancedSettings(proto.Message): - Agent level. """ + class DtmfSettings(proto.Message): + r"""Define behaviors for DTMF (dual tone multi frequency). + + Attributes: + enabled (bool): + If true, incoming audio is processed for DTMF + (dual tone multi frequency) events. For example, + if the caller presses a button on their + telephone keypad and DTMF processing is enabled, + Dialogflow will detect the event (e.g. a "3" was + pressed) in the incoming audio and pass the + event to the bot to drive business logic (e.g. + when 3 is pressed, return the account balance). + max_digits (int): + Max length of DTMF digits. + finish_digit (str): + The digit that terminates a DTMF digit + sequence. + """ + + enabled: bool = proto.Field( + proto.BOOL, + number=1, + ) + max_digits: int = proto.Field( + proto.INT32, + number=2, + ) + finish_digit: str = proto.Field( + proto.STRING, + number=3, + ) + class LoggingSettings(proto.Message): r"""Define behaviors on logging. @@ -87,6 +128,11 @@ class LoggingSettings(proto.Message): number=2, message=gcs.GcsDestination, ) + dtmf_settings: DtmfSettings = proto.Field( + proto.MESSAGE, + number=5, + message=DtmfSettings, + ) logging_settings: LoggingSettings = proto.Field( proto.MESSAGE, number=6, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/flow.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/flow.py index 7aa7d7bed9d6..ed1a9faa7c4c 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/flow.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/flow.py @@ -26,6 +26,9 @@ page, validation_message, ) +from google.cloud.dialogflowcx_v3beta1.types import ( + advanced_settings as gcdc_advanced_settings, +) __protobuf__ = proto.module( package="google.cloud.dialogflow.cx.v3beta1", @@ -202,6 +205,11 @@ class Flow(proto.Message): for agent-level groups. nlu_settings (google.cloud.dialogflowcx_v3beta1.types.NluSettings): NLU related settings of the flow. + advanced_settings (google.cloud.dialogflowcx_v3beta1.types.AdvancedSettings): + Hierarchical advanced settings for this flow. + The settings exposed at the lower level + overrides the settings exposed at the higher + level. knowledge_connector_settings (google.cloud.dialogflowcx_v3beta1.types.KnowledgeConnectorSettings): Optional. Knowledge connector configuration. """ @@ -237,6 +245,11 @@ class Flow(proto.Message): number=11, message="NluSettings", ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=14, + message=gcdc_advanced_settings.AdvancedSettings, + ) knowledge_connector_settings: page.KnowledgeConnectorSettings = proto.Field( proto.MESSAGE, number=18, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/fulfillment.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/fulfillment.py index 2bb10c27a29a..1cf2b0956b31 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/fulfillment.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/fulfillment.py @@ -20,6 +20,9 @@ from google.protobuf import struct_pb2 # type: ignore import proto # type: ignore +from google.cloud.dialogflowcx_v3beta1.types import ( + advanced_settings as gcdc_advanced_settings, +) from google.cloud.dialogflowcx_v3beta1.types import response_message __protobuf__ = proto.module( @@ -85,6 +88,18 @@ class Fulfillment(proto.Message): webhook. conditional_cases (MutableSequence[google.cloud.dialogflowcx_v3beta1.types.Fulfillment.ConditionalCases]): Conditional cases for this fulfillment. + advanced_settings (google.cloud.dialogflowcx_v3beta1.types.AdvancedSettings): + Hierarchical advanced settings for this + fulfillment. The settings exposed at the lower + level overrides the settings exposed at the + higher level. + enable_generative_fallback (bool): + If the flag is true, the agent will utilize LLM to generate + a text response. If LLM generation fails, the defined + [responses][google.cloud.dialogflow.cx.v3beta1.Fulfillment.messages] + in the fulfillment will be respected. This flag is only + useful for fulfillments associated with no-match event + handlers. """ class SetParameterAction(proto.Message): @@ -218,6 +233,15 @@ class CaseContent(proto.Message): number=5, message=ConditionalCases, ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=7, + message=gcdc_advanced_settings.AdvancedSettings, + ) + enable_generative_fallback: bool = proto.Field( + proto.BOOL, + number=12, + ) __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/inline.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/inline.py new file mode 100644 index 000000000000..e90282739927 --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/inline.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +__protobuf__ = proto.module( + package="google.cloud.dialogflow.cx.v3beta1", + manifest={ + "InlineDestination", + "InlineSource", + }, +) + + +class InlineDestination(proto.Message): + r"""Inline destination for a Dialogflow operation that writes or exports + objects (e.g. [intents][google.cloud.dialogflow.cx.v3beta1.Intent]) + outside of Dialogflow. + + Attributes: + content (bytes): + Output only. The uncompressed byte content + for the objects. Only populated in responses. + """ + + content: bytes = proto.Field( + proto.BYTES, + number=1, + ) + + +class InlineSource(proto.Message): + r"""Inline source for a Dialogflow operation that reads or imports + objects (e.g. [intents][google.cloud.dialogflow.cx.v3beta1.Intent]) + into Dialogflow. + + Attributes: + content (bytes): + The uncompressed byte content for the + objects. + """ + + content: bytes = proto.Field( + proto.BYTES, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/intent.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/intent.py index 7434430f10c6..436d5cf2d481 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/intent.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/intent.py @@ -20,6 +20,8 @@ from google.protobuf import field_mask_pb2 # type: ignore import proto # type: ignore +from google.cloud.dialogflowcx_v3beta1.types import inline + __protobuf__ = proto.module( package="google.cloud.dialogflow.cx.v3beta1", manifest={ @@ -31,6 +33,12 @@ "CreateIntentRequest", "UpdateIntentRequest", "DeleteIntentRequest", + "ImportIntentsRequest", + "ImportIntentsResponse", + "ImportIntentsMetadata", + "ExportIntentsRequest", + "ExportIntentsResponse", + "ExportIntentsMetadata", }, ) @@ -484,4 +492,289 @@ class DeleteIntentRequest(proto.Message): ) +class ImportIntentsRequest(proto.Message): + r"""The request message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + parent (str): + Required. The agent to import the intents into. Format: + ``projects//locations//agents/``. + intents_uri (str): + The `Google Cloud + Storage `__ URI to + import intents from. The format of this URI must be + ``gs:///``. + + Dialogflow performs a read operation for the Cloud Storage + object on the caller's behalf, so your request + authentication must have read permissions for the object. + For more information, see `Dialogflow access + control `__. + + This field is a member of `oneof`_ ``intents``. + intents_content (google.cloud.dialogflowcx_v3beta1.types.InlineSource): + Uncompressed byte content of intents. + + This field is a member of `oneof`_ ``intents``. + merge_option (google.cloud.dialogflowcx_v3beta1.types.ImportIntentsRequest.MergeOption): + Merge option for importing intents. If not specified, + ``REJECT`` is assumed. + """ + + class MergeOption(proto.Enum): + r"""Merge option when display name conflicts exist during import. + + Values: + MERGE_OPTION_UNSPECIFIED (0): + Unspecified. Should not be used. + REJECT (1): + DEPRECATED: Please use + [REPORT_CONFLICT][ImportIntentsRequest.REPORT_CONFLICT] + instead. Fail the request if there are intents whose display + names conflict with the display names of intents in the + agent. + REPLACE (2): + Replace the original intent in the agent with + the new intent when display name conflicts + exist. + MERGE (3): + Merge the original intent with the new intent + when display name conflicts exist. + RENAME (4): + Create new intents with new display names to + differentiate them from the existing intents + when display name conflicts exist. + REPORT_CONFLICT (5): + Report conflict information if display names + conflict is detected. Otherwise, import intents. + KEEP (6): + Keep the original intent and discard the + conflicting new intent when display name + conflicts exist. + """ + MERGE_OPTION_UNSPECIFIED = 0 + REJECT = 1 + REPLACE = 2 + MERGE = 3 + RENAME = 4 + REPORT_CONFLICT = 5 + KEEP = 6 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + intents_uri: str = proto.Field( + proto.STRING, + number=2, + oneof="intents", + ) + intents_content: inline.InlineSource = proto.Field( + proto.MESSAGE, + number=3, + oneof="intents", + message=inline.InlineSource, + ) + merge_option: MergeOption = proto.Field( + proto.ENUM, + number=4, + enum=MergeOption, + ) + + +class ImportIntentsResponse(proto.Message): + r"""The response message for + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents]. + + Attributes: + intents (MutableSequence[str]): + The unique identifier of the imported intents. Format: + ``projects//locations//agents//intents/``. + conflicting_resources (google.cloud.dialogflowcx_v3beta1.types.ImportIntentsResponse.ConflictingResources): + Info which resources have conflicts when + [REPORT_CONFLICT][ImportIntentsResponse.REPORT_CONFLICT] + merge_option is set in ImportIntentsRequest. + """ + + class ConflictingResources(proto.Message): + r"""Conflicting resources detected during the import process. Only + filled when [REPORT_CONFLICT][ImportIntentsResponse.REPORT_CONFLICT] + is set in the request and there are conflicts in the display names. + + Attributes: + intent_display_names (MutableSequence[str]): + Display names of conflicting intents. + entity_display_names (MutableSequence[str]): + Display names of conflicting entities. + """ + + intent_display_names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + entity_display_names: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + intents: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + conflicting_resources: ConflictingResources = proto.Field( + proto.MESSAGE, + number=2, + message=ConflictingResources, + ) + + +class ImportIntentsMetadata(proto.Message): + r"""Metadata returned for the + [Intents.ImportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents] + long running operation. + + """ + + +class ExportIntentsRequest(proto.Message): + r"""The request message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + parent (str): + Required. The name of the parent agent to export intents. + Format: + ``projects//locations//agents/``. + intents (MutableSequence[str]): + Required. The name of the intents to export. Format: + ``projects//locations//agents//intents/``. + intents_uri (str): + Optional. The `Google Cloud + Storage `__ URI to + export the intents to. The format of this URI must be + ``gs:///``. + + Dialogflow performs a write operation for the Cloud Storage + object on the caller's behalf, so your request + authentication must have write permissions for the object. + For more information, see `Dialogflow access + control `__. + + This field is a member of `oneof`_ ``destination``. + intents_content_inline (bool): + Optional. The option to return the serialized + intents inline. + + This field is a member of `oneof`_ ``destination``. + data_format (google.cloud.dialogflowcx_v3beta1.types.ExportIntentsRequest.DataFormat): + Optional. The data format of the exported intents. If not + specified, ``BLOB`` is assumed. + """ + + class DataFormat(proto.Enum): + r"""Data format of the exported intents. + + Values: + DATA_FORMAT_UNSPECIFIED (0): + Unspecified format. Treated as ``BLOB``. + BLOB (1): + Intents will be exported as raw bytes. + JSON (2): + Intents will be exported in JSON format. + CSV (3): + Intents will be exported in CSV format. + """ + DATA_FORMAT_UNSPECIFIED = 0 + BLOB = 1 + JSON = 2 + CSV = 3 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + intents: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + intents_uri: str = proto.Field( + proto.STRING, + number=3, + oneof="destination", + ) + intents_content_inline: bool = proto.Field( + proto.BOOL, + number=4, + oneof="destination", + ) + data_format: DataFormat = proto.Field( + proto.ENUM, + number=5, + enum=DataFormat, + ) + + +class ExportIntentsResponse(proto.Message): + r"""The response message for + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents]. + + This message has `oneof`_ fields (mutually exclusive fields). + For each oneof, at most one member field can be set at the same time. + Setting any member of the oneof automatically clears all other + members. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + intents_uri (str): + The URI to a file containing the exported intents. This + field is populated only if ``intents_uri`` is specified in + [ExportIntentsRequest][google.cloud.dialogflow.cx.v3beta1.ExportIntentsRequest]. + + This field is a member of `oneof`_ ``intents``. + intents_content (google.cloud.dialogflowcx_v3beta1.types.InlineDestination): + Uncompressed byte content for intents. This field is + populated only if ``intents_content_inline`` is set to true + in + [ExportIntentsRequest][google.cloud.dialogflow.cx.v3beta1.ExportIntentsRequest]. + + This field is a member of `oneof`_ ``intents``. + """ + + intents_uri: str = proto.Field( + proto.STRING, + number=1, + oneof="intents", + ) + intents_content: inline.InlineDestination = proto.Field( + proto.MESSAGE, + number=2, + oneof="intents", + message=inline.InlineDestination, + ) + + +class ExportIntentsMetadata(proto.Message): + r"""Metadata returned for the + [Intents.ExportIntents][google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents] + long running operation. + + """ + + __all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/page.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/page.py index f81d160d8ec9..96fc1327fbe2 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/page.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/page.py @@ -22,6 +22,9 @@ import proto # type: ignore from google.cloud.dialogflowcx_v3beta1.types import data_store_connection, fulfillment +from google.cloud.dialogflowcx_v3beta1.types import ( + advanced_settings as gcdc_advanced_settings, +) __protobuf__ = proto.module( package="google.cloud.dialogflow.cx.v3beta1", @@ -127,6 +130,11 @@ class Page(proto.Message): Handlers associated with the page to handle events such as webhook errors, no match or no input. + advanced_settings (google.cloud.dialogflowcx_v3beta1.types.AdvancedSettings): + Hierarchical advanced settings for this page. + The settings exposed at the lower level + overrides the settings exposed at the higher + level. knowledge_connector_settings (google.cloud.dialogflowcx_v3beta1.types.KnowledgeConnectorSettings): Optional. Knowledge connector configuration. """ @@ -163,6 +171,11 @@ class Page(proto.Message): number=10, message="EventHandler", ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=13, + message=gcdc_advanced_settings.AdvancedSettings, + ) knowledge_connector_settings: "KnowledgeConnectorSettings" = proto.Field( proto.MESSAGE, number=18, @@ -223,6 +236,11 @@ class Parameter(proto.Message): parameter level redaction or [entity type level redaction][google.cloud.dialogflow.cx.v3beta1.EntityType.redact] is enabled. + advanced_settings (google.cloud.dialogflowcx_v3beta1.types.AdvancedSettings): + Hierarchical advanced settings for this + parameter. The settings exposed at the lower + level overrides the settings exposed at the + higher level. """ class FillBehavior(proto.Message): @@ -317,6 +335,11 @@ class FillBehavior(proto.Message): proto.BOOL, number=11, ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=12, + message=gcdc_advanced_settings.AdvancedSettings, + ) parameters: MutableSequence[Parameter] = proto.RepeatedField( proto.MESSAGE, diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/session.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/session.py index 7e8a33397b69..24ed960b8c9f 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/session.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/types/session.py @@ -28,6 +28,9 @@ response_message, session_entity_type, ) +from google.cloud.dialogflowcx_v3beta1.types import ( + advanced_settings as gcdc_advanced_settings, +) from google.cloud.dialogflowcx_v3beta1.types import audio_config from google.cloud.dialogflowcx_v3beta1.types import intent as gcdc_intent @@ -1073,6 +1076,16 @@ class QueryResult(proto.Message): [``analyze_query_text_sentiment``] [google.cloud.dialogflow.cx.v3beta1.QueryParameters.analyze_query_text_sentiment], specified in the request. + advanced_settings (google.cloud.dialogflowcx_v3beta1.types.AdvancedSettings): + Returns the current advanced settings + including IVR settings. Even though the + operations configured by these settings are + performed by Dialogflow, the client may need to + perform special logic at the moment. For + example, if Dialogflow exports audio to Google + Cloud Storage, then the client may need to wait + for the resulting object to appear in the bucket + before proceeding. """ text: str = proto.Field( @@ -1156,6 +1169,11 @@ class QueryResult(proto.Message): number=17, message="SentimentAnalysisResult", ) + advanced_settings: gcdc_advanced_settings.AdvancedSettings = proto.Field( + proto.MESSAGE, + number=21, + message=gcdc_advanced_settings.AdvancedSettings, + ) class TextInput(proto.Message): diff --git a/packages/google-cloud-dialogflow-cx/noxfile.py b/packages/google-cloud-dialogflow-cx/noxfile.py index 9a2acd8b6787..be54712bfa8f 100644 --- a/packages/google-cloud-dialogflow-cx/noxfile.py +++ b/packages/google-cloud-dialogflow-cx/noxfile.py @@ -46,7 +46,7 @@ UNIT_TEST_EXTRAS = [] UNIT_TEST_EXTRAS_BY_PYTHON = {} -SYSTEM_TEST_PYTHON_VERSIONS = [] +SYSTEM_TEST_PYTHON_VERSIONS = ["3.8", "3.9", "3.10", "3.11"] SYSTEM_TEST_STANDARD_DEPENDENCIES = [ "mock", "pytest", @@ -405,24 +405,3 @@ def prerelease_deps(session): session.run("python", "-c", "import google.auth; print(google.auth.__version__)") session.run("py.test", "tests/unit") - - system_test_path = os.path.join("tests", "system.py") - system_test_folder_path = os.path.join("tests", "system") - - # Only run system tests if found. - if os.path.exists(system_test_path): - session.run( - "py.test", - "--verbose", - f"--junitxml=system_{session.python}_sponge_log.xml", - system_test_path, - *session.posargs, - ) - if os.path.exists(system_test_folder_path): - session.run( - "py.test", - "--verbose", - f"--junitxml=system_{session.python}_sponge_log.xml", - system_test_folder_path, - *session.posargs, - ) diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_export_intents_async.py b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_export_intents_async.py new file mode 100644 index 000000000000..c626f785ae22 --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_export_intents_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportIntents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow-cx + + +# [START dialogflow_v3_generated_Intents_ExportIntents_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflowcx_v3 + + +async def sample_export_intents(): + # Create a client + client = dialogflowcx_v3.IntentsAsyncClient() + + # Initialize request argument(s) + request = dialogflowcx_v3.ExportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + intents=['intents_value1', 'intents_value2'], + ) + + # Make the request + operation = client.export_intents(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END dialogflow_v3_generated_Intents_ExportIntents_async] diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_export_intents_sync.py b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_export_intents_sync.py new file mode 100644 index 000000000000..ae1813e80b3e --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_export_intents_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportIntents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow-cx + + +# [START dialogflow_v3_generated_Intents_ExportIntents_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflowcx_v3 + + +def sample_export_intents(): + # Create a client + client = dialogflowcx_v3.IntentsClient() + + # Initialize request argument(s) + request = dialogflowcx_v3.ExportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + intents=['intents_value1', 'intents_value2'], + ) + + # Make the request + operation = client.export_intents(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END dialogflow_v3_generated_Intents_ExportIntents_sync] diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_import_intents_async.py b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_import_intents_async.py new file mode 100644 index 000000000000..0aa85a8896bb --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_import_intents_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportIntents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow-cx + + +# [START dialogflow_v3_generated_Intents_ImportIntents_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflowcx_v3 + + +async def sample_import_intents(): + # Create a client + client = dialogflowcx_v3.IntentsAsyncClient() + + # Initialize request argument(s) + request = dialogflowcx_v3.ImportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + ) + + # Make the request + operation = client.import_intents(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END dialogflow_v3_generated_Intents_ImportIntents_async] diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_import_intents_sync.py b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_import_intents_sync.py new file mode 100644 index 000000000000..4eba2ac58198 --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3_generated_intents_import_intents_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportIntents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow-cx + + +# [START dialogflow_v3_generated_Intents_ImportIntents_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflowcx_v3 + + +def sample_import_intents(): + # Create a client + client = dialogflowcx_v3.IntentsClient() + + # Initialize request argument(s) + request = dialogflowcx_v3.ImportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + ) + + # Make the request + operation = client.import_intents(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END dialogflow_v3_generated_Intents_ImportIntents_sync] diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_export_intents_async.py b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_export_intents_async.py new file mode 100644 index 000000000000..42255cc58257 --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_export_intents_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportIntents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow-cx + + +# [START dialogflow_v3beta1_generated_Intents_ExportIntents_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflowcx_v3beta1 + + +async def sample_export_intents(): + # Create a client + client = dialogflowcx_v3beta1.IntentsAsyncClient() + + # Initialize request argument(s) + request = dialogflowcx_v3beta1.ExportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + intents=['intents_value1', 'intents_value2'], + ) + + # Make the request + operation = client.export_intents(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END dialogflow_v3beta1_generated_Intents_ExportIntents_async] diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_export_intents_sync.py b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_export_intents_sync.py new file mode 100644 index 000000000000..68da6becfa75 --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_export_intents_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ExportIntents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow-cx + + +# [START dialogflow_v3beta1_generated_Intents_ExportIntents_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflowcx_v3beta1 + + +def sample_export_intents(): + # Create a client + client = dialogflowcx_v3beta1.IntentsClient() + + # Initialize request argument(s) + request = dialogflowcx_v3beta1.ExportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + intents=['intents_value1', 'intents_value2'], + ) + + # Make the request + operation = client.export_intents(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END dialogflow_v3beta1_generated_Intents_ExportIntents_sync] diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_import_intents_async.py b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_import_intents_async.py new file mode 100644 index 000000000000..65447b5b14f7 --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_import_intents_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportIntents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow-cx + + +# [START dialogflow_v3beta1_generated_Intents_ImportIntents_async] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflowcx_v3beta1 + + +async def sample_import_intents(): + # Create a client + client = dialogflowcx_v3beta1.IntentsAsyncClient() + + # Initialize request argument(s) + request = dialogflowcx_v3beta1.ImportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + ) + + # Make the request + operation = client.import_intents(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END dialogflow_v3beta1_generated_Intents_ImportIntents_async] diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_import_intents_sync.py b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_import_intents_sync.py new file mode 100644 index 000000000000..20eafe101d3b --- /dev/null +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/dialogflow_v3beta1_generated_intents_import_intents_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 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. +# +# Generated code. DO NOT EDIT! +# +# Snippet for ImportIntents +# NOTE: This snippet has been automatically generated for illustrative purposes only. +# It may require modifications to work in your environment. + +# To install the latest published package dependency, execute the following: +# python3 -m pip install google-cloud-dialogflow-cx + + +# [START dialogflow_v3beta1_generated_Intents_ImportIntents_sync] +# This snippet has been automatically generated and should be regarded as a +# code template only. +# It will require modifications to work: +# - It may require correct/in-range values for request initialization. +# - It may require specifying regional endpoints when creating the service +# client as shown in: +# https://googleapis.dev/python/google-api-core/latest/client_options.html +from google.cloud import dialogflowcx_v3beta1 + + +def sample_import_intents(): + # Create a client + client = dialogflowcx_v3beta1.IntentsClient() + + # Initialize request argument(s) + request = dialogflowcx_v3beta1.ImportIntentsRequest( + intents_uri="intents_uri_value", + parent="parent_value", + ) + + # Make the request + operation = client.import_intents(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END dialogflow_v3beta1_generated_Intents_ImportIntents_sync] diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3.json b/packages/google-cloud-dialogflow-cx/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3.json index 2ee987e2ff77..078d3ee16252 100644 --- a/packages/google-cloud-dialogflow-cx/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3.json +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dialogflow-cx", - "version": "1.27.1" + "version": "0.1.0" }, "snippets": [ { @@ -7743,6 +7743,159 @@ ], "title": "dialogflow_v3_generated_intents_delete_intent_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflowcx_v3.IntentsAsyncClient", + "shortName": "IntentsAsyncClient" + }, + "fullName": "google.cloud.dialogflowcx_v3.IntentsAsyncClient.export_intents", + "method": { + "fullName": "google.cloud.dialogflow.cx.v3.Intents.ExportIntents", + "service": { + "fullName": "google.cloud.dialogflow.cx.v3.Intents", + "shortName": "Intents" + }, + "shortName": "ExportIntents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflowcx_v3.types.ExportIntentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "export_intents" + }, + "description": "Sample for ExportIntents", + "file": "dialogflow_v3_generated_intents_export_intents_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v3_generated_Intents_ExportIntents_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v3_generated_intents_export_intents_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflowcx_v3.IntentsClient", + "shortName": "IntentsClient" + }, + "fullName": "google.cloud.dialogflowcx_v3.IntentsClient.export_intents", + "method": { + "fullName": "google.cloud.dialogflow.cx.v3.Intents.ExportIntents", + "service": { + "fullName": "google.cloud.dialogflow.cx.v3.Intents", + "shortName": "Intents" + }, + "shortName": "ExportIntents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflowcx_v3.types.ExportIntentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "export_intents" + }, + "description": "Sample for ExportIntents", + "file": "dialogflow_v3_generated_intents_export_intents_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v3_generated_Intents_ExportIntents_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v3_generated_intents_export_intents_sync.py" + }, { "canonical": true, "clientMethod": { @@ -7904,6 +8057,159 @@ ], "title": "dialogflow_v3_generated_intents_get_intent_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflowcx_v3.IntentsAsyncClient", + "shortName": "IntentsAsyncClient" + }, + "fullName": "google.cloud.dialogflowcx_v3.IntentsAsyncClient.import_intents", + "method": { + "fullName": "google.cloud.dialogflow.cx.v3.Intents.ImportIntents", + "service": { + "fullName": "google.cloud.dialogflow.cx.v3.Intents", + "shortName": "Intents" + }, + "shortName": "ImportIntents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflowcx_v3.types.ImportIntentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "import_intents" + }, + "description": "Sample for ImportIntents", + "file": "dialogflow_v3_generated_intents_import_intents_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v3_generated_Intents_ImportIntents_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v3_generated_intents_import_intents_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflowcx_v3.IntentsClient", + "shortName": "IntentsClient" + }, + "fullName": "google.cloud.dialogflowcx_v3.IntentsClient.import_intents", + "method": { + "fullName": "google.cloud.dialogflow.cx.v3.Intents.ImportIntents", + "service": { + "fullName": "google.cloud.dialogflow.cx.v3.Intents", + "shortName": "Intents" + }, + "shortName": "ImportIntents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflowcx_v3.types.ImportIntentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "import_intents" + }, + "description": "Sample for ImportIntents", + "file": "dialogflow_v3_generated_intents_import_intents_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v3_generated_Intents_ImportIntents_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v3_generated_intents_import_intents_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-dialogflow-cx/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3beta1.json b/packages/google-cloud-dialogflow-cx/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3beta1.json index 758da063a8e9..c268e8afeef3 100644 --- a/packages/google-cloud-dialogflow-cx/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3beta1.json +++ b/packages/google-cloud-dialogflow-cx/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.cx.v3beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dialogflow-cx", - "version": "1.27.1" + "version": "0.1.0" }, "snippets": [ { @@ -7743,6 +7743,159 @@ ], "title": "dialogflow_v3beta1_generated_intents_delete_intent_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflowcx_v3beta1.IntentsAsyncClient", + "shortName": "IntentsAsyncClient" + }, + "fullName": "google.cloud.dialogflowcx_v3beta1.IntentsAsyncClient.export_intents", + "method": { + "fullName": "google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents", + "service": { + "fullName": "google.cloud.dialogflow.cx.v3beta1.Intents", + "shortName": "Intents" + }, + "shortName": "ExportIntents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflowcx_v3beta1.types.ExportIntentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "export_intents" + }, + "description": "Sample for ExportIntents", + "file": "dialogflow_v3beta1_generated_intents_export_intents_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v3beta1_generated_Intents_ExportIntents_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v3beta1_generated_intents_export_intents_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflowcx_v3beta1.IntentsClient", + "shortName": "IntentsClient" + }, + "fullName": "google.cloud.dialogflowcx_v3beta1.IntentsClient.export_intents", + "method": { + "fullName": "google.cloud.dialogflow.cx.v3beta1.Intents.ExportIntents", + "service": { + "fullName": "google.cloud.dialogflow.cx.v3beta1.Intents", + "shortName": "Intents" + }, + "shortName": "ExportIntents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflowcx_v3beta1.types.ExportIntentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "export_intents" + }, + "description": "Sample for ExportIntents", + "file": "dialogflow_v3beta1_generated_intents_export_intents_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v3beta1_generated_Intents_ExportIntents_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v3beta1_generated_intents_export_intents_sync.py" + }, { "canonical": true, "clientMethod": { @@ -7904,6 +8057,159 @@ ], "title": "dialogflow_v3beta1_generated_intents_get_intent_sync.py" }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.dialogflowcx_v3beta1.IntentsAsyncClient", + "shortName": "IntentsAsyncClient" + }, + "fullName": "google.cloud.dialogflowcx_v3beta1.IntentsAsyncClient.import_intents", + "method": { + "fullName": "google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents", + "service": { + "fullName": "google.cloud.dialogflow.cx.v3beta1.Intents", + "shortName": "Intents" + }, + "shortName": "ImportIntents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflowcx_v3beta1.types.ImportIntentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation_async.AsyncOperation", + "shortName": "import_intents" + }, + "description": "Sample for ImportIntents", + "file": "dialogflow_v3beta1_generated_intents_import_intents_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v3beta1_generated_Intents_ImportIntents_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v3beta1_generated_intents_import_intents_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.dialogflowcx_v3beta1.IntentsClient", + "shortName": "IntentsClient" + }, + "fullName": "google.cloud.dialogflowcx_v3beta1.IntentsClient.import_intents", + "method": { + "fullName": "google.cloud.dialogflow.cx.v3beta1.Intents.ImportIntents", + "service": { + "fullName": "google.cloud.dialogflow.cx.v3beta1.Intents", + "shortName": "Intents" + }, + "shortName": "ImportIntents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.dialogflowcx_v3beta1.types.ImportIntentsRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api_core.operation.Operation", + "shortName": "import_intents" + }, + "description": "Sample for ImportIntents", + "file": "dialogflow_v3beta1_generated_intents_import_intents_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "dialogflow_v3beta1_generated_Intents_ImportIntents_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "dialogflow_v3beta1_generated_intents_import_intents_sync.py" + }, { "canonical": true, "clientMethod": { diff --git a/packages/google-cloud-dialogflow-cx/scripts/fixup_dialogflowcx_v3_keywords.py b/packages/google-cloud-dialogflow-cx/scripts/fixup_dialogflowcx_v3_keywords.py index fd5c1515eb6f..2f631a4ede1d 100644 --- a/packages/google-cloud-dialogflow-cx/scripts/fixup_dialogflowcx_v3_keywords.py +++ b/packages/google-cloud-dialogflow-cx/scripts/fixup_dialogflowcx_v3_keywords.py @@ -72,6 +72,7 @@ class dialogflowcxCallTransformer(cst.CSTTransformer): 'detect_intent': ('session', 'query_input', 'query_params', 'output_audio_config', ), 'export_agent': ('name', 'agent_uri', 'data_format', 'environment', 'git_destination', 'include_bigquery_export_settings', ), 'export_flow': ('name', 'flow_uri', 'include_referenced_flows', ), + 'export_intents': ('parent', 'intents', 'intents_uri', 'intents_content_inline', 'data_format', ), 'export_test_cases': ('parent', 'gcs_uri', 'data_format', 'filter', ), 'fulfill_intent': ('match_intent_request', 'match', 'output_audio_config', ), 'get_agent': ('name', ), @@ -94,6 +95,7 @@ class dialogflowcxCallTransformer(cst.CSTTransformer): 'get_version': ('name', ), 'get_webhook': ('name', ), 'import_flow': ('parent', 'flow_uri', 'flow_content', 'import_option', 'flow_import_strategy', ), + 'import_intents': ('parent', 'intents_uri', 'intents_content', 'merge_option', ), 'import_test_cases': ('parent', 'gcs_uri', 'content', ), 'list_agents': ('parent', 'page_size', 'page_token', ), 'list_changelogs': ('parent', 'filter', 'page_size', 'page_token', ), diff --git a/packages/google-cloud-dialogflow-cx/scripts/fixup_dialogflowcx_v3beta1_keywords.py b/packages/google-cloud-dialogflow-cx/scripts/fixup_dialogflowcx_v3beta1_keywords.py index fd5c1515eb6f..2f631a4ede1d 100644 --- a/packages/google-cloud-dialogflow-cx/scripts/fixup_dialogflowcx_v3beta1_keywords.py +++ b/packages/google-cloud-dialogflow-cx/scripts/fixup_dialogflowcx_v3beta1_keywords.py @@ -72,6 +72,7 @@ class dialogflowcxCallTransformer(cst.CSTTransformer): 'detect_intent': ('session', 'query_input', 'query_params', 'output_audio_config', ), 'export_agent': ('name', 'agent_uri', 'data_format', 'environment', 'git_destination', 'include_bigquery_export_settings', ), 'export_flow': ('name', 'flow_uri', 'include_referenced_flows', ), + 'export_intents': ('parent', 'intents', 'intents_uri', 'intents_content_inline', 'data_format', ), 'export_test_cases': ('parent', 'gcs_uri', 'data_format', 'filter', ), 'fulfill_intent': ('match_intent_request', 'match', 'output_audio_config', ), 'get_agent': ('name', ), @@ -94,6 +95,7 @@ class dialogflowcxCallTransformer(cst.CSTTransformer): 'get_version': ('name', ), 'get_webhook': ('name', ), 'import_flow': ('parent', 'flow_uri', 'flow_content', 'import_option', 'flow_import_strategy', ), + 'import_intents': ('parent', 'intents_uri', 'intents_content', 'merge_option', ), 'import_test_cases': ('parent', 'gcs_uri', 'content', ), 'list_agents': ('parent', 'page_size', 'page_token', ), 'list_changelogs': ('parent', 'filter', 'page_size', 'page_token', ), diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_agents.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_agents.py index 0ddbd755c4d2..79aa06c42bfa 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_agents.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_agents.py @@ -4019,6 +4019,11 @@ def test_create_agent_rest(request_type): "locked": True, "advanced_settings": { "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, "logging_settings": { "enable_stackdriver_logging": True, "enable_interaction_logging": True, @@ -4255,6 +4260,11 @@ def test_create_agent_rest_bad_request( "locked": True, "advanced_settings": { "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, "logging_settings": { "enable_stackdriver_logging": True, "enable_interaction_logging": True, @@ -4385,6 +4395,11 @@ def test_update_agent_rest(request_type): "locked": True, "advanced_settings": { "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, "logging_settings": { "enable_stackdriver_logging": True, "enable_interaction_logging": True, @@ -4612,6 +4627,11 @@ def test_update_agent_rest_bad_request( "locked": True, "advanced_settings": { "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, "logging_settings": { "enable_stackdriver_logging": True, "enable_interaction_logging": True, diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_flows.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_flows.py index 75597d73169b..e1fdbb8723e7 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_flows.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_flows.py @@ -63,14 +63,15 @@ pagers, transports, ) +from google.cloud.dialogflowcx_v3.types import advanced_settings, data_store_connection from google.cloud.dialogflowcx_v3.types import ( fulfillment, + gcs, import_strategy, page, response_message, validation_message, ) -from google.cloud.dialogflowcx_v3.types import data_store_connection from google.cloud.dialogflowcx_v3.types import flow from google.cloud.dialogflowcx_v3.types import flow as gcdc_flow @@ -3067,6 +3068,19 @@ def test_create_flow_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3090,6 +3104,7 @@ def test_create_flow_rest(request_type): "classification_threshold": 0.25520000000000004, "model_training_mode": 1, }, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -3361,6 +3376,19 @@ def test_create_flow_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3384,6 +3412,7 @@ def test_create_flow_rest_bad_request( "classification_threshold": 0.25520000000000004, "model_training_mode": 1, }, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -4429,6 +4458,19 @@ def test_update_flow_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -4452,6 +4494,7 @@ def test_update_flow_rest(request_type): "classification_threshold": 0.25520000000000004, "model_training_mode": 1, }, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -4727,6 +4770,19 @@ def test_update_flow_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -4750,6 +4806,7 @@ def test_update_flow_rest_bad_request( "classification_threshold": 0.25520000000000004, "model_training_mode": 1, }, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_intents.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_intents.py index 24644e6af410..4e52eb65f8cc 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_intents.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_intents.py @@ -26,9 +26,18 @@ import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) from google.api_core import client_options from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError @@ -51,6 +60,7 @@ pagers, transports, ) +from google.cloud.dialogflowcx_v3.types import inline from google.cloud.dialogflowcx_v3.types import intent from google.cloud.dialogflowcx_v3.types import intent as gcdc_intent @@ -2059,6 +2069,294 @@ async def test_delete_intent_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + intent.ImportIntentsRequest, + dict, + ], +) +def test_import_intents(request_type, transport: str = "grpc"): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.import_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ImportIntentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_intents_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + client.import_intents() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ImportIntentsRequest() + + +@pytest.mark.asyncio +async def test_import_intents_async( + transport: str = "grpc_asyncio", request_type=intent.ImportIntentsRequest +): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.import_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ImportIntentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_intents_async_from_dict(): + await test_import_intents_async(request_type=dict) + + +def test_import_intents_field_headers(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = intent.ImportIntentsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.import_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_import_intents_field_headers_async(): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = intent.ImportIntentsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.import_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.parametrize( + "request_type", + [ + intent.ExportIntentsRequest, + dict, + ], +) +def test_export_intents(request_type, transport: str = "grpc"): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.export_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ExportIntentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_export_intents_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + client.export_intents() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ExportIntentsRequest() + + +@pytest.mark.asyncio +async def test_export_intents_async( + transport: str = "grpc_asyncio", request_type=intent.ExportIntentsRequest +): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.export_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ExportIntentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_export_intents_async_from_dict(): + await test_export_intents_async(request_type=dict) + + +def test_export_intents_field_headers(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = intent.ExportIntentsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.export_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_export_intents_field_headers_async(): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = intent.ExportIntentsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.export_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + @pytest.mark.parametrize( "request_type", [ @@ -3598,28 +3896,446 @@ def test_delete_intent_rest_error(): ) -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.IntentsGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = IntentsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.IntentsGrpcTransport( +@pytest.mark.parametrize( + "request_type", + [ + intent.ImportIntentsRequest, + dict, + ], +) +def test_import_intents_rest(request_type): + client = IntentsClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = IntentsClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - # It is an error to provide an api_key and a transport instance. + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/agents/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.import_intents(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_intents_rest_required_fields(request_type=intent.ImportIntentsRequest): + transport_class = transports.IntentsRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).import_intents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).import_intents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.import_intents(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_import_intents_rest_unset_required_fields(): + transport = transports.IntentsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.import_intents._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_intents_rest_interceptors(null_interceptor): + transport = transports.IntentsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.IntentsRestInterceptor(), + ) + client = IntentsClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.IntentsRestInterceptor, "post_import_intents" + ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "pre_import_intents" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = intent.ImportIntentsRequest.pb(intent.ImportIntentsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = intent.ImportIntentsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_intents( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_intents_rest_bad_request( + transport: str = "rest", request_type=intent.ImportIntentsRequest +): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/agents/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.import_intents(request) + + +def test_import_intents_rest_error(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + intent.ExportIntentsRequest, + dict, + ], +) +def test_export_intents_rest(request_type): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/agents/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.export_intents(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_export_intents_rest_required_fields(request_type=intent.ExportIntentsRequest): + transport_class = transports.IntentsRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["intents"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).export_intents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["intents"] = "intents_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).export_intents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "intents" in jsonified_request + assert jsonified_request["intents"] == "intents_value" + + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.export_intents(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_export_intents_rest_unset_required_fields(): + transport = transports.IntentsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.export_intents._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "intents", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_export_intents_rest_interceptors(null_interceptor): + transport = transports.IntentsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.IntentsRestInterceptor(), + ) + client = IntentsClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.IntentsRestInterceptor, "post_export_intents" + ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "pre_export_intents" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = intent.ExportIntentsRequest.pb(intent.ExportIntentsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = intent.ExportIntentsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.export_intents( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_export_intents_rest_bad_request( + transport: str = "rest", request_type=intent.ExportIntentsRequest +): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/agents/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.export_intents(request) + + +def test_export_intents_rest_error(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.IntentsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.IntentsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = IntentsClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. transport = transports.IntentsGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), ) @@ -3742,6 +4458,8 @@ def test_intents_base_transport(): "create_intent", "update_intent", "delete_intent", + "import_intents", + "export_intents", "get_location", "list_locations", "get_operation", @@ -3755,6 +4473,11 @@ def test_intents_base_transport(): with pytest.raises(NotImplementedError): transport.close() + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + # Catch all for all remaining methods and properties remainder = [ "kind", @@ -3951,6 +4674,23 @@ def test_intents_http_transport_client_cert_source_for_mtls(): mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) +def test_intents_rest_lro_client(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + @pytest.mark.parametrize( "transport_name", [ @@ -4029,6 +4769,12 @@ def test_intents_client_transport_session_collision(transport_name): session1 = client1.transport.delete_intent._session session2 = client2.transport.delete_intent._session assert session1 != session2 + session1 = client1.transport.import_intents._session + session2 = client2.transport.import_intents._session + assert session1 != session2 + session1 = client1.transport.export_intents._session + session2 = client2.transport.export_intents._session + assert session1 != session2 def test_intents_grpc_transport_channel(): @@ -4149,6 +4895,40 @@ def test_intents_transport_channel_mtls_with_adc(transport_class): assert transport.grpc_channel == mock_grpc_channel +def test_intents_grpc_lro_client(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_intents_grpc_lro_async_client(): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + def test_entity_type_path(): project = "squid" location = "clam" diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_pages.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_pages.py index 58802ea27a99..9f2ca53f8c85 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_pages.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_pages.py @@ -52,7 +52,12 @@ pagers, transports, ) -from google.cloud.dialogflowcx_v3.types import data_store_connection, fulfillment +from google.cloud.dialogflowcx_v3.types import ( + advanced_settings, + data_store_connection, + fulfillment, + gcs, +) from google.cloud.dialogflowcx_v3.types import page from google.cloud.dialogflowcx_v3.types import page as gcdc_page from google.cloud.dialogflowcx_v3.types import response_message @@ -2733,6 +2738,19 @@ def test_create_page_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -2755,6 +2773,7 @@ def test_create_page_rest(request_type): }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -2774,6 +2793,7 @@ def test_create_page_rest(request_type): } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -3034,6 +3054,19 @@ def test_create_page_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -3056,6 +3089,7 @@ def test_create_page_rest_bad_request( }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -3075,6 +3109,7 @@ def test_create_page_rest_bad_request( } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -3248,6 +3283,19 @@ def test_update_page_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -3270,6 +3318,7 @@ def test_update_page_rest(request_type): }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -3289,6 +3338,7 @@ def test_update_page_rest(request_type): } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -3551,6 +3601,19 @@ def test_update_page_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -3573,6 +3636,7 @@ def test_update_page_rest_bad_request( }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -3592,6 +3656,7 @@ def test_update_page_rest_bad_request( } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_test_cases.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_test_cases.py index cb7af621d933..5ee6d3fc3a15 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_test_cases.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_test_cases.py @@ -65,9 +65,11 @@ transports, ) from google.cloud.dialogflowcx_v3.types import ( + advanced_settings, audio_config, data_store_connection, fulfillment, + gcs, intent, page, response_message, @@ -4606,6 +4608,19 @@ def test_create_test_case_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -4628,6 +4643,7 @@ def test_create_test_case_rest(request_type): }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -4647,6 +4663,7 @@ def test_create_test_case_rest(request_type): } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -5015,6 +5032,19 @@ def test_create_test_case_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -5037,6 +5067,7 @@ def test_create_test_case_rest_bad_request( }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -5056,6 +5087,7 @@ def test_create_test_case_rest_bad_request( } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -5331,6 +5363,19 @@ def test_update_test_case_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -5353,6 +5398,7 @@ def test_update_test_case_rest(request_type): }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -5372,6 +5418,7 @@ def test_update_test_case_rest(request_type): } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -5741,6 +5788,19 @@ def test_update_test_case_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -5763,6 +5823,7 @@ def test_update_test_case_rest_bad_request( }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -5782,6 +5843,7 @@ def test_update_test_case_rest_bad_request( } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_transition_route_groups.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_transition_route_groups.py index d11fe7827d61..59bc0c65525e 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_transition_route_groups.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_transition_route_groups.py @@ -52,7 +52,13 @@ pagers, transports, ) -from google.cloud.dialogflowcx_v3.types import fulfillment, page, response_message +from google.cloud.dialogflowcx_v3.types import ( + advanced_settings, + fulfillment, + gcs, + page, + response_message, +) from google.cloud.dialogflowcx_v3.types import ( transition_route_group as gcdc_transition_route_group, ) @@ -2985,6 +2991,19 @@ def test_create_transition_route_group_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3268,6 +3287,19 @@ def test_create_transition_route_group_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3453,6 +3485,19 @@ def test_update_transition_route_group_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3738,6 +3783,19 @@ def test_update_transition_route_group_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_agents.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_agents.py index 268651a987ea..5dfc5b88463a 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_agents.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_agents.py @@ -4021,6 +4021,11 @@ def test_create_agent_rest(request_type): "locked": True, "advanced_settings": { "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, "logging_settings": { "enable_stackdriver_logging": True, "enable_interaction_logging": True, @@ -4257,6 +4262,11 @@ def test_create_agent_rest_bad_request( "locked": True, "advanced_settings": { "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, "logging_settings": { "enable_stackdriver_logging": True, "enable_interaction_logging": True, @@ -4388,6 +4398,11 @@ def test_update_agent_rest(request_type): "locked": True, "advanced_settings": { "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, "logging_settings": { "enable_stackdriver_logging": True, "enable_interaction_logging": True, @@ -4615,6 +4630,11 @@ def test_update_agent_rest_bad_request( "locked": True, "advanced_settings": { "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, "logging_settings": { "enable_stackdriver_logging": True, "enable_interaction_logging": True, diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_flows.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_flows.py index 705aecda6ae7..63265be8e73c 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_flows.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_flows.py @@ -63,14 +63,18 @@ pagers, transports, ) +from google.cloud.dialogflowcx_v3beta1.types import ( + advanced_settings, + data_store_connection, +) from google.cloud.dialogflowcx_v3beta1.types import ( fulfillment, + gcs, import_strategy, page, response_message, validation_message, ) -from google.cloud.dialogflowcx_v3beta1.types import data_store_connection from google.cloud.dialogflowcx_v3beta1.types import flow from google.cloud.dialogflowcx_v3beta1.types import flow as gcdc_flow @@ -3066,6 +3070,19 @@ def test_create_flow_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3089,6 +3106,7 @@ def test_create_flow_rest(request_type): "classification_threshold": 0.25520000000000004, "model_training_mode": 1, }, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -3359,6 +3377,19 @@ def test_create_flow_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3382,6 +3413,7 @@ def test_create_flow_rest_bad_request( "classification_threshold": 0.25520000000000004, "model_training_mode": 1, }, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -4426,6 +4458,19 @@ def test_update_flow_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -4449,6 +4494,7 @@ def test_update_flow_rest(request_type): "classification_threshold": 0.25520000000000004, "model_training_mode": 1, }, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -4723,6 +4769,19 @@ def test_update_flow_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -4746,6 +4805,7 @@ def test_update_flow_rest_bad_request( "classification_threshold": 0.25520000000000004, "model_training_mode": 1, }, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_intents.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_intents.py index 2d89a2bc1bec..7916c2953a24 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_intents.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_intents.py @@ -26,9 +26,18 @@ import json import math -from google.api_core import gapic_v1, grpc_helpers, grpc_helpers_async, path_template +from google.api_core import ( + future, + gapic_v1, + grpc_helpers, + grpc_helpers_async, + operation, + operations_v1, + path_template, +) from google.api_core import client_options from google.api_core import exceptions as core_exceptions +from google.api_core import operation_async # type: ignore import google.auth from google.auth import credentials as ga_credentials from google.auth.exceptions import MutualTLSChannelError @@ -51,6 +60,7 @@ pagers, transports, ) +from google.cloud.dialogflowcx_v3beta1.types import inline from google.cloud.dialogflowcx_v3beta1.types import intent from google.cloud.dialogflowcx_v3beta1.types import intent as gcdc_intent @@ -2059,6 +2069,294 @@ async def test_delete_intent_flattened_error_async(): ) +@pytest.mark.parametrize( + "request_type", + [ + intent.ImportIntentsRequest, + dict, + ], +) +def test_import_intents(request_type, transport: str = "grpc"): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.import_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ImportIntentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_intents_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + client.import_intents() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ImportIntentsRequest() + + +@pytest.mark.asyncio +async def test_import_intents_async( + transport: str = "grpc_asyncio", request_type=intent.ImportIntentsRequest +): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.import_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ImportIntentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_intents_async_from_dict(): + await test_import_intents_async(request_type=dict) + + +def test_import_intents_field_headers(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = intent.ImportIntentsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.import_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_import_intents_field_headers_async(): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = intent.ImportIntentsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.import_intents), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.import_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.parametrize( + "request_type", + [ + intent.ExportIntentsRequest, + dict, + ], +) +def test_export_intents(request_type, transport: str = "grpc"): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name="operations/spam") + response = client.export_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ExportIntentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_export_intents_empty_call(): + # This test is a coverage failsafe to make sure that totally empty calls, + # i.e. request == None and no flattened fields passed, work. + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + client.export_intents() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ExportIntentsRequest() + + +@pytest.mark.asyncio +async def test_export_intents_async( + transport: str = "grpc_asyncio", request_type=intent.ExportIntentsRequest +): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # Everything is optional in proto3 as far as the runtime is concerned, + # and we are mocking out the actual API, so just send an empty request. + request = request_type() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/spam") + ) + response = await client.export_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == intent.ExportIntentsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_export_intents_async_from_dict(): + await test_export_intents_async(request_type=dict) + + +def test_export_intents_field_headers(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = intent.ExportIntentsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + call.return_value = operations_pb2.Operation(name="operations/op") + client.export_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + +@pytest.mark.asyncio +async def test_export_intents_field_headers_async(): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Any value that is part of the HTTP/1.1 URI should be sent as + # a field header. Set these to a non-empty value. + request = intent.ExportIntentsRequest() + + request.parent = "parent_value" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.export_intents), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation(name="operations/op") + ) + await client.export_intents(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == request + + # Establish that the field header was sent. + _, _, kw = call.mock_calls[0] + assert ( + "x-goog-request-params", + "parent=parent_value", + ) in kw["metadata"] + + @pytest.mark.parametrize( "request_type", [ @@ -3598,28 +3896,446 @@ def test_delete_intent_rest_error(): ) -def test_credentials_transport_error(): - # It is an error to provide credentials and a transport instance. - transport = transports.IntentsGrpcTransport( - credentials=ga_credentials.AnonymousCredentials(), - ) - with pytest.raises(ValueError): - client = IntentsClient( - credentials=ga_credentials.AnonymousCredentials(), - transport=transport, - ) - - # It is an error to provide a credentials file and a transport instance. - transport = transports.IntentsGrpcTransport( +@pytest.mark.parametrize( + "request_type", + [ + intent.ImportIntentsRequest, + dict, + ], +) +def test_import_intents_rest(request_type): + client = IntentsClient( credentials=ga_credentials.AnonymousCredentials(), + transport="rest", ) - with pytest.raises(ValueError): - client = IntentsClient( - client_options={"credentials_file": "credentials.json"}, - transport=transport, - ) - # It is an error to provide an api_key and a transport instance. + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/agents/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.import_intents(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_intents_rest_required_fields(request_type=intent.ImportIntentsRequest): + transport_class = transports.IntentsRestTransport + + request_init = {} + request_init["parent"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).import_intents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).import_intents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.import_intents(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_import_intents_rest_unset_required_fields(): + transport = transports.IntentsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.import_intents._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent",))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_intents_rest_interceptors(null_interceptor): + transport = transports.IntentsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.IntentsRestInterceptor(), + ) + client = IntentsClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.IntentsRestInterceptor, "post_import_intents" + ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "pre_import_intents" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = intent.ImportIntentsRequest.pb(intent.ImportIntentsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = intent.ImportIntentsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_intents( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_intents_rest_bad_request( + transport: str = "rest", request_type=intent.ImportIntentsRequest +): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/agents/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.import_intents(request) + + +def test_import_intents_rest_error(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +@pytest.mark.parametrize( + "request_type", + [ + intent.ExportIntentsRequest, + dict, + ], +) +def test_export_intents_rest(request_type): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/agents/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a response. + with mock.patch.object(type(client.transport._session), "request") as req: + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + response = client.export_intents(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_export_intents_rest_required_fields(request_type=intent.ExportIntentsRequest): + transport_class = transports.IntentsRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["intents"] = "" + request = request_type(**request_init) + pb_request = request_type.pb(request) + jsonified_request = json.loads( + json_format.MessageToJson( + pb_request, + including_default_value_fields=False, + use_integers_for_enums=False, + ) + ) + + # verify fields with default values are dropped + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).export_intents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["parent"] = "parent_value" + jsonified_request["intents"] = "intents_value" + + unset_fields = transport_class( + credentials=ga_credentials.AnonymousCredentials() + ).export_intents._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "parent" in jsonified_request + assert jsonified_request["parent"] == "parent_value" + assert "intents" in jsonified_request + assert jsonified_request["intents"] == "intents_value" + + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = operations_pb2.Operation(name="operations/spam") + # Mock the http request call within the method and fake a response. + with mock.patch.object(Session, "request") as req: + # We need to mock transcode() because providing default values + # for required fields will fail the real version if the http_options + # expect actual values for those fields. + with mock.patch.object(path_template, "transcode") as transcode: + # A uri without fields and an empty body will force all the + # request fields to show up in the query_params. + pb_request = request_type.pb(request) + transcode_result = { + "uri": "v1/sample_method", + "method": "post", + "query_params": pb_request, + } + transcode_result["body"] = pb_request + transcode.return_value = transcode_result + + response_value = Response() + response_value.status_code = 200 + json_return_value = json_format.MessageToJson(return_value) + + response_value._content = json_return_value.encode("UTF-8") + req.return_value = response_value + + response = client.export_intents(request) + + expected_params = [("$alt", "json;enum-encoding=int")] + actual_params = req.call_args.kwargs["params"] + assert expected_params == actual_params + + +def test_export_intents_rest_unset_required_fields(): + transport = transports.IntentsRestTransport( + credentials=ga_credentials.AnonymousCredentials + ) + + unset_fields = transport.export_intents._get_unset_required_fields({}) + assert set(unset_fields) == ( + set(()) + & set( + ( + "parent", + "intents", + ) + ) + ) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_export_intents_rest_interceptors(null_interceptor): + transport = transports.IntentsRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.IntentsRestInterceptor(), + ) + client = IntentsClient(transport=transport) + with mock.patch.object( + type(client.transport._session), "request" + ) as req, mock.patch.object( + path_template, "transcode" + ) as transcode, mock.patch.object( + operation.Operation, "_set_result_from_operation" + ), mock.patch.object( + transports.IntentsRestInterceptor, "post_export_intents" + ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "pre_export_intents" + ) as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = intent.ExportIntentsRequest.pb(intent.ExportIntentsRequest()) + transcode.return_value = { + "method": "post", + "uri": "my_uri", + "body": pb_message, + "query_params": pb_message, + } + + req.return_value = Response() + req.return_value.status_code = 200 + req.return_value.request = PreparedRequest() + req.return_value._content = json_format.MessageToJson( + operations_pb2.Operation() + ) + + request = intent.ExportIntentsRequest() + metadata = [ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.export_intents( + request, + metadata=[ + ("key", "val"), + ("cephalopod", "squid"), + ], + ) + + pre.assert_called_once() + post.assert_called_once() + + +def test_export_intents_rest_bad_request( + transport: str = "rest", request_type=intent.ExportIntentsRequest +): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {"parent": "projects/sample1/locations/sample2/agents/sample3"} + request = request_type(**request_init) + + # Mock the http request call within the method and fake a BadRequest error. + with mock.patch.object(Session, "request") as req, pytest.raises( + core_exceptions.BadRequest + ): + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 400 + response_value.request = Request() + req.return_value = response_value + client.export_intents(request) + + +def test_export_intents_rest_error(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), transport="rest" + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.IntentsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.IntentsGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = IntentsClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. transport = transports.IntentsGrpcTransport( credentials=ga_credentials.AnonymousCredentials(), ) @@ -3742,6 +4458,8 @@ def test_intents_base_transport(): "create_intent", "update_intent", "delete_intent", + "import_intents", + "export_intents", "get_location", "list_locations", "get_operation", @@ -3755,6 +4473,11 @@ def test_intents_base_transport(): with pytest.raises(NotImplementedError): transport.close() + # Additionally, the LRO client (a property) should + # also raise NotImplementedError + with pytest.raises(NotImplementedError): + transport.operations_client + # Catch all for all remaining methods and properties remainder = [ "kind", @@ -3951,6 +4674,23 @@ def test_intents_http_transport_client_cert_source_for_mtls(): mock_configure_mtls_channel.assert_called_once_with(client_cert_source_callback) +def test_intents_rest_lro_client(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.AbstractOperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + @pytest.mark.parametrize( "transport_name", [ @@ -4029,6 +4769,12 @@ def test_intents_client_transport_session_collision(transport_name): session1 = client1.transport.delete_intent._session session2 = client2.transport.delete_intent._session assert session1 != session2 + session1 = client1.transport.import_intents._session + session2 = client2.transport.import_intents._session + assert session1 != session2 + session1 = client1.transport.export_intents._session + session2 = client2.transport.export_intents._session + assert session1 != session2 def test_intents_grpc_transport_channel(): @@ -4149,6 +4895,40 @@ def test_intents_transport_channel_mtls_with_adc(transport_class): assert transport.grpc_channel == mock_grpc_channel +def test_intents_grpc_lro_client(): + client = IntentsClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + +def test_intents_grpc_lro_async_client(): + client = IntentsAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="grpc_asyncio", + ) + transport = client.transport + + # Ensure that we have a api-core operations client. + assert isinstance( + transport.operations_client, + operations_v1.OperationsAsyncClient, + ) + + # Ensure that subsequent calls to the property send the exact same object. + assert transport.operations_client is transport.operations_client + + def test_entity_type_path(): project = "squid" location = "clam" diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_pages.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_pages.py index 8338a55cd4c3..e79d7d544744 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_pages.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_pages.py @@ -52,7 +52,12 @@ pagers, transports, ) -from google.cloud.dialogflowcx_v3beta1.types import data_store_connection, fulfillment +from google.cloud.dialogflowcx_v3beta1.types import ( + advanced_settings, + data_store_connection, + fulfillment, + gcs, +) from google.cloud.dialogflowcx_v3beta1.types import page from google.cloud.dialogflowcx_v3beta1.types import page as gcdc_page from google.cloud.dialogflowcx_v3beta1.types import response_message @@ -2732,6 +2737,19 @@ def test_create_page_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -2754,6 +2772,7 @@ def test_create_page_rest(request_type): }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -2773,6 +2792,7 @@ def test_create_page_rest(request_type): } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -3032,6 +3052,19 @@ def test_create_page_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -3054,6 +3087,7 @@ def test_create_page_rest_bad_request( }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -3073,6 +3107,7 @@ def test_create_page_rest_bad_request( } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -3245,6 +3280,19 @@ def test_update_page_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -3267,6 +3315,7 @@ def test_update_page_rest(request_type): }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -3286,6 +3335,7 @@ def test_update_page_rest(request_type): } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -3547,6 +3597,19 @@ def test_update_page_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -3569,6 +3632,7 @@ def test_update_page_rest_bad_request( }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -3588,6 +3652,7 @@ def test_update_page_rest_bad_request( } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_test_cases.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_test_cases.py index d8e73c7f3f98..f8e9fb6d2f68 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_test_cases.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_test_cases.py @@ -65,9 +65,11 @@ transports, ) from google.cloud.dialogflowcx_v3beta1.types import ( + advanced_settings, audio_config, data_store_connection, fulfillment, + gcs, intent, page, response_message, @@ -4605,6 +4607,19 @@ def test_create_test_case_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -4627,6 +4642,7 @@ def test_create_test_case_rest(request_type): }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -4646,6 +4662,7 @@ def test_create_test_case_rest(request_type): } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -5013,6 +5030,19 @@ def test_create_test_case_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -5035,6 +5065,7 @@ def test_create_test_case_rest_bad_request( }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -5054,6 +5085,7 @@ def test_create_test_case_rest_bad_request( } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -5328,6 +5360,19 @@ def test_update_test_case_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -5350,6 +5395,7 @@ def test_update_test_case_rest(request_type): }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -5369,6 +5415,7 @@ def test_update_test_case_rest(request_type): } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, @@ -5737,6 +5784,19 @@ def test_update_test_case_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "form": { "parameters": [ @@ -5759,6 +5819,7 @@ def test_update_test_case_rest_bad_request( }, "default_value": {}, "redact": True, + "advanced_settings": {}, } ] }, @@ -5778,6 +5839,7 @@ def test_update_test_case_rest_bad_request( } ], "event_handlers": {}, + "advanced_settings": {}, "knowledge_connector_settings": { "enabled": True, "trigger_fulfillment": {}, diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_transition_route_groups.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_transition_route_groups.py index b1650b0da6c6..06ae6fbc2755 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_transition_route_groups.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_transition_route_groups.py @@ -52,7 +52,13 @@ pagers, transports, ) -from google.cloud.dialogflowcx_v3beta1.types import fulfillment, page, response_message +from google.cloud.dialogflowcx_v3beta1.types import ( + advanced_settings, + fulfillment, + gcs, + page, + response_message, +) from google.cloud.dialogflowcx_v3beta1.types import ( transition_route_group as gcdc_transition_route_group, ) @@ -2984,6 +2990,19 @@ def test_create_transition_route_group_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3266,6 +3285,19 @@ def test_create_transition_route_group_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3450,6 +3482,19 @@ def test_update_transition_route_group_rest(request_type): ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value", @@ -3734,6 +3779,19 @@ def test_update_transition_route_group_rest_bad_request( ] } ], + "advanced_settings": { + "audio_export_gcs_destination": {"uri": "uri_value"}, + "dtmf_settings": { + "enabled": True, + "max_digits": 1065, + "finish_digit": "finish_digit_value", + }, + "logging_settings": { + "enable_stackdriver_logging": True, + "enable_interaction_logging": True, + }, + }, + "enable_generative_fallback": True, }, "target_page": "target_page_value", "target_flow": "target_flow_value",