diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/gapic_version.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/gapic_version.py index 075108786e34..558c8aab67c5 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/gapic_version.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.3.11" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_version.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_version.py index 075108786e34..558c8aab67c5 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_version.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.3.11" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/client.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/client.py index e0c68d2dc0dc..af5ab30f0dfb 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/client.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -545,6 +547,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2770,16 +2799,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2825,16 +2858,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, diff --git a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest.py b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest.py index f5d4b4f959cd..778d6c2c3d21 100644 --- a/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest.py +++ b/packages/google-cloud-datacatalog-lineage/google/cloud/datacatalog_lineage_v1/services/lineage/transports/rest.py @@ -227,12 +227,38 @@ def post_batch_search_link_processes( ) -> lineage.BatchSearchLinkProcessesResponse: """Post-rpc interceptor for batch_search_link_processes - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_search_link_processes_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_batch_search_link_processes` interceptor runs + before the `post_batch_search_link_processes_with_metadata` interceptor. """ return response + def post_batch_search_link_processes_with_metadata( + self, + response: lineage.BatchSearchLinkProcessesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + lineage.BatchSearchLinkProcessesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_search_link_processes + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_batch_search_link_processes_with_metadata` + interceptor in new development instead of the `post_batch_search_link_processes` interceptor. + When both interceptors are used, this `post_batch_search_link_processes_with_metadata` interceptor runs after the + `post_batch_search_link_processes` interceptor. The (possibly modified) response returned by + `post_batch_search_link_processes` will be passed to + `post_batch_search_link_processes_with_metadata`. + """ + return response, metadata + def pre_create_lineage_event( self, request: lineage.CreateLineageEventRequest, @@ -252,12 +278,35 @@ def post_create_lineage_event( ) -> lineage.LineageEvent: """Post-rpc interceptor for create_lineage_event - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_lineage_event_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_create_lineage_event` interceptor runs + before the `post_create_lineage_event_with_metadata` interceptor. """ return response + def post_create_lineage_event_with_metadata( + self, + response: lineage.LineageEvent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lineage.LineageEvent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_lineage_event + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_create_lineage_event_with_metadata` + interceptor in new development instead of the `post_create_lineage_event` interceptor. + When both interceptors are used, this `post_create_lineage_event_with_metadata` interceptor runs after the + `post_create_lineage_event` interceptor. The (possibly modified) response returned by + `post_create_lineage_event` will be passed to + `post_create_lineage_event_with_metadata`. + """ + return response, metadata + def pre_create_process( self, request: lineage.CreateProcessRequest, @@ -273,12 +322,35 @@ def pre_create_process( def post_create_process(self, response: lineage.Process) -> lineage.Process: """Post-rpc interceptor for create_process - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_process_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_create_process` interceptor runs + before the `post_create_process_with_metadata` interceptor. """ return response + def post_create_process_with_metadata( + self, + response: lineage.Process, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lineage.Process, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_process + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_create_process_with_metadata` + interceptor in new development instead of the `post_create_process` interceptor. + When both interceptors are used, this `post_create_process_with_metadata` interceptor runs after the + `post_create_process` interceptor. The (possibly modified) response returned by + `post_create_process` will be passed to + `post_create_process_with_metadata`. + """ + return response, metadata + def pre_create_run( self, request: lineage.CreateRunRequest, @@ -294,12 +366,33 @@ def pre_create_run( def post_create_run(self, response: lineage.Run) -> lineage.Run: """Post-rpc interceptor for create_run - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_run_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_create_run` interceptor runs + before the `post_create_run_with_metadata` interceptor. """ return response + def post_create_run_with_metadata( + self, response: lineage.Run, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[lineage.Run, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_run + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_create_run_with_metadata` + interceptor in new development instead of the `post_create_run` interceptor. + When both interceptors are used, this `post_create_run_with_metadata` interceptor runs after the + `post_create_run` interceptor. The (possibly modified) response returned by + `post_create_run` will be passed to + `post_create_run_with_metadata`. + """ + return response, metadata + def pre_delete_lineage_event( self, request: lineage.DeleteLineageEventRequest, @@ -331,12 +424,35 @@ def post_delete_process( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_process - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_process_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_delete_process` interceptor runs + before the `post_delete_process_with_metadata` interceptor. """ return response + def post_delete_process_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_process + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_delete_process_with_metadata` + interceptor in new development instead of the `post_delete_process` interceptor. + When both interceptors are used, this `post_delete_process_with_metadata` interceptor runs after the + `post_delete_process` interceptor. The (possibly modified) response returned by + `post_delete_process` will be passed to + `post_delete_process_with_metadata`. + """ + return response, metadata + def pre_delete_run( self, request: lineage.DeleteRunRequest, @@ -354,12 +470,35 @@ def post_delete_run( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_run - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_run_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_delete_run` interceptor runs + before the `post_delete_run_with_metadata` interceptor. """ return response + def post_delete_run_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_run + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_delete_run_with_metadata` + interceptor in new development instead of the `post_delete_run` interceptor. + When both interceptors are used, this `post_delete_run_with_metadata` interceptor runs after the + `post_delete_run` interceptor. The (possibly modified) response returned by + `post_delete_run` will be passed to + `post_delete_run_with_metadata`. + """ + return response, metadata + def pre_get_lineage_event( self, request: lineage.GetLineageEventRequest, @@ -377,12 +516,35 @@ def post_get_lineage_event( ) -> lineage.LineageEvent: """Post-rpc interceptor for get_lineage_event - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_lineage_event_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_get_lineage_event` interceptor runs + before the `post_get_lineage_event_with_metadata` interceptor. """ return response + def post_get_lineage_event_with_metadata( + self, + response: lineage.LineageEvent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lineage.LineageEvent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_lineage_event + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_get_lineage_event_with_metadata` + interceptor in new development instead of the `post_get_lineage_event` interceptor. + When both interceptors are used, this `post_get_lineage_event_with_metadata` interceptor runs after the + `post_get_lineage_event` interceptor. The (possibly modified) response returned by + `post_get_lineage_event` will be passed to + `post_get_lineage_event_with_metadata`. + """ + return response, metadata + def pre_get_process( self, request: lineage.GetProcessRequest, @@ -398,12 +560,35 @@ def pre_get_process( def post_get_process(self, response: lineage.Process) -> lineage.Process: """Post-rpc interceptor for get_process - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_process_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_get_process` interceptor runs + before the `post_get_process_with_metadata` interceptor. """ return response + def post_get_process_with_metadata( + self, + response: lineage.Process, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lineage.Process, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_process + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_get_process_with_metadata` + interceptor in new development instead of the `post_get_process` interceptor. + When both interceptors are used, this `post_get_process_with_metadata` interceptor runs after the + `post_get_process` interceptor. The (possibly modified) response returned by + `post_get_process` will be passed to + `post_get_process_with_metadata`. + """ + return response, metadata + def pre_get_run( self, request: lineage.GetRunRequest, @@ -419,12 +604,33 @@ def pre_get_run( def post_get_run(self, response: lineage.Run) -> lineage.Run: """Post-rpc interceptor for get_run - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_run_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_get_run` interceptor runs + before the `post_get_run_with_metadata` interceptor. """ return response + def post_get_run_with_metadata( + self, response: lineage.Run, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[lineage.Run, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_run + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_get_run_with_metadata` + interceptor in new development instead of the `post_get_run` interceptor. + When both interceptors are used, this `post_get_run_with_metadata` interceptor runs after the + `post_get_run` interceptor. The (possibly modified) response returned by + `post_get_run` will be passed to + `post_get_run_with_metadata`. + """ + return response, metadata + def pre_list_lineage_events( self, request: lineage.ListLineageEventsRequest, @@ -444,12 +650,37 @@ def post_list_lineage_events( ) -> lineage.ListLineageEventsResponse: """Post-rpc interceptor for list_lineage_events - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_lineage_events_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_list_lineage_events` interceptor runs + before the `post_list_lineage_events_with_metadata` interceptor. """ return response + def post_list_lineage_events_with_metadata( + self, + response: lineage.ListLineageEventsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + lineage.ListLineageEventsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_lineage_events + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_list_lineage_events_with_metadata` + interceptor in new development instead of the `post_list_lineage_events` interceptor. + When both interceptors are used, this `post_list_lineage_events_with_metadata` interceptor runs after the + `post_list_lineage_events` interceptor. The (possibly modified) response returned by + `post_list_lineage_events` will be passed to + `post_list_lineage_events_with_metadata`. + """ + return response, metadata + def pre_list_processes( self, request: lineage.ListProcessesRequest, @@ -467,12 +698,35 @@ def post_list_processes( ) -> lineage.ListProcessesResponse: """Post-rpc interceptor for list_processes - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_processes_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_list_processes` interceptor runs + before the `post_list_processes_with_metadata` interceptor. """ return response + def post_list_processes_with_metadata( + self, + response: lineage.ListProcessesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lineage.ListProcessesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_processes + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_list_processes_with_metadata` + interceptor in new development instead of the `post_list_processes` interceptor. + When both interceptors are used, this `post_list_processes_with_metadata` interceptor runs after the + `post_list_processes` interceptor. The (possibly modified) response returned by + `post_list_processes` will be passed to + `post_list_processes_with_metadata`. + """ + return response, metadata + def pre_list_runs( self, request: lineage.ListRunsRequest, @@ -490,12 +744,35 @@ def post_list_runs( ) -> lineage.ListRunsResponse: """Post-rpc interceptor for list_runs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_runs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_list_runs` interceptor runs + before the `post_list_runs_with_metadata` interceptor. """ return response + def post_list_runs_with_metadata( + self, + response: lineage.ListRunsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lineage.ListRunsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_runs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_list_runs_with_metadata` + interceptor in new development instead of the `post_list_runs` interceptor. + When both interceptors are used, this `post_list_runs_with_metadata` interceptor runs after the + `post_list_runs` interceptor. The (possibly modified) response returned by + `post_list_runs` will be passed to + `post_list_runs_with_metadata`. + """ + return response, metadata + def pre_process_open_lineage_run_event( self, request: lineage.ProcessOpenLineageRunEventRequest, @@ -516,12 +793,38 @@ def post_process_open_lineage_run_event( ) -> lineage.ProcessOpenLineageRunEventResponse: """Post-rpc interceptor for process_open_lineage_run_event - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_process_open_lineage_run_event_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_process_open_lineage_run_event` interceptor runs + before the `post_process_open_lineage_run_event_with_metadata` interceptor. """ return response + def post_process_open_lineage_run_event_with_metadata( + self, + response: lineage.ProcessOpenLineageRunEventResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + lineage.ProcessOpenLineageRunEventResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for process_open_lineage_run_event + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_process_open_lineage_run_event_with_metadata` + interceptor in new development instead of the `post_process_open_lineage_run_event` interceptor. + When both interceptors are used, this `post_process_open_lineage_run_event_with_metadata` interceptor runs after the + `post_process_open_lineage_run_event` interceptor. The (possibly modified) response returned by + `post_process_open_lineage_run_event` will be passed to + `post_process_open_lineage_run_event_with_metadata`. + """ + return response, metadata + def pre_search_links( self, request: lineage.SearchLinksRequest, @@ -539,12 +842,35 @@ def post_search_links( ) -> lineage.SearchLinksResponse: """Post-rpc interceptor for search_links - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_links_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_search_links` interceptor runs + before the `post_search_links_with_metadata` interceptor. """ return response + def post_search_links_with_metadata( + self, + response: lineage.SearchLinksResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lineage.SearchLinksResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search_links + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_search_links_with_metadata` + interceptor in new development instead of the `post_search_links` interceptor. + When both interceptors are used, this `post_search_links_with_metadata` interceptor runs after the + `post_search_links` interceptor. The (possibly modified) response returned by + `post_search_links` will be passed to + `post_search_links_with_metadata`. + """ + return response, metadata + def pre_update_process( self, request: lineage.UpdateProcessRequest, @@ -560,12 +886,35 @@ def pre_update_process( def post_update_process(self, response: lineage.Process) -> lineage.Process: """Post-rpc interceptor for update_process - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_process_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_update_process` interceptor runs + before the `post_update_process_with_metadata` interceptor. """ return response + def post_update_process_with_metadata( + self, + response: lineage.Process, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[lineage.Process, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_process + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_update_process_with_metadata` + interceptor in new development instead of the `post_update_process` interceptor. + When both interceptors are used, this `post_update_process_with_metadata` interceptor runs after the + `post_update_process` interceptor. The (possibly modified) response returned by + `post_update_process` will be passed to + `post_update_process_with_metadata`. + """ + return response, metadata + def pre_update_run( self, request: lineage.UpdateRunRequest, @@ -581,12 +930,33 @@ def pre_update_run( def post_update_run(self, response: lineage.Run) -> lineage.Run: """Post-rpc interceptor for update_run - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_run_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Lineage server but before - it is returned to user code. + it is returned to user code. This `post_update_run` interceptor runs + before the `post_update_run_with_metadata` interceptor. """ return response + def post_update_run_with_metadata( + self, response: lineage.Run, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[lineage.Run, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_run + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Lineage server but before it is returned to user code. + + We recommend only using this `post_update_run_with_metadata` + interceptor in new development instead of the `post_update_run` interceptor. + When both interceptors are used, this `post_update_run_with_metadata` interceptor runs after the + `post_update_run` interceptor. The (possibly modified) response returned by + `post_update_run` will be passed to + `post_update_run_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -957,6 +1327,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_search_link_processes(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_search_link_processes_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1113,6 +1487,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_lineage_event(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_lineage_event_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1264,6 +1642,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_process(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_process_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1414,6 +1796,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_run(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_run_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1667,6 +2053,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_process(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_process_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1809,6 +2199,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_run(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_run_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1961,6 +2355,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_lineage_event(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_lineage_event_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2104,6 +2502,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_process(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_process_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2246,6 +2648,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_run(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_run_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2393,6 +2799,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_lineage_events(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_lineage_events_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2540,6 +2950,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_processes(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_processes_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2683,6 +3097,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_runs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_runs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2835,6 +3253,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_process_open_lineage_run_event(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_process_open_lineage_run_event_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2988,6 +3413,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_links(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_links_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3139,6 +3568,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_process(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_process_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3289,6 +3722,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_run(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_run_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.v1.json b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.v1.json index 46db67454e5c..ccc3b69b4a3a 100644 --- a/packages/google-cloud-datacatalog-lineage/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.v1.json +++ b/packages/google-cloud-datacatalog-lineage/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.lineage.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-datacatalog-lineage", - "version": "0.3.11" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/test_lineage.py b/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/test_lineage.py index 1c8eb6e569ed..5abb2d849d3b 100644 --- a/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/test_lineage.py +++ b/packages/google-cloud-datacatalog-lineage/tests/unit/gapic/datacatalog_lineage_v1/test_lineage.py @@ -74,6 +74,13 @@ ) from google.cloud.datacatalog_lineage_v1.types import lineage +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -297,6 +304,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = LineageClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = LineageClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -12057,10 +12107,14 @@ def test_process_open_lineage_run_event_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_process_open_lineage_run_event" ) as post, mock.patch.object( + transports.LineageRestInterceptor, + "post_process_open_lineage_run_event_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_process_open_lineage_run_event" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.ProcessOpenLineageRunEventRequest.pb( lineage.ProcessOpenLineageRunEventRequest() ) @@ -12086,6 +12140,10 @@ def test_process_open_lineage_run_event_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.ProcessOpenLineageRunEventResponse() + post_with_metadata.return_value = ( + lineage.ProcessOpenLineageRunEventResponse(), + metadata, + ) client.process_open_lineage_run_event( request, @@ -12097,6 +12155,7 @@ def test_process_open_lineage_run_event_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_process_rest_bad_request(request_type=lineage.CreateProcessRequest): @@ -12252,10 +12311,13 @@ def test_create_process_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_create_process" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_create_process_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_create_process" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.CreateProcessRequest.pb(lineage.CreateProcessRequest()) transcode.return_value = { "method": "post", @@ -12277,6 +12339,7 @@ def test_create_process_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.Process() + post_with_metadata.return_value = lineage.Process(), metadata client.create_process( request, @@ -12288,6 +12351,7 @@ def test_create_process_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_process_rest_bad_request(request_type=lineage.UpdateProcessRequest): @@ -12447,10 +12511,13 @@ def test_update_process_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_update_process" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_update_process_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_update_process" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.UpdateProcessRequest.pb(lineage.UpdateProcessRequest()) transcode.return_value = { "method": "post", @@ -12472,6 +12539,7 @@ def test_update_process_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.Process() + post_with_metadata.return_value = lineage.Process(), metadata client.update_process( request, @@ -12483,6 +12551,7 @@ def test_update_process_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_process_rest_bad_request(request_type=lineage.GetProcessRequest): @@ -12565,10 +12634,13 @@ def test_get_process_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_get_process" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_get_process_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_get_process" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.GetProcessRequest.pb(lineage.GetProcessRequest()) transcode.return_value = { "method": "post", @@ -12590,6 +12662,7 @@ def test_get_process_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.Process() + post_with_metadata.return_value = lineage.Process(), metadata client.get_process( request, @@ -12601,6 +12674,7 @@ def test_get_process_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_processes_rest_bad_request(request_type=lineage.ListProcessesRequest): @@ -12681,10 +12755,13 @@ def test_list_processes_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_list_processes" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_list_processes_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_list_processes" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.ListProcessesRequest.pb(lineage.ListProcessesRequest()) transcode.return_value = { "method": "post", @@ -12708,6 +12785,7 @@ def test_list_processes_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.ListProcessesResponse() + post_with_metadata.return_value = lineage.ListProcessesResponse(), metadata client.list_processes( request, @@ -12719,6 +12797,7 @@ def test_list_processes_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_process_rest_bad_request(request_type=lineage.DeleteProcessRequest): @@ -12795,10 +12874,13 @@ def test_delete_process_rest_interceptors(null_interceptor): ), mock.patch.object( transports.LineageRestInterceptor, "post_delete_process" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_delete_process_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_delete_process" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.DeleteProcessRequest.pb(lineage.DeleteProcessRequest()) transcode.return_value = { "method": "post", @@ -12820,6 +12902,7 @@ def test_delete_process_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_process( request, @@ -12831,6 +12914,7 @@ def test_delete_process_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_run_rest_bad_request(request_type=lineage.CreateRunRequest): @@ -12990,10 +13074,13 @@ def test_create_run_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_create_run" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_create_run_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_create_run" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.CreateRunRequest.pb(lineage.CreateRunRequest()) transcode.return_value = { "method": "post", @@ -13015,6 +13102,7 @@ def test_create_run_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.Run() + post_with_metadata.return_value = lineage.Run(), metadata client.create_run( request, @@ -13026,6 +13114,7 @@ def test_create_run_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_run_rest_bad_request(request_type=lineage.UpdateRunRequest): @@ -13193,10 +13282,13 @@ def test_update_run_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_update_run" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_update_run_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_update_run" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.UpdateRunRequest.pb(lineage.UpdateRunRequest()) transcode.return_value = { "method": "post", @@ -13218,6 +13310,7 @@ def test_update_run_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.Run() + post_with_metadata.return_value = lineage.Run(), metadata client.update_run( request, @@ -13229,6 +13322,7 @@ def test_update_run_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_run_rest_bad_request(request_type=lineage.GetRunRequest): @@ -13317,10 +13411,13 @@ def test_get_run_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_get_run" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_get_run_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_get_run" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.GetRunRequest.pb(lineage.GetRunRequest()) transcode.return_value = { "method": "post", @@ -13342,6 +13439,7 @@ def test_get_run_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.Run() + post_with_metadata.return_value = lineage.Run(), metadata client.get_run( request, @@ -13353,6 +13451,7 @@ def test_get_run_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_runs_rest_bad_request(request_type=lineage.ListRunsRequest): @@ -13433,10 +13532,13 @@ def test_list_runs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_list_runs" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_list_runs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_list_runs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.ListRunsRequest.pb(lineage.ListRunsRequest()) transcode.return_value = { "method": "post", @@ -13458,6 +13560,7 @@ def test_list_runs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.ListRunsResponse() + post_with_metadata.return_value = lineage.ListRunsResponse(), metadata client.list_runs( request, @@ -13469,6 +13572,7 @@ def test_list_runs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_run_rest_bad_request(request_type=lineage.DeleteRunRequest): @@ -13549,10 +13653,13 @@ def test_delete_run_rest_interceptors(null_interceptor): ), mock.patch.object( transports.LineageRestInterceptor, "post_delete_run" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_delete_run_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_delete_run" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.DeleteRunRequest.pb(lineage.DeleteRunRequest()) transcode.return_value = { "method": "post", @@ -13574,6 +13681,7 @@ def test_delete_run_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_run( request, @@ -13585,6 +13693,7 @@ def test_delete_run_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_lineage_event_rest_bad_request( @@ -13749,10 +13858,13 @@ def test_create_lineage_event_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_create_lineage_event" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_create_lineage_event_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_create_lineage_event" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.CreateLineageEventRequest.pb( lineage.CreateLineageEventRequest() ) @@ -13776,6 +13888,7 @@ def test_create_lineage_event_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.LineageEvent() + post_with_metadata.return_value = lineage.LineageEvent(), metadata client.create_lineage_event( request, @@ -13787,6 +13900,7 @@ def test_create_lineage_event_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_lineage_event_rest_bad_request( @@ -13873,10 +13987,13 @@ def test_get_lineage_event_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_get_lineage_event" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_get_lineage_event_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_get_lineage_event" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.GetLineageEventRequest.pb(lineage.GetLineageEventRequest()) transcode.return_value = { "method": "post", @@ -13898,6 +14015,7 @@ def test_get_lineage_event_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.LineageEvent() + post_with_metadata.return_value = lineage.LineageEvent(), metadata client.get_lineage_event( request, @@ -13909,6 +14027,7 @@ def test_get_lineage_event_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_lineage_events_rest_bad_request( @@ -13995,10 +14114,13 @@ def test_list_lineage_events_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_list_lineage_events" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_list_lineage_events_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_list_lineage_events" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.ListLineageEventsRequest.pb( lineage.ListLineageEventsRequest() ) @@ -14024,6 +14146,7 @@ def test_list_lineage_events_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.ListLineageEventsResponse() + post_with_metadata.return_value = lineage.ListLineageEventsResponse(), metadata client.list_lineage_events( request, @@ -14035,6 +14158,7 @@ def test_list_lineage_events_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_lineage_event_rest_bad_request( @@ -14226,10 +14350,13 @@ def test_search_links_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_search_links" ) as post, mock.patch.object( + transports.LineageRestInterceptor, "post_search_links_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_search_links" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.SearchLinksRequest.pb(lineage.SearchLinksRequest()) transcode.return_value = { "method": "post", @@ -14253,6 +14380,7 @@ def test_search_links_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.SearchLinksResponse() + post_with_metadata.return_value = lineage.SearchLinksResponse(), metadata client.search_links( request, @@ -14264,6 +14392,7 @@ def test_search_links_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_search_link_processes_rest_bad_request( @@ -14346,10 +14475,14 @@ def test_batch_search_link_processes_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.LineageRestInterceptor, "post_batch_search_link_processes" ) as post, mock.patch.object( + transports.LineageRestInterceptor, + "post_batch_search_link_processes_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.LineageRestInterceptor, "pre_batch_search_link_processes" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = lineage.BatchSearchLinkProcessesRequest.pb( lineage.BatchSearchLinkProcessesRequest() ) @@ -14375,6 +14508,10 @@ def test_batch_search_link_processes_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = lineage.BatchSearchLinkProcessesResponse() + post_with_metadata.return_value = ( + lineage.BatchSearchLinkProcessesResponse(), + metadata, + ) client.batch_search_link_processes( request, @@ -14386,6 +14523,7 @@ def test_batch_search_link_processes_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog/gapic_version.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog/gapic_version.py index 493e754ab337..558c8aab67c5 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog/gapic_version.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.24.1" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/gapic_version.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/gapic_version.py index 493e754ab337..558c8aab67c5 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/gapic_version.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.24.1" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/data_catalog/client.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/data_catalog/client.py index 1bfb7d97e535..15c733b9abe9 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/data_catalog/client.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/data_catalog/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -624,6 +626,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -5402,16 +5431,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -5457,16 +5490,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/policy_tag_manager/client.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/policy_tag_manager/client.py index 6bbf36a3252a..8540905771a1 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/policy_tag_manager/client.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/policy_tag_manager/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -516,6 +518,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2235,16 +2264,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2290,16 +2323,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/policy_tag_manager_serialization/client.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/policy_tag_manager_serialization/client.py index 78170d5e8e1a..4819928882ba 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/policy_tag_manager_serialization/client.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1/services/policy_tag_manager_serialization/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -500,6 +502,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1076,16 +1105,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1131,16 +1164,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/gapic_version.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/gapic_version.py index 493e754ab337..558c8aab67c5 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/gapic_version.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.24.1" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/data_catalog/client.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/data_catalog/client.py index 5b63130b88e1..2148c7ddd103 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/data_catalog/client.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/data_catalog/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -621,6 +623,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/policy_tag_manager/client.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/policy_tag_manager/client.py index cdaa782fb712..e1c575e0da41 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/policy_tag_manager/client.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/policy_tag_manager/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -512,6 +514,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/policy_tag_manager_serialization/client.py b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/policy_tag_manager_serialization/client.py index 7ff41a67e144..f8df202d3784 100644 --- a/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/policy_tag_manager_serialization/client.py +++ b/packages/google-cloud-datacatalog/google/cloud/datacatalog_v1beta1/services/policy_tag_manager_serialization/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -497,6 +499,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-datacatalog/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1.json b/packages/google-cloud-datacatalog/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1.json index eebce1e44dd6..e1bfcdcf1b01 100644 --- a/packages/google-cloud-datacatalog/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1.json +++ b/packages/google-cloud-datacatalog/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-datacatalog", - "version": "3.24.1" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-datacatalog/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1beta1.json b/packages/google-cloud-datacatalog/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1beta1.json index 424f580d3cb4..f2e225c6cf60 100644 --- a/packages/google-cloud-datacatalog/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1beta1.json +++ b/packages/google-cloud-datacatalog/samples/generated_samples/snippet_metadata_google.cloud.datacatalog.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-datacatalog", - "version": "3.24.1" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_data_catalog.py b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_data_catalog.py index 2fa4a93c0d42..fc309ea4b5e2 100644 --- a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_data_catalog.py +++ b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_data_catalog.py @@ -22,6 +22,7 @@ except ImportError: # pragma: NO COVER import mock +import json import math from google.api_core import api_core_version @@ -85,6 +86,13 @@ usage, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -324,6 +332,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataCatalogClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataCatalogClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ diff --git a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_policy_tag_manager.py b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_policy_tag_manager.py index 972254a07769..f9e11108ee78 100644 --- a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_policy_tag_manager.py +++ b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_policy_tag_manager.py @@ -22,6 +22,7 @@ except ImportError: # pragma: NO COVER import mock +import json import math from google.api_core import api_core_version @@ -62,6 +63,13 @@ ) from google.cloud.datacatalog_v1.types import common, policytagmanager, timestamps +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -321,6 +329,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = PolicyTagManagerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = PolicyTagManagerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ diff --git a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_policy_tag_manager_serialization.py b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_policy_tag_manager_serialization.py index c3975dc8fb0f..657c63aff768 100644 --- a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_policy_tag_manager_serialization.py +++ b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1/test_policy_tag_manager_serialization.py @@ -22,6 +22,7 @@ except ImportError: # pragma: NO COVER import mock +import json import math from google.api_core import api_core_version @@ -62,6 +63,13 @@ timestamps, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -349,6 +357,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = PolicyTagManagerSerializationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = PolicyTagManagerSerializationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ diff --git a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_data_catalog.py b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_data_catalog.py index bfab0c177432..4db3d0d4919c 100644 --- a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_data_catalog.py +++ b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_data_catalog.py @@ -22,6 +22,7 @@ except ImportError: # pragma: NO COVER import mock +import json import math from google.api_core import api_core_version @@ -72,6 +73,13 @@ usage, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -311,6 +319,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataCatalogClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataCatalogClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ diff --git a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_policy_tag_manager.py b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_policy_tag_manager.py index 810cb501ae32..e4e169219449 100644 --- a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_policy_tag_manager.py +++ b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_policy_tag_manager.py @@ -22,6 +22,7 @@ except ImportError: # pragma: NO COVER import mock +import json import math from google.api_core import api_core_version @@ -62,6 +63,13 @@ ) from google.cloud.datacatalog_v1beta1.types import common, policytagmanager, timestamps +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -321,6 +329,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = PolicyTagManagerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = PolicyTagManagerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ diff --git a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_policy_tag_manager_serialization.py b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_policy_tag_manager_serialization.py index ec57ea454df9..0e23f26221f7 100644 --- a/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_policy_tag_manager_serialization.py +++ b/packages/google-cloud-datacatalog/tests/unit/gapic/datacatalog_v1beta1/test_policy_tag_manager_serialization.py @@ -22,6 +22,7 @@ except ImportError: # pragma: NO COVER import mock +import json import math from google.api_core import api_core_version @@ -61,6 +62,13 @@ policytagmanagerserialization, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -348,6 +356,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = PolicyTagManagerSerializationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = PolicyTagManagerSerializationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow/gapic_version.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow/gapic_version.py index 3fe6a5d4ecad..558c8aab67c5 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow/gapic_version.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.8.15" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/gapic_version.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/gapic_version.py index 3fe6a5d4ecad..558c8aab67c5 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/gapic_version.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.8.15" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/flex_templates_service/client.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/flex_templates_service/client.py index 7fd3ec7a3bf3..1bdd8bac54da 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/flex_templates_service/client.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/flex_templates_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -463,6 +465,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/flex_templates_service/transports/rest.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/flex_templates_service/transports/rest.py index 243b73ea7328..d168d1fcb8a4 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/flex_templates_service/transports/rest.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/flex_templates_service/transports/rest.py @@ -101,12 +101,37 @@ def post_launch_flex_template( ) -> templates.LaunchFlexTemplateResponse: """Post-rpc interceptor for launch_flex_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_launch_flex_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the FlexTemplatesService server but before - it is returned to user code. + it is returned to user code. This `post_launch_flex_template` interceptor runs + before the `post_launch_flex_template_with_metadata` interceptor. """ return response + def post_launch_flex_template_with_metadata( + self, + response: templates.LaunchFlexTemplateResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + templates.LaunchFlexTemplateResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for launch_flex_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the FlexTemplatesService server but before it is returned to user code. + + We recommend only using this `post_launch_flex_template_with_metadata` + interceptor in new development instead of the `post_launch_flex_template` interceptor. + When both interceptors are used, this `post_launch_flex_template_with_metadata` interceptor runs after the + `post_launch_flex_template` interceptor. The (possibly modified) response returned by + `post_launch_flex_template` will be passed to + `post_launch_flex_template_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class FlexTemplatesServiceRestStub: @@ -326,6 +351,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_launch_flex_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_launch_flex_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/jobs_v1_beta3/client.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/jobs_v1_beta3/client.py index fabfd436124f..b667f4580925 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/jobs_v1_beta3/client.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/jobs_v1_beta3/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -466,6 +468,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/jobs_v1_beta3/transports/rest.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/jobs_v1_beta3/transports/rest.py index 2a352e8f0f87..ddd3556dc54b 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/jobs_v1_beta3/transports/rest.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/jobs_v1_beta3/transports/rest.py @@ -147,12 +147,35 @@ def post_aggregated_list_jobs( ) -> jobs.ListJobsResponse: """Post-rpc interceptor for aggregated_list_jobs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_aggregated_list_jobs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_aggregated_list_jobs` interceptor runs + before the `post_aggregated_list_jobs_with_metadata` interceptor. """ return response + def post_aggregated_list_jobs_with_metadata( + self, + response: jobs.ListJobsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[jobs.ListJobsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for aggregated_list_jobs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_aggregated_list_jobs_with_metadata` + interceptor in new development instead of the `post_aggregated_list_jobs` interceptor. + When both interceptors are used, this `post_aggregated_list_jobs_with_metadata` interceptor runs after the + `post_aggregated_list_jobs` interceptor. The (possibly modified) response returned by + `post_aggregated_list_jobs` will be passed to + `post_aggregated_list_jobs_with_metadata`. + """ + return response, metadata + def pre_create_job( self, request: jobs.CreateJobRequest, @@ -168,12 +191,33 @@ def pre_create_job( def post_create_job(self, response: jobs.Job) -> jobs.Job: """Post-rpc interceptor for create_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_create_job` interceptor runs + before the `post_create_job_with_metadata` interceptor. """ return response + def post_create_job_with_metadata( + self, response: jobs.Job, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[jobs.Job, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_create_job_with_metadata` + interceptor in new development instead of the `post_create_job` interceptor. + When both interceptors are used, this `post_create_job_with_metadata` interceptor runs after the + `post_create_job` interceptor. The (possibly modified) response returned by + `post_create_job` will be passed to + `post_create_job_with_metadata`. + """ + return response, metadata + def pre_get_job( self, request: jobs.GetJobRequest, @@ -189,12 +233,33 @@ def pre_get_job( def post_get_job(self, response: jobs.Job) -> jobs.Job: """Post-rpc interceptor for get_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_get_job` interceptor runs + before the `post_get_job_with_metadata` interceptor. """ return response + def post_get_job_with_metadata( + self, response: jobs.Job, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[jobs.Job, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_get_job_with_metadata` + interceptor in new development instead of the `post_get_job` interceptor. + When both interceptors are used, this `post_get_job_with_metadata` interceptor runs after the + `post_get_job` interceptor. The (possibly modified) response returned by + `post_get_job` will be passed to + `post_get_job_with_metadata`. + """ + return response, metadata + def pre_list_jobs( self, request: jobs.ListJobsRequest, @@ -210,12 +275,35 @@ def pre_list_jobs( def post_list_jobs(self, response: jobs.ListJobsResponse) -> jobs.ListJobsResponse: """Post-rpc interceptor for list_jobs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_jobs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_list_jobs` interceptor runs + before the `post_list_jobs_with_metadata` interceptor. """ return response + def post_list_jobs_with_metadata( + self, + response: jobs.ListJobsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[jobs.ListJobsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_jobs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_list_jobs_with_metadata` + interceptor in new development instead of the `post_list_jobs` interceptor. + When both interceptors are used, this `post_list_jobs_with_metadata` interceptor runs after the + `post_list_jobs` interceptor. The (possibly modified) response returned by + `post_list_jobs` will be passed to + `post_list_jobs_with_metadata`. + """ + return response, metadata + def pre_snapshot_job( self, request: jobs.SnapshotJobRequest, @@ -231,12 +319,35 @@ def pre_snapshot_job( def post_snapshot_job(self, response: snapshots.Snapshot) -> snapshots.Snapshot: """Post-rpc interceptor for snapshot_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_snapshot_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_snapshot_job` interceptor runs + before the `post_snapshot_job_with_metadata` interceptor. """ return response + def post_snapshot_job_with_metadata( + self, + response: snapshots.Snapshot, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[snapshots.Snapshot, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for snapshot_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_snapshot_job_with_metadata` + interceptor in new development instead of the `post_snapshot_job` interceptor. + When both interceptors are used, this `post_snapshot_job_with_metadata` interceptor runs after the + `post_snapshot_job` interceptor. The (possibly modified) response returned by + `post_snapshot_job` will be passed to + `post_snapshot_job_with_metadata`. + """ + return response, metadata + def pre_update_job( self, request: jobs.UpdateJobRequest, @@ -252,12 +363,33 @@ def pre_update_job( def post_update_job(self, response: jobs.Job) -> jobs.Job: """Post-rpc interceptor for update_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_update_job` interceptor runs + before the `post_update_job_with_metadata` interceptor. """ return response + def post_update_job_with_metadata( + self, response: jobs.Job, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[jobs.Job, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_update_job_with_metadata` + interceptor in new development instead of the `post_update_job` interceptor. + When both interceptors are used, this `post_update_job_with_metadata` interceptor runs after the + `post_update_job` interceptor. The (possibly modified) response returned by + `post_update_job` will be passed to + `post_update_job_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class JobsV1Beta3RestStub: @@ -474,6 +606,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_aggregated_list_jobs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_aggregated_list_jobs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -643,6 +779,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -786,6 +926,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -936,6 +1080,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_jobs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_jobs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1089,6 +1237,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_snapshot_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_snapshot_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1240,6 +1392,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/messages_v1_beta3/client.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/messages_v1_beta3/client.py index a539108831ae..af85219277d7 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/messages_v1_beta3/client.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/messages_v1_beta3/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -464,6 +466,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/messages_v1_beta3/transports/rest.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/messages_v1_beta3/transports/rest.py index e34a59dadc9e..ada8d871681a 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/messages_v1_beta3/transports/rest.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/messages_v1_beta3/transports/rest.py @@ -101,12 +101,37 @@ def post_list_job_messages( ) -> messages.ListJobMessagesResponse: """Post-rpc interceptor for list_job_messages - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_job_messages_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the MessagesV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_list_job_messages` interceptor runs + before the `post_list_job_messages_with_metadata` interceptor. """ return response + def post_list_job_messages_with_metadata( + self, + response: messages.ListJobMessagesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + messages.ListJobMessagesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_job_messages + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MessagesV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_list_job_messages_with_metadata` + interceptor in new development instead of the `post_list_job_messages` interceptor. + When both interceptors are used, this `post_list_job_messages_with_metadata` interceptor runs after the + `post_list_job_messages` interceptor. The (possibly modified) response returned by + `post_list_job_messages` will be passed to + `post_list_job_messages_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class MessagesV1Beta3RestStub: @@ -320,6 +345,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_job_messages(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_job_messages_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/metrics_v1_beta3/client.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/metrics_v1_beta3/client.py index 3974d1e608b3..067dfcf1c399 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/metrics_v1_beta3/client.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/metrics_v1_beta3/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -466,6 +468,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/metrics_v1_beta3/transports/rest.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/metrics_v1_beta3/transports/rest.py index 1166941a61d3..1a3a46e5b4fe 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/metrics_v1_beta3/transports/rest.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/metrics_v1_beta3/transports/rest.py @@ -117,12 +117,35 @@ def post_get_job_execution_details( ) -> metrics.JobExecutionDetails: """Post-rpc interceptor for get_job_execution_details - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_job_execution_details_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the MetricsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_get_job_execution_details` interceptor runs + before the `post_get_job_execution_details_with_metadata` interceptor. """ return response + def post_get_job_execution_details_with_metadata( + self, + response: metrics.JobExecutionDetails, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metrics.JobExecutionDetails, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_job_execution_details + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MetricsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_get_job_execution_details_with_metadata` + interceptor in new development instead of the `post_get_job_execution_details` interceptor. + When both interceptors are used, this `post_get_job_execution_details_with_metadata` interceptor runs after the + `post_get_job_execution_details` interceptor. The (possibly modified) response returned by + `post_get_job_execution_details` will be passed to + `post_get_job_execution_details_with_metadata`. + """ + return response, metadata + def pre_get_job_metrics( self, request: metrics.GetJobMetricsRequest, @@ -138,12 +161,35 @@ def pre_get_job_metrics( def post_get_job_metrics(self, response: metrics.JobMetrics) -> metrics.JobMetrics: """Post-rpc interceptor for get_job_metrics - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_job_metrics_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the MetricsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_get_job_metrics` interceptor runs + before the `post_get_job_metrics_with_metadata` interceptor. """ return response + def post_get_job_metrics_with_metadata( + self, + response: metrics.JobMetrics, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metrics.JobMetrics, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_job_metrics + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MetricsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_get_job_metrics_with_metadata` + interceptor in new development instead of the `post_get_job_metrics` interceptor. + When both interceptors are used, this `post_get_job_metrics_with_metadata` interceptor runs after the + `post_get_job_metrics` interceptor. The (possibly modified) response returned by + `post_get_job_metrics` will be passed to + `post_get_job_metrics_with_metadata`. + """ + return response, metadata + def pre_get_stage_execution_details( self, request: metrics.GetStageExecutionDetailsRequest, @@ -163,12 +209,35 @@ def post_get_stage_execution_details( ) -> metrics.StageExecutionDetails: """Post-rpc interceptor for get_stage_execution_details - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_stage_execution_details_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the MetricsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_get_stage_execution_details` interceptor runs + before the `post_get_stage_execution_details_with_metadata` interceptor. """ return response + def post_get_stage_execution_details_with_metadata( + self, + response: metrics.StageExecutionDetails, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metrics.StageExecutionDetails, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_stage_execution_details + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the MetricsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_get_stage_execution_details_with_metadata` + interceptor in new development instead of the `post_get_stage_execution_details` interceptor. + When both interceptors are used, this `post_get_stage_execution_details_with_metadata` interceptor runs after the + `post_get_stage_execution_details` interceptor. The (possibly modified) response returned by + `post_get_stage_execution_details` will be passed to + `post_get_stage_execution_details_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class MetricsV1Beta3RestStub: @@ -381,6 +450,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_job_execution_details(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_job_execution_details_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -532,6 +605,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_job_metrics(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_job_metrics_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -682,6 +759,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_stage_execution_details(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_stage_execution_details_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/snapshots_v1_beta3/client.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/snapshots_v1_beta3/client.py index 74540655751b..42b87cb8b645 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/snapshots_v1_beta3/client.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/snapshots_v1_beta3/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -466,6 +468,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/snapshots_v1_beta3/transports/rest.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/snapshots_v1_beta3/transports/rest.py index 625d64d36519..f5ad6c3d2379 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/snapshots_v1_beta3/transports/rest.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/snapshots_v1_beta3/transports/rest.py @@ -117,12 +117,37 @@ def post_delete_snapshot( ) -> snapshots.DeleteSnapshotResponse: """Post-rpc interceptor for delete_snapshot - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_snapshot_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SnapshotsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_delete_snapshot` interceptor runs + before the `post_delete_snapshot_with_metadata` interceptor. """ return response + def post_delete_snapshot_with_metadata( + self, + response: snapshots.DeleteSnapshotResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + snapshots.DeleteSnapshotResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for delete_snapshot + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SnapshotsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_delete_snapshot_with_metadata` + interceptor in new development instead of the `post_delete_snapshot` interceptor. + When both interceptors are used, this `post_delete_snapshot_with_metadata` interceptor runs after the + `post_delete_snapshot` interceptor. The (possibly modified) response returned by + `post_delete_snapshot` will be passed to + `post_delete_snapshot_with_metadata`. + """ + return response, metadata + def pre_get_snapshot( self, request: snapshots.GetSnapshotRequest, @@ -138,12 +163,35 @@ def pre_get_snapshot( def post_get_snapshot(self, response: snapshots.Snapshot) -> snapshots.Snapshot: """Post-rpc interceptor for get_snapshot - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_snapshot_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SnapshotsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_get_snapshot` interceptor runs + before the `post_get_snapshot_with_metadata` interceptor. """ return response + def post_get_snapshot_with_metadata( + self, + response: snapshots.Snapshot, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[snapshots.Snapshot, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_snapshot + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SnapshotsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_get_snapshot_with_metadata` + interceptor in new development instead of the `post_get_snapshot` interceptor. + When both interceptors are used, this `post_get_snapshot_with_metadata` interceptor runs after the + `post_get_snapshot` interceptor. The (possibly modified) response returned by + `post_get_snapshot` will be passed to + `post_get_snapshot_with_metadata`. + """ + return response, metadata + def pre_list_snapshots( self, request: snapshots.ListSnapshotsRequest, @@ -161,12 +209,37 @@ def post_list_snapshots( ) -> snapshots.ListSnapshotsResponse: """Post-rpc interceptor for list_snapshots - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_snapshots_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SnapshotsV1Beta3 server but before - it is returned to user code. + it is returned to user code. This `post_list_snapshots` interceptor runs + before the `post_list_snapshots_with_metadata` interceptor. """ return response + def post_list_snapshots_with_metadata( + self, + response: snapshots.ListSnapshotsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + snapshots.ListSnapshotsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_snapshots + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SnapshotsV1Beta3 server but before it is returned to user code. + + We recommend only using this `post_list_snapshots_with_metadata` + interceptor in new development instead of the `post_list_snapshots` interceptor. + When both interceptors are used, this `post_list_snapshots_with_metadata` interceptor runs after the + `post_list_snapshots` interceptor. The (possibly modified) response returned by + `post_list_snapshots` will be passed to + `post_list_snapshots_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class SnapshotsV1Beta3RestStub: @@ -372,6 +445,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_snapshot(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_snapshot_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -515,6 +592,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_snapshot(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_snapshot_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -655,6 +736,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_snapshots(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_snapshots_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/templates_service/client.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/templates_service/client.py index 4de564ffc698..834ed7a21579 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/templates_service/client.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/templates_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -466,6 +468,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/templates_service/transports/rest.py b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/templates_service/transports/rest.py index 7211a753a289..cc898e03aaca 100644 --- a/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/templates_service/transports/rest.py +++ b/packages/google-cloud-dataflow-client/google/cloud/dataflow_v1beta3/services/templates_service/transports/rest.py @@ -115,12 +115,33 @@ def pre_create_job_from_template( def post_create_job_from_template(self, response: jobs.Job) -> jobs.Job: """Post-rpc interceptor for create_job_from_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_job_from_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TemplatesService server but before - it is returned to user code. + it is returned to user code. This `post_create_job_from_template` interceptor runs + before the `post_create_job_from_template_with_metadata` interceptor. """ return response + def post_create_job_from_template_with_metadata( + self, response: jobs.Job, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[jobs.Job, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_job_from_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TemplatesService server but before it is returned to user code. + + We recommend only using this `post_create_job_from_template_with_metadata` + interceptor in new development instead of the `post_create_job_from_template` interceptor. + When both interceptors are used, this `post_create_job_from_template_with_metadata` interceptor runs after the + `post_create_job_from_template` interceptor. The (possibly modified) response returned by + `post_create_job_from_template` will be passed to + `post_create_job_from_template_with_metadata`. + """ + return response, metadata + def pre_get_template( self, request: templates.GetTemplateRequest, @@ -138,12 +159,35 @@ def post_get_template( ) -> templates.GetTemplateResponse: """Post-rpc interceptor for get_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TemplatesService server but before - it is returned to user code. + it is returned to user code. This `post_get_template` interceptor runs + before the `post_get_template_with_metadata` interceptor. """ return response + def post_get_template_with_metadata( + self, + response: templates.GetTemplateResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[templates.GetTemplateResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TemplatesService server but before it is returned to user code. + + We recommend only using this `post_get_template_with_metadata` + interceptor in new development instead of the `post_get_template` interceptor. + When both interceptors are used, this `post_get_template_with_metadata` interceptor runs after the + `post_get_template` interceptor. The (possibly modified) response returned by + `post_get_template` will be passed to + `post_get_template_with_metadata`. + """ + return response, metadata + def pre_launch_template( self, request: templates.LaunchTemplateRequest, @@ -163,12 +207,37 @@ def post_launch_template( ) -> templates.LaunchTemplateResponse: """Post-rpc interceptor for launch_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_launch_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TemplatesService server but before - it is returned to user code. + it is returned to user code. This `post_launch_template` interceptor runs + before the `post_launch_template_with_metadata` interceptor. """ return response + def post_launch_template_with_metadata( + self, + response: templates.LaunchTemplateResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + templates.LaunchTemplateResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for launch_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TemplatesService server but before it is returned to user code. + + We recommend only using this `post_launch_template_with_metadata` + interceptor in new development instead of the `post_launch_template` interceptor. + When both interceptors are used, this `post_launch_template_with_metadata` interceptor runs after the + `post_launch_template` interceptor. The (possibly modified) response returned by + `post_launch_template` will be passed to + `post_launch_template_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class TemplatesServiceRestStub: @@ -388,6 +457,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_job_from_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_job_from_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -531,6 +604,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -679,6 +756,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_launch_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_launch_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataflow-client/samples/generated_samples/snippet_metadata_google.dataflow.v1beta3.json b/packages/google-cloud-dataflow-client/samples/generated_samples/snippet_metadata_google.dataflow.v1beta3.json index 2b8596034c81..80b091d09c04 100644 --- a/packages/google-cloud-dataflow-client/samples/generated_samples/snippet_metadata_google.dataflow.v1beta3.json +++ b/packages/google-cloud-dataflow-client/samples/generated_samples/snippet_metadata_google.dataflow.v1beta3.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dataflow-client", - "version": "0.8.15" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_flex_templates_service.py b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_flex_templates_service.py index 1837f09caa75..cad3272f73df 100644 --- a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_flex_templates_service.py +++ b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_flex_templates_service.py @@ -59,6 +59,13 @@ ) from google.cloud.dataflow_v1beta3.types import environment, jobs, templates +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -332,6 +339,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = FlexTemplatesServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = FlexTemplatesServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1673,10 +1723,14 @@ def test_launch_flex_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlexTemplatesServiceRestInterceptor, "post_launch_flex_template" ) as post, mock.patch.object( + transports.FlexTemplatesServiceRestInterceptor, + "post_launch_flex_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.FlexTemplatesServiceRestInterceptor, "pre_launch_flex_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = templates.LaunchFlexTemplateRequest.pb( templates.LaunchFlexTemplateRequest() ) @@ -1702,6 +1756,10 @@ def test_launch_flex_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = templates.LaunchFlexTemplateResponse() + post_with_metadata.return_value = ( + templates.LaunchFlexTemplateResponse(), + metadata, + ) client.launch_flex_template( request, @@ -1713,6 +1771,7 @@ def test_launch_flex_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_jobs_v1_beta3.py b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_jobs_v1_beta3.py index 5293d5aca195..538753212f35 100644 --- a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_jobs_v1_beta3.py +++ b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_jobs_v1_beta3.py @@ -64,6 +64,13 @@ ) from google.cloud.dataflow_v1beta3.types import environment, jobs, snapshots +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -303,6 +310,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = JobsV1Beta3Client(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = JobsV1Beta3Client(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4565,10 +4615,13 @@ def test_create_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "post_create_job" ) as post, mock.patch.object( + transports.JobsV1Beta3RestInterceptor, "post_create_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "pre_create_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.CreateJobRequest.pb(jobs.CreateJobRequest()) transcode.return_value = { "method": "post", @@ -4590,6 +4643,7 @@ def test_create_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.Job() + post_with_metadata.return_value = jobs.Job(), metadata client.create_job( request, @@ -4601,6 +4655,7 @@ def test_create_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_job_rest_bad_request(request_type=jobs.GetJobRequest): @@ -4709,10 +4764,13 @@ def test_get_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "post_get_job" ) as post, mock.patch.object( + transports.JobsV1Beta3RestInterceptor, "post_get_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "pre_get_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.GetJobRequest.pb(jobs.GetJobRequest()) transcode.return_value = { "method": "post", @@ -4734,6 +4792,7 @@ def test_get_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.Job() + post_with_metadata.return_value = jobs.Job(), metadata client.get_job( request, @@ -4745,6 +4804,7 @@ def test_get_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_job_rest_bad_request(request_type=jobs.UpdateJobRequest): @@ -5144,10 +5204,13 @@ def test_update_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "post_update_job" ) as post, mock.patch.object( + transports.JobsV1Beta3RestInterceptor, "post_update_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "pre_update_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.UpdateJobRequest.pb(jobs.UpdateJobRequest()) transcode.return_value = { "method": "post", @@ -5169,6 +5232,7 @@ def test_update_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.Job() + post_with_metadata.return_value = jobs.Job(), metadata client.update_job( request, @@ -5180,6 +5244,7 @@ def test_update_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_jobs_rest_bad_request(request_type=jobs.ListJobsRequest): @@ -5262,10 +5327,13 @@ def test_list_jobs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "post_list_jobs" ) as post, mock.patch.object( + transports.JobsV1Beta3RestInterceptor, "post_list_jobs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "pre_list_jobs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.ListJobsRequest.pb(jobs.ListJobsRequest()) transcode.return_value = { "method": "post", @@ -5287,6 +5355,7 @@ def test_list_jobs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.ListJobsResponse() + post_with_metadata.return_value = jobs.ListJobsResponse(), metadata client.list_jobs( request, @@ -5298,6 +5367,7 @@ def test_list_jobs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_aggregated_list_jobs_rest_bad_request(request_type=jobs.ListJobsRequest): @@ -5380,10 +5450,13 @@ def test_aggregated_list_jobs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "post_aggregated_list_jobs" ) as post, mock.patch.object( + transports.JobsV1Beta3RestInterceptor, "post_aggregated_list_jobs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "pre_aggregated_list_jobs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.ListJobsRequest.pb(jobs.ListJobsRequest()) transcode.return_value = { "method": "post", @@ -5405,6 +5478,7 @@ def test_aggregated_list_jobs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.ListJobsResponse() + post_with_metadata.return_value = jobs.ListJobsResponse(), metadata client.aggregated_list_jobs( request, @@ -5416,6 +5490,7 @@ def test_aggregated_list_jobs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_check_active_jobs_rest_error(): @@ -5522,10 +5597,13 @@ def test_snapshot_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "post_snapshot_job" ) as post, mock.patch.object( + transports.JobsV1Beta3RestInterceptor, "post_snapshot_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobsV1Beta3RestInterceptor, "pre_snapshot_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.SnapshotJobRequest.pb(jobs.SnapshotJobRequest()) transcode.return_value = { "method": "post", @@ -5547,6 +5625,7 @@ def test_snapshot_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = snapshots.Snapshot() + post_with_metadata.return_value = snapshots.Snapshot(), metadata client.snapshot_job( request, @@ -5558,6 +5637,7 @@ def test_snapshot_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_messages_v1_beta3.py b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_messages_v1_beta3.py index afb9ec120b0b..7748d6fefd3a 100644 --- a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_messages_v1_beta3.py +++ b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_messages_v1_beta3.py @@ -61,6 +61,13 @@ ) from google.cloud.dataflow_v1beta3.types import messages +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -319,6 +326,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = MessagesV1Beta3Client(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = MessagesV1Beta3Client(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1925,10 +1975,14 @@ def test_list_job_messages_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.MessagesV1Beta3RestInterceptor, "post_list_job_messages" ) as post, mock.patch.object( + transports.MessagesV1Beta3RestInterceptor, + "post_list_job_messages_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.MessagesV1Beta3RestInterceptor, "pre_list_job_messages" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = messages.ListJobMessagesRequest.pb( messages.ListJobMessagesRequest() ) @@ -1954,6 +2008,7 @@ def test_list_job_messages_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = messages.ListJobMessagesResponse() + post_with_metadata.return_value = messages.ListJobMessagesResponse(), metadata client.list_job_messages( request, @@ -1965,6 +2020,7 @@ def test_list_job_messages_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_metrics_v1_beta3.py b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_metrics_v1_beta3.py index 72d841d63e93..e1a3e25c2ff2 100644 --- a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_metrics_v1_beta3.py +++ b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_metrics_v1_beta3.py @@ -61,6 +61,13 @@ ) from google.cloud.dataflow_v1beta3.types import metrics +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -319,6 +326,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = MetricsV1Beta3Client(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = MetricsV1Beta3Client(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2868,10 +2918,13 @@ def test_get_job_metrics_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.MetricsV1Beta3RestInterceptor, "post_get_job_metrics" ) as post, mock.patch.object( + transports.MetricsV1Beta3RestInterceptor, "post_get_job_metrics_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.MetricsV1Beta3RestInterceptor, "pre_get_job_metrics" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metrics.GetJobMetricsRequest.pb(metrics.GetJobMetricsRequest()) transcode.return_value = { "method": "post", @@ -2893,6 +2946,7 @@ def test_get_job_metrics_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metrics.JobMetrics() + post_with_metadata.return_value = metrics.JobMetrics(), metadata client.get_job_metrics( request, @@ -2904,6 +2958,7 @@ def test_get_job_metrics_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_job_execution_details_rest_bad_request( @@ -2988,10 +3043,14 @@ def test_get_job_execution_details_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.MetricsV1Beta3RestInterceptor, "post_get_job_execution_details" ) as post, mock.patch.object( + transports.MetricsV1Beta3RestInterceptor, + "post_get_job_execution_details_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.MetricsV1Beta3RestInterceptor, "pre_get_job_execution_details" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metrics.GetJobExecutionDetailsRequest.pb( metrics.GetJobExecutionDetailsRequest() ) @@ -3017,6 +3076,7 @@ def test_get_job_execution_details_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metrics.JobExecutionDetails() + post_with_metadata.return_value = metrics.JobExecutionDetails(), metadata client.get_job_execution_details( request, @@ -3028,6 +3088,7 @@ def test_get_job_execution_details_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_stage_execution_details_rest_bad_request( @@ -3122,10 +3183,14 @@ def test_get_stage_execution_details_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.MetricsV1Beta3RestInterceptor, "post_get_stage_execution_details" ) as post, mock.patch.object( + transports.MetricsV1Beta3RestInterceptor, + "post_get_stage_execution_details_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.MetricsV1Beta3RestInterceptor, "pre_get_stage_execution_details" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metrics.GetStageExecutionDetailsRequest.pb( metrics.GetStageExecutionDetailsRequest() ) @@ -3151,6 +3216,7 @@ def test_get_stage_execution_details_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metrics.StageExecutionDetails() + post_with_metadata.return_value = metrics.StageExecutionDetails(), metadata client.get_stage_execution_details( request, @@ -3162,6 +3228,7 @@ def test_get_stage_execution_details_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_snapshots_v1_beta3.py b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_snapshots_v1_beta3.py index 3edcd11f8875..56bfc4600509 100644 --- a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_snapshots_v1_beta3.py +++ b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_snapshots_v1_beta3.py @@ -61,6 +61,13 @@ ) from google.cloud.dataflow_v1beta3.types import snapshots +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -320,6 +327,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SnapshotsV1Beta3Client(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SnapshotsV1Beta3Client(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2334,10 +2384,13 @@ def test_get_snapshot_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SnapshotsV1Beta3RestInterceptor, "post_get_snapshot" ) as post, mock.patch.object( + transports.SnapshotsV1Beta3RestInterceptor, "post_get_snapshot_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SnapshotsV1Beta3RestInterceptor, "pre_get_snapshot" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = snapshots.GetSnapshotRequest.pb(snapshots.GetSnapshotRequest()) transcode.return_value = { "method": "post", @@ -2359,6 +2412,7 @@ def test_get_snapshot_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = snapshots.Snapshot() + post_with_metadata.return_value = snapshots.Snapshot(), metadata client.get_snapshot( request, @@ -2370,6 +2424,7 @@ def test_get_snapshot_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_snapshot_rest_bad_request(request_type=snapshots.DeleteSnapshotRequest): @@ -2457,10 +2512,13 @@ def test_delete_snapshot_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SnapshotsV1Beta3RestInterceptor, "post_delete_snapshot" ) as post, mock.patch.object( + transports.SnapshotsV1Beta3RestInterceptor, "post_delete_snapshot_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SnapshotsV1Beta3RestInterceptor, "pre_delete_snapshot" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = snapshots.DeleteSnapshotRequest.pb( snapshots.DeleteSnapshotRequest() ) @@ -2486,6 +2544,7 @@ def test_delete_snapshot_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = snapshots.DeleteSnapshotResponse() + post_with_metadata.return_value = snapshots.DeleteSnapshotResponse(), metadata client.delete_snapshot( request, @@ -2497,6 +2556,7 @@ def test_delete_snapshot_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_snapshots_rest_bad_request(request_type=snapshots.ListSnapshotsRequest): @@ -2576,10 +2636,13 @@ def test_list_snapshots_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SnapshotsV1Beta3RestInterceptor, "post_list_snapshots" ) as post, mock.patch.object( + transports.SnapshotsV1Beta3RestInterceptor, "post_list_snapshots_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SnapshotsV1Beta3RestInterceptor, "pre_list_snapshots" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = snapshots.ListSnapshotsRequest.pb(snapshots.ListSnapshotsRequest()) transcode.return_value = { "method": "post", @@ -2603,6 +2666,7 @@ def test_list_snapshots_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = snapshots.ListSnapshotsResponse() + post_with_metadata.return_value = snapshots.ListSnapshotsResponse(), metadata client.list_snapshots( request, @@ -2614,6 +2678,7 @@ def test_list_snapshots_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_templates_service.py b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_templates_service.py index 906f76fb96db..42d075c5e628 100644 --- a/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_templates_service.py +++ b/packages/google-cloud-dataflow-client/tests/unit/gapic/dataflow_v1beta3/test_templates_service.py @@ -61,6 +61,13 @@ ) from google.cloud.dataflow_v1beta3.types import environment, jobs, templates +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -320,6 +327,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = TemplatesServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = TemplatesServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2405,10 +2455,14 @@ def test_create_job_from_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TemplatesServiceRestInterceptor, "post_create_job_from_template" ) as post, mock.patch.object( + transports.TemplatesServiceRestInterceptor, + "post_create_job_from_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.TemplatesServiceRestInterceptor, "pre_create_job_from_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = templates.CreateJobFromTemplateRequest.pb( templates.CreateJobFromTemplateRequest() ) @@ -2432,6 +2486,7 @@ def test_create_job_from_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.Job() + post_with_metadata.return_value = jobs.Job(), metadata client.create_job_from_template( request, @@ -2443,6 +2498,7 @@ def test_create_job_from_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_launch_template_rest_bad_request(request_type=templates.LaunchTemplateRequest): @@ -2616,10 +2672,13 @@ def test_launch_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TemplatesServiceRestInterceptor, "post_launch_template" ) as post, mock.patch.object( + transports.TemplatesServiceRestInterceptor, "post_launch_template_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TemplatesServiceRestInterceptor, "pre_launch_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = templates.LaunchTemplateRequest.pb( templates.LaunchTemplateRequest() ) @@ -2645,6 +2704,7 @@ def test_launch_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = templates.LaunchTemplateResponse() + post_with_metadata.return_value = templates.LaunchTemplateResponse(), metadata client.launch_template( request, @@ -2656,6 +2716,7 @@ def test_launch_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_template_rest_bad_request(request_type=templates.GetTemplateRequest): @@ -2738,10 +2799,13 @@ def test_get_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TemplatesServiceRestInterceptor, "post_get_template" ) as post, mock.patch.object( + transports.TemplatesServiceRestInterceptor, "post_get_template_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TemplatesServiceRestInterceptor, "pre_get_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = templates.GetTemplateRequest.pb(templates.GetTemplateRequest()) transcode.return_value = { "method": "post", @@ -2765,6 +2829,7 @@ def test_get_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = templates.GetTemplateResponse() + post_with_metadata.return_value = templates.GetTemplateResponse(), metadata client.get_template( request, @@ -2776,6 +2841,7 @@ def test_get_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-dataform/google/cloud/dataform/gapic_version.py b/packages/google-cloud-dataform/google/cloud/dataform/gapic_version.py index 0f3dcb10f73a..558c8aab67c5 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform/gapic_version.py +++ b/packages/google-cloud-dataform/google/cloud/dataform/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.14" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/gapic_version.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/gapic_version.py index 0f3dcb10f73a..558c8aab67c5 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/gapic_version.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.14" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/client.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/client.py index 10cb6cbb3c2c..24509e5a8f43 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/client.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -634,6 +636,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -5951,16 +5980,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -6073,16 +6106,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -6133,16 +6170,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_location( self, @@ -6188,16 +6229,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -6243,16 +6288,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest.py b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest.py index 5c585373e904..2662fe69d156 100644 --- a/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest.py +++ b/packages/google-cloud-dataform/google/cloud/dataform_v1beta1/services/dataform/transports/rest.py @@ -497,12 +497,38 @@ def post_compute_repository_access_token_status( ) -> dataform.ComputeRepositoryAccessTokenStatusResponse: """Post-rpc interceptor for compute_repository_access_token_status - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_compute_repository_access_token_status_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_compute_repository_access_token_status` interceptor runs + before the `post_compute_repository_access_token_status_with_metadata` interceptor. """ return response + def post_compute_repository_access_token_status_with_metadata( + self, + response: dataform.ComputeRepositoryAccessTokenStatusResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.ComputeRepositoryAccessTokenStatusResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for compute_repository_access_token_status + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_compute_repository_access_token_status_with_metadata` + interceptor in new development instead of the `post_compute_repository_access_token_status` interceptor. + When both interceptors are used, this `post_compute_repository_access_token_status_with_metadata` interceptor runs after the + `post_compute_repository_access_token_status` interceptor. The (possibly modified) response returned by + `post_compute_repository_access_token_status` will be passed to + `post_compute_repository_access_token_status_with_metadata`. + """ + return response, metadata + def pre_create_compilation_result( self, request: dataform.CreateCompilationResultRequest, @@ -522,12 +548,35 @@ def post_create_compilation_result( ) -> dataform.CompilationResult: """Post-rpc interceptor for create_compilation_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_compilation_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_create_compilation_result` interceptor runs + before the `post_create_compilation_result_with_metadata` interceptor. """ return response + def post_create_compilation_result_with_metadata( + self, + response: dataform.CompilationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.CompilationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_compilation_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_create_compilation_result_with_metadata` + interceptor in new development instead of the `post_create_compilation_result` interceptor. + When both interceptors are used, this `post_create_compilation_result_with_metadata` interceptor runs after the + `post_create_compilation_result` interceptor. The (possibly modified) response returned by + `post_create_compilation_result` will be passed to + `post_create_compilation_result_with_metadata`. + """ + return response, metadata + def pre_create_release_config( self, request: dataform.CreateReleaseConfigRequest, @@ -547,12 +596,35 @@ def post_create_release_config( ) -> dataform.ReleaseConfig: """Post-rpc interceptor for create_release_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_release_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_create_release_config` interceptor runs + before the `post_create_release_config_with_metadata` interceptor. """ return response + def post_create_release_config_with_metadata( + self, + response: dataform.ReleaseConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.ReleaseConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_release_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_create_release_config_with_metadata` + interceptor in new development instead of the `post_create_release_config` interceptor. + When both interceptors are used, this `post_create_release_config_with_metadata` interceptor runs after the + `post_create_release_config` interceptor. The (possibly modified) response returned by + `post_create_release_config` will be passed to + `post_create_release_config_with_metadata`. + """ + return response, metadata + def pre_create_repository( self, request: dataform.CreateRepositoryRequest, @@ -572,12 +644,35 @@ def post_create_repository( ) -> dataform.Repository: """Post-rpc interceptor for create_repository - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_repository_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_create_repository` interceptor runs + before the `post_create_repository_with_metadata` interceptor. """ return response + def post_create_repository_with_metadata( + self, + response: dataform.Repository, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.Repository, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_repository + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_create_repository_with_metadata` + interceptor in new development instead of the `post_create_repository` interceptor. + When both interceptors are used, this `post_create_repository_with_metadata` interceptor runs after the + `post_create_repository` interceptor. The (possibly modified) response returned by + `post_create_repository` will be passed to + `post_create_repository_with_metadata`. + """ + return response, metadata + def pre_create_workflow_config( self, request: dataform.CreateWorkflowConfigRequest, @@ -597,12 +692,35 @@ def post_create_workflow_config( ) -> dataform.WorkflowConfig: """Post-rpc interceptor for create_workflow_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_workflow_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_create_workflow_config` interceptor runs + before the `post_create_workflow_config_with_metadata` interceptor. """ return response + def post_create_workflow_config_with_metadata( + self, + response: dataform.WorkflowConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.WorkflowConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_workflow_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_create_workflow_config_with_metadata` + interceptor in new development instead of the `post_create_workflow_config` interceptor. + When both interceptors are used, this `post_create_workflow_config_with_metadata` interceptor runs after the + `post_create_workflow_config` interceptor. The (possibly modified) response returned by + `post_create_workflow_config` will be passed to + `post_create_workflow_config_with_metadata`. + """ + return response, metadata + def pre_create_workflow_invocation( self, request: dataform.CreateWorkflowInvocationRequest, @@ -623,12 +741,35 @@ def post_create_workflow_invocation( ) -> dataform.WorkflowInvocation: """Post-rpc interceptor for create_workflow_invocation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_workflow_invocation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_create_workflow_invocation` interceptor runs + before the `post_create_workflow_invocation_with_metadata` interceptor. """ return response + def post_create_workflow_invocation_with_metadata( + self, + response: dataform.WorkflowInvocation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.WorkflowInvocation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_workflow_invocation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_create_workflow_invocation_with_metadata` + interceptor in new development instead of the `post_create_workflow_invocation` interceptor. + When both interceptors are used, this `post_create_workflow_invocation_with_metadata` interceptor runs after the + `post_create_workflow_invocation` interceptor. The (possibly modified) response returned by + `post_create_workflow_invocation` will be passed to + `post_create_workflow_invocation_with_metadata`. + """ + return response, metadata + def pre_create_workspace( self, request: dataform.CreateWorkspaceRequest, @@ -646,12 +787,35 @@ def pre_create_workspace( def post_create_workspace(self, response: dataform.Workspace) -> dataform.Workspace: """Post-rpc interceptor for create_workspace - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_workspace_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_create_workspace` interceptor runs + before the `post_create_workspace_with_metadata` interceptor. """ return response + def post_create_workspace_with_metadata( + self, + response: dataform.Workspace, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.Workspace, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_workspace + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_create_workspace_with_metadata` + interceptor in new development instead of the `post_create_workspace` interceptor. + When both interceptors are used, this `post_create_workspace_with_metadata` interceptor runs after the + `post_create_workspace` interceptor. The (possibly modified) response returned by + `post_create_workspace` will be passed to + `post_create_workspace_with_metadata`. + """ + return response, metadata + def pre_delete_release_config( self, request: dataform.DeleteReleaseConfigRequest, @@ -740,12 +904,35 @@ def post_fetch_file_diff( ) -> dataform.FetchFileDiffResponse: """Post-rpc interceptor for fetch_file_diff - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_file_diff_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_fetch_file_diff` interceptor runs + before the `post_fetch_file_diff_with_metadata` interceptor. """ return response + def post_fetch_file_diff_with_metadata( + self, + response: dataform.FetchFileDiffResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.FetchFileDiffResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for fetch_file_diff + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_fetch_file_diff_with_metadata` + interceptor in new development instead of the `post_fetch_file_diff` interceptor. + When both interceptors are used, this `post_fetch_file_diff_with_metadata` interceptor runs after the + `post_fetch_file_diff` interceptor. The (possibly modified) response returned by + `post_fetch_file_diff` will be passed to + `post_fetch_file_diff_with_metadata`. + """ + return response, metadata + def pre_fetch_file_git_statuses( self, request: dataform.FetchFileGitStatusesRequest, @@ -765,12 +952,37 @@ def post_fetch_file_git_statuses( ) -> dataform.FetchFileGitStatusesResponse: """Post-rpc interceptor for fetch_file_git_statuses - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_file_git_statuses_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_fetch_file_git_statuses` interceptor runs + before the `post_fetch_file_git_statuses_with_metadata` interceptor. """ return response + def post_fetch_file_git_statuses_with_metadata( + self, + response: dataform.FetchFileGitStatusesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.FetchFileGitStatusesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for fetch_file_git_statuses + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_fetch_file_git_statuses_with_metadata` + interceptor in new development instead of the `post_fetch_file_git_statuses` interceptor. + When both interceptors are used, this `post_fetch_file_git_statuses_with_metadata` interceptor runs after the + `post_fetch_file_git_statuses` interceptor. The (possibly modified) response returned by + `post_fetch_file_git_statuses` will be passed to + `post_fetch_file_git_statuses_with_metadata`. + """ + return response, metadata + def pre_fetch_git_ahead_behind( self, request: dataform.FetchGitAheadBehindRequest, @@ -790,12 +1002,37 @@ def post_fetch_git_ahead_behind( ) -> dataform.FetchGitAheadBehindResponse: """Post-rpc interceptor for fetch_git_ahead_behind - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_git_ahead_behind_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_fetch_git_ahead_behind` interceptor runs + before the `post_fetch_git_ahead_behind_with_metadata` interceptor. """ return response + def post_fetch_git_ahead_behind_with_metadata( + self, + response: dataform.FetchGitAheadBehindResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.FetchGitAheadBehindResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for fetch_git_ahead_behind + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_fetch_git_ahead_behind_with_metadata` + interceptor in new development instead of the `post_fetch_git_ahead_behind` interceptor. + When both interceptors are used, this `post_fetch_git_ahead_behind_with_metadata` interceptor runs after the + `post_fetch_git_ahead_behind` interceptor. The (possibly modified) response returned by + `post_fetch_git_ahead_behind` will be passed to + `post_fetch_git_ahead_behind_with_metadata`. + """ + return response, metadata + def pre_fetch_remote_branches( self, request: dataform.FetchRemoteBranchesRequest, @@ -815,12 +1052,37 @@ def post_fetch_remote_branches( ) -> dataform.FetchRemoteBranchesResponse: """Post-rpc interceptor for fetch_remote_branches - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_remote_branches_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_fetch_remote_branches` interceptor runs + before the `post_fetch_remote_branches_with_metadata` interceptor. """ return response + def post_fetch_remote_branches_with_metadata( + self, + response: dataform.FetchRemoteBranchesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.FetchRemoteBranchesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for fetch_remote_branches + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_fetch_remote_branches_with_metadata` + interceptor in new development instead of the `post_fetch_remote_branches` interceptor. + When both interceptors are used, this `post_fetch_remote_branches_with_metadata` interceptor runs after the + `post_fetch_remote_branches` interceptor. The (possibly modified) response returned by + `post_fetch_remote_branches` will be passed to + `post_fetch_remote_branches_with_metadata`. + """ + return response, metadata + def pre_fetch_repository_history( self, request: dataform.FetchRepositoryHistoryRequest, @@ -840,12 +1102,37 @@ def post_fetch_repository_history( ) -> dataform.FetchRepositoryHistoryResponse: """Post-rpc interceptor for fetch_repository_history - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_repository_history_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_fetch_repository_history` interceptor runs + before the `post_fetch_repository_history_with_metadata` interceptor. """ return response + def post_fetch_repository_history_with_metadata( + self, + response: dataform.FetchRepositoryHistoryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.FetchRepositoryHistoryResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for fetch_repository_history + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_fetch_repository_history_with_metadata` + interceptor in new development instead of the `post_fetch_repository_history` interceptor. + When both interceptors are used, this `post_fetch_repository_history_with_metadata` interceptor runs after the + `post_fetch_repository_history` interceptor. The (possibly modified) response returned by + `post_fetch_repository_history` will be passed to + `post_fetch_repository_history_with_metadata`. + """ + return response, metadata + def pre_get_compilation_result( self, request: dataform.GetCompilationResultRequest, @@ -865,12 +1152,35 @@ def post_get_compilation_result( ) -> dataform.CompilationResult: """Post-rpc interceptor for get_compilation_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_compilation_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_get_compilation_result` interceptor runs + before the `post_get_compilation_result_with_metadata` interceptor. """ return response + def post_get_compilation_result_with_metadata( + self, + response: dataform.CompilationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.CompilationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_compilation_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_get_compilation_result_with_metadata` + interceptor in new development instead of the `post_get_compilation_result` interceptor. + When both interceptors are used, this `post_get_compilation_result_with_metadata` interceptor runs after the + `post_get_compilation_result` interceptor. The (possibly modified) response returned by + `post_get_compilation_result` will be passed to + `post_get_compilation_result_with_metadata`. + """ + return response, metadata + def pre_get_release_config( self, request: dataform.GetReleaseConfigRequest, @@ -890,12 +1200,35 @@ def post_get_release_config( ) -> dataform.ReleaseConfig: """Post-rpc interceptor for get_release_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_release_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_get_release_config` interceptor runs + before the `post_get_release_config_with_metadata` interceptor. """ return response + def post_get_release_config_with_metadata( + self, + response: dataform.ReleaseConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.ReleaseConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_release_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_get_release_config_with_metadata` + interceptor in new development instead of the `post_get_release_config` interceptor. + When both interceptors are used, this `post_get_release_config_with_metadata` interceptor runs after the + `post_get_release_config` interceptor. The (possibly modified) response returned by + `post_get_release_config` will be passed to + `post_get_release_config_with_metadata`. + """ + return response, metadata + def pre_get_repository( self, request: dataform.GetRepositoryRequest, @@ -911,12 +1244,35 @@ def pre_get_repository( def post_get_repository(self, response: dataform.Repository) -> dataform.Repository: """Post-rpc interceptor for get_repository - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_repository_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_get_repository` interceptor runs + before the `post_get_repository_with_metadata` interceptor. """ return response + def post_get_repository_with_metadata( + self, + response: dataform.Repository, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.Repository, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_repository + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_get_repository_with_metadata` + interceptor in new development instead of the `post_get_repository` interceptor. + When both interceptors are used, this `post_get_repository_with_metadata` interceptor runs after the + `post_get_repository` interceptor. The (possibly modified) response returned by + `post_get_repository` will be passed to + `post_get_repository_with_metadata`. + """ + return response, metadata + def pre_get_workflow_config( self, request: dataform.GetWorkflowConfigRequest, @@ -936,12 +1292,35 @@ def post_get_workflow_config( ) -> dataform.WorkflowConfig: """Post-rpc interceptor for get_workflow_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_workflow_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_get_workflow_config` interceptor runs + before the `post_get_workflow_config_with_metadata` interceptor. """ return response + def post_get_workflow_config_with_metadata( + self, + response: dataform.WorkflowConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.WorkflowConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_workflow_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_get_workflow_config_with_metadata` + interceptor in new development instead of the `post_get_workflow_config` interceptor. + When both interceptors are used, this `post_get_workflow_config_with_metadata` interceptor runs after the + `post_get_workflow_config` interceptor. The (possibly modified) response returned by + `post_get_workflow_config` will be passed to + `post_get_workflow_config_with_metadata`. + """ + return response, metadata + def pre_get_workflow_invocation( self, request: dataform.GetWorkflowInvocationRequest, @@ -961,12 +1340,35 @@ def post_get_workflow_invocation( ) -> dataform.WorkflowInvocation: """Post-rpc interceptor for get_workflow_invocation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_workflow_invocation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_get_workflow_invocation` interceptor runs + before the `post_get_workflow_invocation_with_metadata` interceptor. """ return response + def post_get_workflow_invocation_with_metadata( + self, + response: dataform.WorkflowInvocation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.WorkflowInvocation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_workflow_invocation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_get_workflow_invocation_with_metadata` + interceptor in new development instead of the `post_get_workflow_invocation` interceptor. + When both interceptors are used, this `post_get_workflow_invocation_with_metadata` interceptor runs after the + `post_get_workflow_invocation` interceptor. The (possibly modified) response returned by + `post_get_workflow_invocation` will be passed to + `post_get_workflow_invocation_with_metadata`. + """ + return response, metadata + def pre_get_workspace( self, request: dataform.GetWorkspaceRequest, @@ -982,12 +1384,35 @@ def pre_get_workspace( def post_get_workspace(self, response: dataform.Workspace) -> dataform.Workspace: """Post-rpc interceptor for get_workspace - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_workspace_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_get_workspace` interceptor runs + before the `post_get_workspace_with_metadata` interceptor. """ return response + def post_get_workspace_with_metadata( + self, + response: dataform.Workspace, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.Workspace, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_workspace + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_get_workspace_with_metadata` + interceptor in new development instead of the `post_get_workspace` interceptor. + When both interceptors are used, this `post_get_workspace_with_metadata` interceptor runs after the + `post_get_workspace` interceptor. The (possibly modified) response returned by + `post_get_workspace` will be passed to + `post_get_workspace_with_metadata`. + """ + return response, metadata + def pre_install_npm_packages( self, request: dataform.InstallNpmPackagesRequest, @@ -1007,12 +1432,37 @@ def post_install_npm_packages( ) -> dataform.InstallNpmPackagesResponse: """Post-rpc interceptor for install_npm_packages - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_install_npm_packages_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_install_npm_packages` interceptor runs + before the `post_install_npm_packages_with_metadata` interceptor. """ return response + def post_install_npm_packages_with_metadata( + self, + response: dataform.InstallNpmPackagesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.InstallNpmPackagesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for install_npm_packages + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_install_npm_packages_with_metadata` + interceptor in new development instead of the `post_install_npm_packages` interceptor. + When both interceptors are used, this `post_install_npm_packages_with_metadata` interceptor runs after the + `post_install_npm_packages` interceptor. The (possibly modified) response returned by + `post_install_npm_packages` will be passed to + `post_install_npm_packages_with_metadata`. + """ + return response, metadata + def pre_list_compilation_results( self, request: dataform.ListCompilationResultsRequest, @@ -1032,12 +1482,37 @@ def post_list_compilation_results( ) -> dataform.ListCompilationResultsResponse: """Post-rpc interceptor for list_compilation_results - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_compilation_results_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_list_compilation_results` interceptor runs + before the `post_list_compilation_results_with_metadata` interceptor. """ return response + def post_list_compilation_results_with_metadata( + self, + response: dataform.ListCompilationResultsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.ListCompilationResultsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_compilation_results + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_list_compilation_results_with_metadata` + interceptor in new development instead of the `post_list_compilation_results` interceptor. + When both interceptors are used, this `post_list_compilation_results_with_metadata` interceptor runs after the + `post_list_compilation_results` interceptor. The (possibly modified) response returned by + `post_list_compilation_results` will be passed to + `post_list_compilation_results_with_metadata`. + """ + return response, metadata + def pre_list_release_configs( self, request: dataform.ListReleaseConfigsRequest, @@ -1057,12 +1532,37 @@ def post_list_release_configs( ) -> dataform.ListReleaseConfigsResponse: """Post-rpc interceptor for list_release_configs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_release_configs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_list_release_configs` interceptor runs + before the `post_list_release_configs_with_metadata` interceptor. """ return response + def post_list_release_configs_with_metadata( + self, + response: dataform.ListReleaseConfigsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.ListReleaseConfigsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_release_configs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_list_release_configs_with_metadata` + interceptor in new development instead of the `post_list_release_configs` interceptor. + When both interceptors are used, this `post_list_release_configs_with_metadata` interceptor runs after the + `post_list_release_configs` interceptor. The (possibly modified) response returned by + `post_list_release_configs` will be passed to + `post_list_release_configs_with_metadata`. + """ + return response, metadata + def pre_list_repositories( self, request: dataform.ListRepositoriesRequest, @@ -1082,12 +1582,37 @@ def post_list_repositories( ) -> dataform.ListRepositoriesResponse: """Post-rpc interceptor for list_repositories - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_repositories_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_list_repositories` interceptor runs + before the `post_list_repositories_with_metadata` interceptor. """ return response + def post_list_repositories_with_metadata( + self, + response: dataform.ListRepositoriesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.ListRepositoriesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_repositories + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_list_repositories_with_metadata` + interceptor in new development instead of the `post_list_repositories` interceptor. + When both interceptors are used, this `post_list_repositories_with_metadata` interceptor runs after the + `post_list_repositories` interceptor. The (possibly modified) response returned by + `post_list_repositories` will be passed to + `post_list_repositories_with_metadata`. + """ + return response, metadata + def pre_list_workflow_configs( self, request: dataform.ListWorkflowConfigsRequest, @@ -1107,12 +1632,37 @@ def post_list_workflow_configs( ) -> dataform.ListWorkflowConfigsResponse: """Post-rpc interceptor for list_workflow_configs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_workflow_configs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_list_workflow_configs` interceptor runs + before the `post_list_workflow_configs_with_metadata` interceptor. """ return response + def post_list_workflow_configs_with_metadata( + self, + response: dataform.ListWorkflowConfigsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.ListWorkflowConfigsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_workflow_configs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_list_workflow_configs_with_metadata` + interceptor in new development instead of the `post_list_workflow_configs` interceptor. + When both interceptors are used, this `post_list_workflow_configs_with_metadata` interceptor runs after the + `post_list_workflow_configs` interceptor. The (possibly modified) response returned by + `post_list_workflow_configs` will be passed to + `post_list_workflow_configs_with_metadata`. + """ + return response, metadata + def pre_list_workflow_invocations( self, request: dataform.ListWorkflowInvocationsRequest, @@ -1132,12 +1682,38 @@ def post_list_workflow_invocations( ) -> dataform.ListWorkflowInvocationsResponse: """Post-rpc interceptor for list_workflow_invocations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_workflow_invocations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_list_workflow_invocations` interceptor runs + before the `post_list_workflow_invocations_with_metadata` interceptor. """ return response + def post_list_workflow_invocations_with_metadata( + self, + response: dataform.ListWorkflowInvocationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.ListWorkflowInvocationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_workflow_invocations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_list_workflow_invocations_with_metadata` + interceptor in new development instead of the `post_list_workflow_invocations` interceptor. + When both interceptors are used, this `post_list_workflow_invocations_with_metadata` interceptor runs after the + `post_list_workflow_invocations` interceptor. The (possibly modified) response returned by + `post_list_workflow_invocations` will be passed to + `post_list_workflow_invocations_with_metadata`. + """ + return response, metadata + def pre_list_workspaces( self, request: dataform.ListWorkspacesRequest, @@ -1155,12 +1731,37 @@ def post_list_workspaces( ) -> dataform.ListWorkspacesResponse: """Post-rpc interceptor for list_workspaces - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_workspaces_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_list_workspaces` interceptor runs + before the `post_list_workspaces_with_metadata` interceptor. """ return response + def post_list_workspaces_with_metadata( + self, + response: dataform.ListWorkspacesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.ListWorkspacesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_workspaces + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_list_workspaces_with_metadata` + interceptor in new development instead of the `post_list_workspaces` interceptor. + When both interceptors are used, this `post_list_workspaces_with_metadata` interceptor runs after the + `post_list_workspaces` interceptor. The (possibly modified) response returned by + `post_list_workspaces` will be passed to + `post_list_workspaces_with_metadata`. + """ + return response, metadata + def pre_make_directory( self, request: dataform.MakeDirectoryRequest, @@ -1178,12 +1779,35 @@ def post_make_directory( ) -> dataform.MakeDirectoryResponse: """Post-rpc interceptor for make_directory - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_make_directory_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_make_directory` interceptor runs + before the `post_make_directory_with_metadata` interceptor. """ return response + def post_make_directory_with_metadata( + self, + response: dataform.MakeDirectoryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.MakeDirectoryResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for make_directory + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_make_directory_with_metadata` + interceptor in new development instead of the `post_make_directory` interceptor. + When both interceptors are used, this `post_make_directory_with_metadata` interceptor runs after the + `post_make_directory` interceptor. The (possibly modified) response returned by + `post_make_directory` will be passed to + `post_make_directory_with_metadata`. + """ + return response, metadata + def pre_move_directory( self, request: dataform.MoveDirectoryRequest, @@ -1201,12 +1825,35 @@ def post_move_directory( ) -> dataform.MoveDirectoryResponse: """Post-rpc interceptor for move_directory - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_move_directory_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_move_directory` interceptor runs + before the `post_move_directory_with_metadata` interceptor. """ return response + def post_move_directory_with_metadata( + self, + response: dataform.MoveDirectoryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.MoveDirectoryResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for move_directory + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_move_directory_with_metadata` + interceptor in new development instead of the `post_move_directory` interceptor. + When both interceptors are used, this `post_move_directory_with_metadata` interceptor runs after the + `post_move_directory` interceptor. The (possibly modified) response returned by + `post_move_directory` will be passed to + `post_move_directory_with_metadata`. + """ + return response, metadata + def pre_move_file( self, request: dataform.MoveFileRequest, @@ -1224,12 +1871,35 @@ def post_move_file( ) -> dataform.MoveFileResponse: """Post-rpc interceptor for move_file - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_move_file_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_move_file` interceptor runs + before the `post_move_file_with_metadata` interceptor. """ return response + def post_move_file_with_metadata( + self, + response: dataform.MoveFileResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.MoveFileResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for move_file + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_move_file_with_metadata` + interceptor in new development instead of the `post_move_file` interceptor. + When both interceptors are used, this `post_move_file_with_metadata` interceptor runs after the + `post_move_file` interceptor. The (possibly modified) response returned by + `post_move_file` will be passed to + `post_move_file_with_metadata`. + """ + return response, metadata + def pre_pull_git_commits( self, request: dataform.PullGitCommitsRequest, @@ -1274,12 +1944,38 @@ def post_query_compilation_result_actions( ) -> dataform.QueryCompilationResultActionsResponse: """Post-rpc interceptor for query_compilation_result_actions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_query_compilation_result_actions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_query_compilation_result_actions` interceptor runs + before the `post_query_compilation_result_actions_with_metadata` interceptor. """ return response + def post_query_compilation_result_actions_with_metadata( + self, + response: dataform.QueryCompilationResultActionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.QueryCompilationResultActionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for query_compilation_result_actions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_query_compilation_result_actions_with_metadata` + interceptor in new development instead of the `post_query_compilation_result_actions` interceptor. + When both interceptors are used, this `post_query_compilation_result_actions_with_metadata` interceptor runs after the + `post_query_compilation_result_actions` interceptor. The (possibly modified) response returned by + `post_query_compilation_result_actions` will be passed to + `post_query_compilation_result_actions_with_metadata`. + """ + return response, metadata + def pre_query_directory_contents( self, request: dataform.QueryDirectoryContentsRequest, @@ -1299,12 +1995,37 @@ def post_query_directory_contents( ) -> dataform.QueryDirectoryContentsResponse: """Post-rpc interceptor for query_directory_contents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_query_directory_contents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_query_directory_contents` interceptor runs + before the `post_query_directory_contents_with_metadata` interceptor. """ return response + def post_query_directory_contents_with_metadata( + self, + response: dataform.QueryDirectoryContentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.QueryDirectoryContentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for query_directory_contents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_query_directory_contents_with_metadata` + interceptor in new development instead of the `post_query_directory_contents` interceptor. + When both interceptors are used, this `post_query_directory_contents_with_metadata` interceptor runs after the + `post_query_directory_contents` interceptor. The (possibly modified) response returned by + `post_query_directory_contents` will be passed to + `post_query_directory_contents_with_metadata`. + """ + return response, metadata + def pre_query_repository_directory_contents( self, request: dataform.QueryRepositoryDirectoryContentsRequest, @@ -1325,12 +2046,38 @@ def post_query_repository_directory_contents( ) -> dataform.QueryRepositoryDirectoryContentsResponse: """Post-rpc interceptor for query_repository_directory_contents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_query_repository_directory_contents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_query_repository_directory_contents` interceptor runs + before the `post_query_repository_directory_contents_with_metadata` interceptor. """ return response + def post_query_repository_directory_contents_with_metadata( + self, + response: dataform.QueryRepositoryDirectoryContentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.QueryRepositoryDirectoryContentsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for query_repository_directory_contents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_query_repository_directory_contents_with_metadata` + interceptor in new development instead of the `post_query_repository_directory_contents` interceptor. + When both interceptors are used, this `post_query_repository_directory_contents_with_metadata` interceptor runs after the + `post_query_repository_directory_contents` interceptor. The (possibly modified) response returned by + `post_query_repository_directory_contents` will be passed to + `post_query_repository_directory_contents_with_metadata`. + """ + return response, metadata + def pre_query_workflow_invocation_actions( self, request: dataform.QueryWorkflowInvocationActionsRequest, @@ -1351,12 +2098,38 @@ def post_query_workflow_invocation_actions( ) -> dataform.QueryWorkflowInvocationActionsResponse: """Post-rpc interceptor for query_workflow_invocation_actions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_query_workflow_invocation_actions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_query_workflow_invocation_actions` interceptor runs + before the `post_query_workflow_invocation_actions_with_metadata` interceptor. """ return response + def post_query_workflow_invocation_actions_with_metadata( + self, + response: dataform.QueryWorkflowInvocationActionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.QueryWorkflowInvocationActionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for query_workflow_invocation_actions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_query_workflow_invocation_actions_with_metadata` + interceptor in new development instead of the `post_query_workflow_invocation_actions` interceptor. + When both interceptors are used, this `post_query_workflow_invocation_actions_with_metadata` interceptor runs after the + `post_query_workflow_invocation_actions` interceptor. The (possibly modified) response returned by + `post_query_workflow_invocation_actions` will be passed to + `post_query_workflow_invocation_actions_with_metadata`. + """ + return response, metadata + def pre_read_file( self, request: dataform.ReadFileRequest, @@ -1374,12 +2147,35 @@ def post_read_file( ) -> dataform.ReadFileResponse: """Post-rpc interceptor for read_file - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_read_file_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_read_file` interceptor runs + before the `post_read_file_with_metadata` interceptor. """ return response + def post_read_file_with_metadata( + self, + response: dataform.ReadFileResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.ReadFileResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for read_file + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_read_file_with_metadata` + interceptor in new development instead of the `post_read_file` interceptor. + When both interceptors are used, this `post_read_file_with_metadata` interceptor runs after the + `post_read_file` interceptor. The (possibly modified) response returned by + `post_read_file` will be passed to + `post_read_file_with_metadata`. + """ + return response, metadata + def pre_read_repository_file( self, request: dataform.ReadRepositoryFileRequest, @@ -1399,12 +2195,37 @@ def post_read_repository_file( ) -> dataform.ReadRepositoryFileResponse: """Post-rpc interceptor for read_repository_file - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_read_repository_file_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_read_repository_file` interceptor runs + before the `post_read_repository_file_with_metadata` interceptor. """ return response + def post_read_repository_file_with_metadata( + self, + response: dataform.ReadRepositoryFileResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dataform.ReadRepositoryFileResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for read_repository_file + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_read_repository_file_with_metadata` + interceptor in new development instead of the `post_read_repository_file` interceptor. + When both interceptors are used, this `post_read_repository_file_with_metadata` interceptor runs after the + `post_read_repository_file` interceptor. The (possibly modified) response returned by + `post_read_repository_file` will be passed to + `post_read_repository_file_with_metadata`. + """ + return response, metadata + def pre_remove_directory( self, request: dataform.RemoveDirectoryRequest, @@ -1464,12 +2285,35 @@ def post_update_release_config( ) -> dataform.ReleaseConfig: """Post-rpc interceptor for update_release_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_release_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_update_release_config` interceptor runs + before the `post_update_release_config_with_metadata` interceptor. """ return response + def post_update_release_config_with_metadata( + self, + response: dataform.ReleaseConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.ReleaseConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_release_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_update_release_config_with_metadata` + interceptor in new development instead of the `post_update_release_config` interceptor. + When both interceptors are used, this `post_update_release_config_with_metadata` interceptor runs after the + `post_update_release_config` interceptor. The (possibly modified) response returned by + `post_update_release_config` will be passed to + `post_update_release_config_with_metadata`. + """ + return response, metadata + def pre_update_repository( self, request: dataform.UpdateRepositoryRequest, @@ -1489,12 +2333,35 @@ def post_update_repository( ) -> dataform.Repository: """Post-rpc interceptor for update_repository - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_repository_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_update_repository` interceptor runs + before the `post_update_repository_with_metadata` interceptor. """ return response + def post_update_repository_with_metadata( + self, + response: dataform.Repository, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.Repository, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_repository + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_update_repository_with_metadata` + interceptor in new development instead of the `post_update_repository` interceptor. + When both interceptors are used, this `post_update_repository_with_metadata` interceptor runs after the + `post_update_repository` interceptor. The (possibly modified) response returned by + `post_update_repository` will be passed to + `post_update_repository_with_metadata`. + """ + return response, metadata + def pre_update_workflow_config( self, request: dataform.UpdateWorkflowConfigRequest, @@ -1514,12 +2381,35 @@ def post_update_workflow_config( ) -> dataform.WorkflowConfig: """Post-rpc interceptor for update_workflow_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_workflow_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_update_workflow_config` interceptor runs + before the `post_update_workflow_config_with_metadata` interceptor. """ return response + def post_update_workflow_config_with_metadata( + self, + response: dataform.WorkflowConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.WorkflowConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_workflow_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_update_workflow_config_with_metadata` + interceptor in new development instead of the `post_update_workflow_config` interceptor. + When both interceptors are used, this `post_update_workflow_config_with_metadata` interceptor runs after the + `post_update_workflow_config` interceptor. The (possibly modified) response returned by + `post_update_workflow_config` will be passed to + `post_update_workflow_config_with_metadata`. + """ + return response, metadata + def pre_write_file( self, request: dataform.WriteFileRequest, @@ -1537,12 +2427,35 @@ def post_write_file( ) -> dataform.WriteFileResponse: """Post-rpc interceptor for write_file - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_write_file_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Dataform server but before - it is returned to user code. + it is returned to user code. This `post_write_file` interceptor runs + before the `post_write_file_with_metadata` interceptor. """ return response + def post_write_file_with_metadata( + self, + response: dataform.WriteFileResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dataform.WriteFileResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for write_file + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Dataform server but before it is returned to user code. + + We recommend only using this `post_write_file_with_metadata` + interceptor in new development instead of the `post_write_file` interceptor. + When both interceptors are used, this `post_write_file_with_metadata` interceptor runs after the + `post_write_file` interceptor. The (possibly modified) response returned by + `post_write_file` will be passed to + `post_write_file_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -2222,6 +3135,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_compute_repository_access_token_status(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_compute_repository_access_token_status_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2376,6 +3296,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_compilation_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_compilation_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2526,6 +3450,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_release_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_release_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2678,6 +3606,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_repository(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_repository_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2828,6 +3760,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_workflow_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_workflow_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2979,6 +3915,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_workflow_invocation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_workflow_invocation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3133,6 +4073,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_workspace(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_workspace_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3824,6 +4768,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_file_diff(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_file_diff_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3966,6 +4914,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_file_git_statuses(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_file_git_statuses_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4110,6 +5062,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_git_ahead_behind(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_git_ahead_behind_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4254,6 +5210,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_remote_branches(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_remote_branches_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4398,6 +5358,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_repository_history(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_repository_history_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4544,6 +5508,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_compilation_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_compilation_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4690,6 +5658,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_release_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_release_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4834,6 +5806,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_repository(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_repository_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4978,6 +5954,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_workflow_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_workflow_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5122,6 +6102,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_workflow_invocation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_workflow_invocation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5264,6 +6248,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_workspace(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_workspace_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5412,6 +6400,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_install_npm_packages(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_install_npm_packages_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5556,6 +6548,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_compilation_results(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_compilation_results_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5700,6 +6696,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_release_configs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_release_configs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5846,6 +6846,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_repositories(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_repositories_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5990,6 +6994,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_workflow_configs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_workflow_configs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6134,6 +7142,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_workflow_invocations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_workflow_invocations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6280,6 +7292,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_workspaces(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_workspaces_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6430,6 +7446,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_make_directory(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_make_directory_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6580,6 +7600,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_move_directory(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_move_directory_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6726,6 +7750,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_move_file(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_move_file_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7111,6 +8139,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_query_compilation_result_actions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_query_compilation_result_actions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7255,6 +8290,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_query_directory_contents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_query_directory_contents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7406,6 +8445,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_query_repository_directory_contents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_query_repository_directory_contents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7555,6 +8601,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_query_workflow_invocation_actions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_query_workflow_invocation_actions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7699,6 +8752,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_read_file(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_read_file_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7841,6 +8898,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_read_repository_file(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_read_repository_file_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8341,6 +9402,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_release_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_release_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8493,6 +9558,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_repository(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_repository_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8643,6 +9712,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_workflow_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_workflow_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8789,6 +9862,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_write_file(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_write_file_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataform/samples/generated_samples/snippet_metadata_google.cloud.dataform.v1beta1.json b/packages/google-cloud-dataform/samples/generated_samples/snippet_metadata_google.cloud.dataform.v1beta1.json index d950e4906c7a..1a184ef105a8 100644 --- a/packages/google-cloud-dataform/samples/generated_samples/snippet_metadata_google.cloud.dataform.v1beta1.json +++ b/packages/google-cloud-dataform/samples/generated_samples/snippet_metadata_google.cloud.dataform.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dataform", - "version": "0.5.14" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dataform/tests/unit/gapic/dataform_v1beta1/test_dataform.py b/packages/google-cloud-dataform/tests/unit/gapic/dataform_v1beta1/test_dataform.py index 1cd3264c023e..2d94ee3f3c6b 100644 --- a/packages/google-cloud-dataform/tests/unit/gapic/dataform_v1beta1/test_dataform.py +++ b/packages/google-cloud-dataform/tests/unit/gapic/dataform_v1beta1/test_dataform.py @@ -69,6 +69,13 @@ ) from google.cloud.dataform_v1beta1.types import dataform +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -299,6 +306,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataformClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataformClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -30348,10 +30398,13 @@ def test_list_repositories_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_list_repositories" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_list_repositories_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_list_repositories" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.ListRepositoriesRequest.pb( dataform.ListRepositoriesRequest() ) @@ -30377,6 +30430,7 @@ def test_list_repositories_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ListRepositoriesResponse() + post_with_metadata.return_value = dataform.ListRepositoriesResponse(), metadata client.list_repositories( request, @@ -30388,6 +30442,7 @@ def test_list_repositories_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_repository_rest_bad_request(request_type=dataform.GetRepositoryRequest): @@ -30479,10 +30534,13 @@ def test_get_repository_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_get_repository" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_get_repository_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_get_repository" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.GetRepositoryRequest.pb(dataform.GetRepositoryRequest()) transcode.return_value = { "method": "post", @@ -30504,6 +30562,7 @@ def test_get_repository_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.Repository() + post_with_metadata.return_value = dataform.Repository(), metadata client.get_repository( request, @@ -30515,6 +30574,7 @@ def test_get_repository_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_repository_rest_bad_request( @@ -30698,10 +30758,13 @@ def test_create_repository_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_create_repository" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_create_repository_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_create_repository" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.CreateRepositoryRequest.pb( dataform.CreateRepositoryRequest() ) @@ -30725,6 +30788,7 @@ def test_create_repository_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.Repository() + post_with_metadata.return_value = dataform.Repository(), metadata client.create_repository( request, @@ -30736,6 +30800,7 @@ def test_create_repository_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_repository_rest_bad_request( @@ -30927,10 +30992,13 @@ def test_update_repository_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_update_repository" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_update_repository_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_update_repository" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.UpdateRepositoryRequest.pb( dataform.UpdateRepositoryRequest() ) @@ -30954,6 +31022,7 @@ def test_update_repository_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.Repository() + post_with_metadata.return_value = dataform.Repository(), metadata client.update_repository( request, @@ -30965,6 +31034,7 @@ def test_update_repository_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_repository_rest_bad_request( @@ -31261,10 +31331,13 @@ def test_read_repository_file_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_read_repository_file" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_read_repository_file_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_read_repository_file" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.ReadRepositoryFileRequest.pb( dataform.ReadRepositoryFileRequest() ) @@ -31290,6 +31363,10 @@ def test_read_repository_file_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ReadRepositoryFileResponse() + post_with_metadata.return_value = ( + dataform.ReadRepositoryFileResponse(), + metadata, + ) client.read_repository_file( request, @@ -31301,6 +31378,7 @@ def test_read_repository_file_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_query_repository_directory_contents_rest_bad_request( @@ -31385,10 +31463,14 @@ def test_query_repository_directory_contents_rest_interceptors(null_interceptor) ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_query_repository_directory_contents" ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_query_repository_directory_contents_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_query_repository_directory_contents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.QueryRepositoryDirectoryContentsRequest.pb( dataform.QueryRepositoryDirectoryContentsRequest() ) @@ -31414,6 +31496,10 @@ def test_query_repository_directory_contents_rest_interceptors(null_interceptor) ] pre.return_value = request, metadata post.return_value = dataform.QueryRepositoryDirectoryContentsResponse() + post_with_metadata.return_value = ( + dataform.QueryRepositoryDirectoryContentsResponse(), + metadata, + ) client.query_repository_directory_contents( request, @@ -31425,6 +31511,7 @@ def test_query_repository_directory_contents_rest_interceptors(null_interceptor) pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_repository_history_rest_bad_request( @@ -31507,10 +31594,14 @@ def test_fetch_repository_history_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_fetch_repository_history" ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_fetch_repository_history_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_fetch_repository_history" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.FetchRepositoryHistoryRequest.pb( dataform.FetchRepositoryHistoryRequest() ) @@ -31536,6 +31627,10 @@ def test_fetch_repository_history_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.FetchRepositoryHistoryResponse() + post_with_metadata.return_value = ( + dataform.FetchRepositoryHistoryResponse(), + metadata, + ) client.fetch_repository_history( request, @@ -31547,6 +31642,7 @@ def test_fetch_repository_history_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_compute_repository_access_token_status_rest_bad_request( @@ -31635,10 +31731,14 @@ def test_compute_repository_access_token_status_rest_interceptors(null_intercept transports.DataformRestInterceptor, "post_compute_repository_access_token_status", ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_compute_repository_access_token_status_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_compute_repository_access_token_status" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.ComputeRepositoryAccessTokenStatusRequest.pb( dataform.ComputeRepositoryAccessTokenStatusRequest() ) @@ -31664,6 +31764,10 @@ def test_compute_repository_access_token_status_rest_interceptors(null_intercept ] pre.return_value = request, metadata post.return_value = dataform.ComputeRepositoryAccessTokenStatusResponse() + post_with_metadata.return_value = ( + dataform.ComputeRepositoryAccessTokenStatusResponse(), + metadata, + ) client.compute_repository_access_token_status( request, @@ -31675,6 +31779,7 @@ def test_compute_repository_access_token_status_rest_interceptors(null_intercept pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_remote_branches_rest_bad_request( @@ -31757,10 +31862,13 @@ def test_fetch_remote_branches_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_fetch_remote_branches" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_fetch_remote_branches_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_fetch_remote_branches" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.FetchRemoteBranchesRequest.pb( dataform.FetchRemoteBranchesRequest() ) @@ -31786,6 +31894,10 @@ def test_fetch_remote_branches_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.FetchRemoteBranchesResponse() + post_with_metadata.return_value = ( + dataform.FetchRemoteBranchesResponse(), + metadata, + ) client.fetch_remote_branches( request, @@ -31797,6 +31909,7 @@ def test_fetch_remote_branches_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_workspaces_rest_bad_request(request_type=dataform.ListWorkspacesRequest): @@ -31879,10 +31992,13 @@ def test_list_workspaces_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_list_workspaces" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_list_workspaces_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_list_workspaces" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.ListWorkspacesRequest.pb(dataform.ListWorkspacesRequest()) transcode.return_value = { "method": "post", @@ -31906,6 +32022,7 @@ def test_list_workspaces_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ListWorkspacesResponse() + post_with_metadata.return_value = dataform.ListWorkspacesResponse(), metadata client.list_workspaces( request, @@ -31917,6 +32034,7 @@ def test_list_workspaces_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_workspace_rest_bad_request(request_type=dataform.GetWorkspaceRequest): @@ -32001,10 +32119,13 @@ def test_get_workspace_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_get_workspace" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_get_workspace_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_get_workspace" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.GetWorkspaceRequest.pb(dataform.GetWorkspaceRequest()) transcode.return_value = { "method": "post", @@ -32026,6 +32147,7 @@ def test_get_workspace_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.Workspace() + post_with_metadata.return_value = dataform.Workspace(), metadata client.get_workspace( request, @@ -32037,6 +32159,7 @@ def test_get_workspace_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_workspace_rest_bad_request( @@ -32187,10 +32310,13 @@ def test_create_workspace_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_create_workspace" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_create_workspace_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_create_workspace" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.CreateWorkspaceRequest.pb( dataform.CreateWorkspaceRequest() ) @@ -32214,6 +32340,7 @@ def test_create_workspace_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.Workspace() + post_with_metadata.return_value = dataform.Workspace(), metadata client.create_workspace( request, @@ -32225,6 +32352,7 @@ def test_create_workspace_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_workspace_rest_bad_request( @@ -32419,10 +32547,13 @@ def test_install_npm_packages_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_install_npm_packages" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_install_npm_packages_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_install_npm_packages" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.InstallNpmPackagesRequest.pb( dataform.InstallNpmPackagesRequest() ) @@ -32448,6 +32579,10 @@ def test_install_npm_packages_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.InstallNpmPackagesResponse() + post_with_metadata.return_value = ( + dataform.InstallNpmPackagesResponse(), + metadata, + ) client.install_npm_packages( request, @@ -32459,6 +32594,7 @@ def test_install_npm_packages_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_pull_git_commits_rest_bad_request(request_type=dataform.PullGitCommitsRequest): @@ -32756,10 +32892,13 @@ def test_fetch_file_git_statuses_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_fetch_file_git_statuses" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_fetch_file_git_statuses_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_fetch_file_git_statuses" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.FetchFileGitStatusesRequest.pb( dataform.FetchFileGitStatusesRequest() ) @@ -32785,6 +32924,10 @@ def test_fetch_file_git_statuses_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.FetchFileGitStatusesResponse() + post_with_metadata.return_value = ( + dataform.FetchFileGitStatusesResponse(), + metadata, + ) client.fetch_file_git_statuses( request, @@ -32796,6 +32939,7 @@ def test_fetch_file_git_statuses_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_git_ahead_behind_rest_bad_request( @@ -32884,10 +33028,13 @@ def test_fetch_git_ahead_behind_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_fetch_git_ahead_behind" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_fetch_git_ahead_behind_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_fetch_git_ahead_behind" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.FetchGitAheadBehindRequest.pb( dataform.FetchGitAheadBehindRequest() ) @@ -32913,6 +33060,10 @@ def test_fetch_git_ahead_behind_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.FetchGitAheadBehindResponse() + post_with_metadata.return_value = ( + dataform.FetchGitAheadBehindResponse(), + metadata, + ) client.fetch_git_ahead_behind( request, @@ -32924,6 +33075,7 @@ def test_fetch_git_ahead_behind_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_commit_workspace_changes_rest_bad_request( @@ -33230,10 +33382,13 @@ def test_fetch_file_diff_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_fetch_file_diff" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_fetch_file_diff_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_fetch_file_diff" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.FetchFileDiffRequest.pb(dataform.FetchFileDiffRequest()) transcode.return_value = { "method": "post", @@ -33257,6 +33412,7 @@ def test_fetch_file_diff_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.FetchFileDiffResponse() + post_with_metadata.return_value = dataform.FetchFileDiffResponse(), metadata client.fetch_file_diff( request, @@ -33268,6 +33424,7 @@ def test_fetch_file_diff_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_query_directory_contents_rest_bad_request( @@ -33354,10 +33511,14 @@ def test_query_directory_contents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_query_directory_contents" ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_query_directory_contents_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_query_directory_contents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.QueryDirectoryContentsRequest.pb( dataform.QueryDirectoryContentsRequest() ) @@ -33383,6 +33544,10 @@ def test_query_directory_contents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.QueryDirectoryContentsResponse() + post_with_metadata.return_value = ( + dataform.QueryDirectoryContentsResponse(), + metadata, + ) client.query_directory_contents( request, @@ -33394,6 +33559,7 @@ def test_query_directory_contents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_make_directory_rest_bad_request(request_type=dataform.MakeDirectoryRequest): @@ -33475,10 +33641,13 @@ def test_make_directory_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_make_directory" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_make_directory_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_make_directory" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.MakeDirectoryRequest.pb(dataform.MakeDirectoryRequest()) transcode.return_value = { "method": "post", @@ -33502,6 +33671,7 @@ def test_make_directory_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.MakeDirectoryResponse() + post_with_metadata.return_value = dataform.MakeDirectoryResponse(), metadata client.make_directory( request, @@ -33513,6 +33683,7 @@ def test_make_directory_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_remove_directory_rest_bad_request( @@ -33705,10 +33876,13 @@ def test_move_directory_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_move_directory" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_move_directory_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_move_directory" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.MoveDirectoryRequest.pb(dataform.MoveDirectoryRequest()) transcode.return_value = { "method": "post", @@ -33732,6 +33906,7 @@ def test_move_directory_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.MoveDirectoryResponse() + post_with_metadata.return_value = dataform.MoveDirectoryResponse(), metadata client.move_directory( request, @@ -33743,6 +33918,7 @@ def test_move_directory_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_read_file_rest_bad_request(request_type=dataform.ReadFileRequest): @@ -33827,10 +34003,13 @@ def test_read_file_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_read_file" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_read_file_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_read_file" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.ReadFileRequest.pb(dataform.ReadFileRequest()) transcode.return_value = { "method": "post", @@ -33852,6 +34031,7 @@ def test_read_file_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ReadFileResponse() + post_with_metadata.return_value = dataform.ReadFileResponse(), metadata client.read_file( request, @@ -33863,6 +34043,7 @@ def test_read_file_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_remove_file_rest_bad_request(request_type=dataform.RemoveFileRequest): @@ -34051,10 +34232,13 @@ def test_move_file_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_move_file" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_move_file_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_move_file" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.MoveFileRequest.pb(dataform.MoveFileRequest()) transcode.return_value = { "method": "post", @@ -34076,6 +34260,7 @@ def test_move_file_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.MoveFileResponse() + post_with_metadata.return_value = dataform.MoveFileResponse(), metadata client.move_file( request, @@ -34087,6 +34272,7 @@ def test_move_file_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_write_file_rest_bad_request(request_type=dataform.WriteFileRequest): @@ -34168,10 +34354,13 @@ def test_write_file_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_write_file" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_write_file_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_write_file" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.WriteFileRequest.pb(dataform.WriteFileRequest()) transcode.return_value = { "method": "post", @@ -34193,6 +34382,7 @@ def test_write_file_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.WriteFileResponse() + post_with_metadata.return_value = dataform.WriteFileResponse(), metadata client.write_file( request, @@ -34204,6 +34394,7 @@ def test_write_file_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_release_configs_rest_bad_request( @@ -34288,10 +34479,13 @@ def test_list_release_configs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_list_release_configs" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_list_release_configs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_list_release_configs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.ListReleaseConfigsRequest.pb( dataform.ListReleaseConfigsRequest() ) @@ -34317,6 +34511,10 @@ def test_list_release_configs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ListReleaseConfigsResponse() + post_with_metadata.return_value = ( + dataform.ListReleaseConfigsResponse(), + metadata, + ) client.list_release_configs( request, @@ -34328,6 +34526,7 @@ def test_list_release_configs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_release_config_rest_bad_request( @@ -34422,10 +34621,13 @@ def test_get_release_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_get_release_config" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_get_release_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_get_release_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.GetReleaseConfigRequest.pb( dataform.GetReleaseConfigRequest() ) @@ -34449,6 +34651,7 @@ def test_get_release_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ReleaseConfig() + post_with_metadata.return_value = dataform.ReleaseConfig(), metadata client.get_release_config( request, @@ -34460,6 +34663,7 @@ def test_get_release_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_release_config_rest_bad_request( @@ -34650,10 +34854,13 @@ def test_create_release_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_create_release_config" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_create_release_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_create_release_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.CreateReleaseConfigRequest.pb( dataform.CreateReleaseConfigRequest() ) @@ -34677,6 +34884,7 @@ def test_create_release_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ReleaseConfig() + post_with_metadata.return_value = dataform.ReleaseConfig(), metadata client.create_release_config( request, @@ -34688,6 +34896,7 @@ def test_create_release_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_release_config_rest_bad_request( @@ -34886,10 +35095,13 @@ def test_update_release_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_update_release_config" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_update_release_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_update_release_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.UpdateReleaseConfigRequest.pb( dataform.UpdateReleaseConfigRequest() ) @@ -34913,6 +35125,7 @@ def test_update_release_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ReleaseConfig() + post_with_metadata.return_value = dataform.ReleaseConfig(), metadata client.update_release_config( request, @@ -34924,6 +35137,7 @@ def test_update_release_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_release_config_rest_bad_request( @@ -35119,10 +35333,14 @@ def test_list_compilation_results_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_list_compilation_results" ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_list_compilation_results_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_list_compilation_results" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.ListCompilationResultsRequest.pb( dataform.ListCompilationResultsRequest() ) @@ -35148,6 +35366,10 @@ def test_list_compilation_results_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ListCompilationResultsResponse() + post_with_metadata.return_value = ( + dataform.ListCompilationResultsResponse(), + metadata, + ) client.list_compilation_results( request, @@ -35159,6 +35381,7 @@ def test_list_compilation_results_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_compilation_result_rest_bad_request( @@ -35250,10 +35473,13 @@ def test_get_compilation_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_get_compilation_result" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_get_compilation_result_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_get_compilation_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.GetCompilationResultRequest.pb( dataform.GetCompilationResultRequest() ) @@ -35277,6 +35503,7 @@ def test_get_compilation_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.CompilationResult() + post_with_metadata.return_value = dataform.CompilationResult(), metadata client.get_compilation_result( request, @@ -35288,6 +35515,7 @@ def test_get_compilation_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_compilation_result_rest_bad_request( @@ -35474,10 +35702,14 @@ def test_create_compilation_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_create_compilation_result" ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_create_compilation_result_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_create_compilation_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.CreateCompilationResultRequest.pb( dataform.CreateCompilationResultRequest() ) @@ -35501,6 +35733,7 @@ def test_create_compilation_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.CompilationResult() + post_with_metadata.return_value = dataform.CompilationResult(), metadata client.create_compilation_result( request, @@ -35512,6 +35745,7 @@ def test_create_compilation_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_query_compilation_result_actions_rest_bad_request( @@ -35598,10 +35832,14 @@ def test_query_compilation_result_actions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_query_compilation_result_actions" ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_query_compilation_result_actions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_query_compilation_result_actions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.QueryCompilationResultActionsRequest.pb( dataform.QueryCompilationResultActionsRequest() ) @@ -35627,6 +35865,10 @@ def test_query_compilation_result_actions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.QueryCompilationResultActionsResponse() + post_with_metadata.return_value = ( + dataform.QueryCompilationResultActionsResponse(), + metadata, + ) client.query_compilation_result_actions( request, @@ -35638,6 +35880,7 @@ def test_query_compilation_result_actions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_workflow_configs_rest_bad_request( @@ -35722,10 +35965,13 @@ def test_list_workflow_configs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_list_workflow_configs" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_list_workflow_configs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_list_workflow_configs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.ListWorkflowConfigsRequest.pb( dataform.ListWorkflowConfigsRequest() ) @@ -35751,6 +35997,10 @@ def test_list_workflow_configs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ListWorkflowConfigsResponse() + post_with_metadata.return_value = ( + dataform.ListWorkflowConfigsResponse(), + metadata, + ) client.list_workflow_configs( request, @@ -35762,6 +36012,7 @@ def test_list_workflow_configs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_workflow_config_rest_bad_request( @@ -35854,10 +36105,13 @@ def test_get_workflow_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_get_workflow_config" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_get_workflow_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_get_workflow_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.GetWorkflowConfigRequest.pb( dataform.GetWorkflowConfigRequest() ) @@ -35881,6 +36135,7 @@ def test_get_workflow_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.WorkflowConfig() + post_with_metadata.return_value = dataform.WorkflowConfig(), metadata client.get_workflow_config( request, @@ -35892,6 +36147,7 @@ def test_get_workflow_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_workflow_config_rest_bad_request( @@ -36083,10 +36339,13 @@ def test_create_workflow_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_create_workflow_config" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_create_workflow_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_create_workflow_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.CreateWorkflowConfigRequest.pb( dataform.CreateWorkflowConfigRequest() ) @@ -36110,6 +36369,7 @@ def test_create_workflow_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.WorkflowConfig() + post_with_metadata.return_value = dataform.WorkflowConfig(), metadata client.create_workflow_config( request, @@ -36121,6 +36381,7 @@ def test_create_workflow_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_workflow_config_rest_bad_request( @@ -36320,10 +36581,13 @@ def test_update_workflow_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_update_workflow_config" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_update_workflow_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_update_workflow_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.UpdateWorkflowConfigRequest.pb( dataform.UpdateWorkflowConfigRequest() ) @@ -36347,6 +36611,7 @@ def test_update_workflow_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.WorkflowConfig() + post_with_metadata.return_value = dataform.WorkflowConfig(), metadata client.update_workflow_config( request, @@ -36358,6 +36623,7 @@ def test_update_workflow_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_workflow_config_rest_bad_request( @@ -36553,10 +36819,14 @@ def test_list_workflow_invocations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_list_workflow_invocations" ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_list_workflow_invocations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_list_workflow_invocations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.ListWorkflowInvocationsRequest.pb( dataform.ListWorkflowInvocationsRequest() ) @@ -36582,6 +36852,10 @@ def test_list_workflow_invocations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.ListWorkflowInvocationsResponse() + post_with_metadata.return_value = ( + dataform.ListWorkflowInvocationsResponse(), + metadata, + ) client.list_workflow_invocations( request, @@ -36593,6 +36867,7 @@ def test_list_workflow_invocations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_workflow_invocation_rest_bad_request( @@ -36682,10 +36957,13 @@ def test_get_workflow_invocation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_get_workflow_invocation" ) as post, mock.patch.object( + transports.DataformRestInterceptor, "post_get_workflow_invocation_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_get_workflow_invocation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.GetWorkflowInvocationRequest.pb( dataform.GetWorkflowInvocationRequest() ) @@ -36711,6 +36989,7 @@ def test_get_workflow_invocation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.WorkflowInvocation() + post_with_metadata.return_value = dataform.WorkflowInvocation(), metadata client.get_workflow_invocation( request, @@ -36722,6 +37001,7 @@ def test_get_workflow_invocation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_workflow_invocation_rest_bad_request( @@ -36900,10 +37180,14 @@ def test_create_workflow_invocation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_create_workflow_invocation" ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_create_workflow_invocation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_create_workflow_invocation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.CreateWorkflowInvocationRequest.pb( dataform.CreateWorkflowInvocationRequest() ) @@ -36929,6 +37213,7 @@ def test_create_workflow_invocation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.WorkflowInvocation() + post_with_metadata.return_value = dataform.WorkflowInvocation(), metadata client.create_workflow_invocation( request, @@ -36940,6 +37225,7 @@ def test_create_workflow_invocation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_workflow_invocation_rest_bad_request( @@ -37248,10 +37534,14 @@ def test_query_workflow_invocation_actions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataformRestInterceptor, "post_query_workflow_invocation_actions" ) as post, mock.patch.object( + transports.DataformRestInterceptor, + "post_query_workflow_invocation_actions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataformRestInterceptor, "pre_query_workflow_invocation_actions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dataform.QueryWorkflowInvocationActionsRequest.pb( dataform.QueryWorkflowInvocationActionsRequest() ) @@ -37277,6 +37567,10 @@ def test_query_workflow_invocation_actions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dataform.QueryWorkflowInvocationActionsResponse() + post_with_metadata.return_value = ( + dataform.QueryWorkflowInvocationActionsResponse(), + metadata, + ) client.query_workflow_invocation_actions( request, @@ -37288,6 +37582,7 @@ def test_query_workflow_invocation_actions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-datalabeling/google/cloud/datalabeling/gapic_version.py b/packages/google-cloud-datalabeling/google/cloud/datalabeling/gapic_version.py index 739fdfae141c..558c8aab67c5 100644 --- a/packages/google-cloud-datalabeling/google/cloud/datalabeling/gapic_version.py +++ b/packages/google-cloud-datalabeling/google/cloud/datalabeling/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/gapic_version.py b/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/gapic_version.py index 739fdfae141c..558c8aab67c5 100644 --- a/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/gapic_version.py +++ b/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/services/data_labeling_service/client.py b/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/services/data_labeling_service/client.py index c3f97d28a50d..beb7d005060c 100644 --- a/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/services/data_labeling_service/client.py +++ b/packages/google-cloud-datalabeling/google/cloud/datalabeling_v1beta1/services/data_labeling_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -644,6 +646,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-datalabeling/samples/generated_samples/snippet_metadata_google.cloud.datalabeling.v1beta1.json b/packages/google-cloud-datalabeling/samples/generated_samples/snippet_metadata_google.cloud.datalabeling.v1beta1.json index 45ccefdac839..84eae0c24275 100644 --- a/packages/google-cloud-datalabeling/samples/generated_samples/snippet_metadata_google.cloud.datalabeling.v1beta1.json +++ b/packages/google-cloud-datalabeling/samples/generated_samples/snippet_metadata_google.cloud.datalabeling.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-datalabeling", - "version": "1.12.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-datalabeling/tests/unit/gapic/datalabeling_v1beta1/test_data_labeling_service.py b/packages/google-cloud-datalabeling/tests/unit/gapic/datalabeling_v1beta1/test_data_labeling_service.py index 634bca8e777b..831daf4ea388 100644 --- a/packages/google-cloud-datalabeling/tests/unit/gapic/datalabeling_v1beta1/test_data_labeling_service.py +++ b/packages/google-cloud-datalabeling/tests/unit/gapic/datalabeling_v1beta1/test_data_labeling_service.py @@ -22,6 +22,7 @@ except ImportError: # pragma: NO COVER import mock +import json import math from google.api_core import api_core_version @@ -84,6 +85,13 @@ from google.cloud.datalabeling_v1beta1.types import instruction from google.cloud.datalabeling_v1beta1.types import operations +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -357,6 +365,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataLabelingServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataLabelingServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore/gapic_version.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore/gapic_version.py index 007d6040cbe0..558c8aab67c5 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore/gapic_version.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/gapic_version.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/gapic_version.py index 007d6040cbe0..558c8aab67c5 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/gapic_version.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore/client.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore/client.py index 713831b7056e..7a3a530fbb5e 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore/client.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -605,6 +607,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -3086,16 +3115,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -3141,16 +3174,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -3373,16 +3410,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -3495,16 +3536,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -3555,16 +3600,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_location( self, @@ -3610,16 +3659,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -3665,16 +3718,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore/transports/rest.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore/transports/rest.py index e53dcbf8d772..b93059b4accd 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore/transports/rest.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore/transports/rest.py @@ -242,12 +242,35 @@ def post_alter_metadata_resource_location( ) -> operations_pb2.Operation: """Post-rpc interceptor for alter_metadata_resource_location - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_alter_metadata_resource_location_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_alter_metadata_resource_location` interceptor runs + before the `post_alter_metadata_resource_location_with_metadata` interceptor. """ return response + def post_alter_metadata_resource_location_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for alter_metadata_resource_location + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_alter_metadata_resource_location_with_metadata` + interceptor in new development instead of the `post_alter_metadata_resource_location` interceptor. + When both interceptors are used, this `post_alter_metadata_resource_location_with_metadata` interceptor runs after the + `post_alter_metadata_resource_location` interceptor. The (possibly modified) response returned by + `post_alter_metadata_resource_location` will be passed to + `post_alter_metadata_resource_location_with_metadata`. + """ + return response, metadata + def pre_create_backup( self, request: metastore.CreateBackupRequest, @@ -265,12 +288,35 @@ def post_create_backup( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_backup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_backup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_create_backup` interceptor runs + before the `post_create_backup_with_metadata` interceptor. """ return response + def post_create_backup_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_backup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_create_backup_with_metadata` + interceptor in new development instead of the `post_create_backup` interceptor. + When both interceptors are used, this `post_create_backup_with_metadata` interceptor runs after the + `post_create_backup` interceptor. The (possibly modified) response returned by + `post_create_backup` will be passed to + `post_create_backup_with_metadata`. + """ + return response, metadata + def pre_create_metadata_import( self, request: metastore.CreateMetadataImportRequest, @@ -290,12 +336,35 @@ def post_create_metadata_import( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_metadata_import - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_metadata_import_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_create_metadata_import` interceptor runs + before the `post_create_metadata_import_with_metadata` interceptor. """ return response + def post_create_metadata_import_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_metadata_import + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_create_metadata_import_with_metadata` + interceptor in new development instead of the `post_create_metadata_import` interceptor. + When both interceptors are used, this `post_create_metadata_import_with_metadata` interceptor runs after the + `post_create_metadata_import` interceptor. The (possibly modified) response returned by + `post_create_metadata_import` will be passed to + `post_create_metadata_import_with_metadata`. + """ + return response, metadata + def pre_create_service( self, request: metastore.CreateServiceRequest, @@ -313,12 +382,35 @@ def post_create_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_create_service` interceptor runs + before the `post_create_service_with_metadata` interceptor. """ return response + def post_create_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_create_service_with_metadata` + interceptor in new development instead of the `post_create_service` interceptor. + When both interceptors are used, this `post_create_service_with_metadata` interceptor runs after the + `post_create_service` interceptor. The (possibly modified) response returned by + `post_create_service` will be passed to + `post_create_service_with_metadata`. + """ + return response, metadata + def pre_delete_backup( self, request: metastore.DeleteBackupRequest, @@ -336,12 +428,35 @@ def post_delete_backup( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_backup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_backup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_delete_backup` interceptor runs + before the `post_delete_backup_with_metadata` interceptor. """ return response + def post_delete_backup_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_backup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_delete_backup_with_metadata` + interceptor in new development instead of the `post_delete_backup` interceptor. + When both interceptors are used, this `post_delete_backup_with_metadata` interceptor runs after the + `post_delete_backup` interceptor. The (possibly modified) response returned by + `post_delete_backup` will be passed to + `post_delete_backup_with_metadata`. + """ + return response, metadata + def pre_delete_service( self, request: metastore.DeleteServiceRequest, @@ -359,12 +474,35 @@ def post_delete_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_delete_service` interceptor runs + before the `post_delete_service_with_metadata` interceptor. """ return response + def post_delete_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_delete_service_with_metadata` + interceptor in new development instead of the `post_delete_service` interceptor. + When both interceptors are used, this `post_delete_service_with_metadata` interceptor runs after the + `post_delete_service` interceptor. The (possibly modified) response returned by + `post_delete_service` will be passed to + `post_delete_service_with_metadata`. + """ + return response, metadata + def pre_export_metadata( self, request: metastore.ExportMetadataRequest, @@ -384,12 +522,35 @@ def post_export_metadata( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_metadata - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_metadata_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_export_metadata` interceptor runs + before the `post_export_metadata_with_metadata` interceptor. """ return response + def post_export_metadata_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_metadata + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_export_metadata_with_metadata` + interceptor in new development instead of the `post_export_metadata` interceptor. + When both interceptors are used, this `post_export_metadata_with_metadata` interceptor runs after the + `post_export_metadata` interceptor. The (possibly modified) response returned by + `post_export_metadata` will be passed to + `post_export_metadata_with_metadata`. + """ + return response, metadata + def pre_get_backup( self, request: metastore.GetBackupRequest, @@ -405,12 +566,35 @@ def pre_get_backup( def post_get_backup(self, response: metastore.Backup) -> metastore.Backup: """Post-rpc interceptor for get_backup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_backup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_get_backup` interceptor runs + before the `post_get_backup_with_metadata` interceptor. """ return response + def post_get_backup_with_metadata( + self, + response: metastore.Backup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.Backup, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_backup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_get_backup_with_metadata` + interceptor in new development instead of the `post_get_backup` interceptor. + When both interceptors are used, this `post_get_backup_with_metadata` interceptor runs after the + `post_get_backup` interceptor. The (possibly modified) response returned by + `post_get_backup` will be passed to + `post_get_backup_with_metadata`. + """ + return response, metadata + def pre_get_metadata_import( self, request: metastore.GetMetadataImportRequest, @@ -430,12 +614,35 @@ def post_get_metadata_import( ) -> metastore.MetadataImport: """Post-rpc interceptor for get_metadata_import - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_metadata_import_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_get_metadata_import` interceptor runs + before the `post_get_metadata_import_with_metadata` interceptor. """ return response + def post_get_metadata_import_with_metadata( + self, + response: metastore.MetadataImport, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.MetadataImport, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_metadata_import + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_get_metadata_import_with_metadata` + interceptor in new development instead of the `post_get_metadata_import` interceptor. + When both interceptors are used, this `post_get_metadata_import_with_metadata` interceptor runs after the + `post_get_metadata_import` interceptor. The (possibly modified) response returned by + `post_get_metadata_import` will be passed to + `post_get_metadata_import_with_metadata`. + """ + return response, metadata + def pre_get_service( self, request: metastore.GetServiceRequest, @@ -451,12 +658,35 @@ def pre_get_service( def post_get_service(self, response: metastore.Service) -> metastore.Service: """Post-rpc interceptor for get_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_get_service` interceptor runs + before the `post_get_service_with_metadata` interceptor. """ return response + def post_get_service_with_metadata( + self, + response: metastore.Service, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.Service, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_get_service_with_metadata` + interceptor in new development instead of the `post_get_service` interceptor. + When both interceptors are used, this `post_get_service_with_metadata` interceptor runs after the + `post_get_service` interceptor. The (possibly modified) response returned by + `post_get_service` will be passed to + `post_get_service_with_metadata`. + """ + return response, metadata + def pre_list_backups( self, request: metastore.ListBackupsRequest, @@ -474,12 +704,35 @@ def post_list_backups( ) -> metastore.ListBackupsResponse: """Post-rpc interceptor for list_backups - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_backups_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_list_backups` interceptor runs + before the `post_list_backups_with_metadata` interceptor. """ return response + def post_list_backups_with_metadata( + self, + response: metastore.ListBackupsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.ListBackupsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_backups + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_list_backups_with_metadata` + interceptor in new development instead of the `post_list_backups` interceptor. + When both interceptors are used, this `post_list_backups_with_metadata` interceptor runs after the + `post_list_backups` interceptor. The (possibly modified) response returned by + `post_list_backups` will be passed to + `post_list_backups_with_metadata`. + """ + return response, metadata + def pre_list_metadata_imports( self, request: metastore.ListMetadataImportsRequest, @@ -499,12 +752,37 @@ def post_list_metadata_imports( ) -> metastore.ListMetadataImportsResponse: """Post-rpc interceptor for list_metadata_imports - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_metadata_imports_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_list_metadata_imports` interceptor runs + before the `post_list_metadata_imports_with_metadata` interceptor. """ return response + def post_list_metadata_imports_with_metadata( + self, + response: metastore.ListMetadataImportsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore.ListMetadataImportsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_metadata_imports + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_list_metadata_imports_with_metadata` + interceptor in new development instead of the `post_list_metadata_imports` interceptor. + When both interceptors are used, this `post_list_metadata_imports_with_metadata` interceptor runs after the + `post_list_metadata_imports` interceptor. The (possibly modified) response returned by + `post_list_metadata_imports` will be passed to + `post_list_metadata_imports_with_metadata`. + """ + return response, metadata + def pre_list_services( self, request: metastore.ListServicesRequest, @@ -522,12 +800,35 @@ def post_list_services( ) -> metastore.ListServicesResponse: """Post-rpc interceptor for list_services - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_services_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_list_services` interceptor runs + before the `post_list_services_with_metadata` interceptor. """ return response + def post_list_services_with_metadata( + self, + response: metastore.ListServicesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.ListServicesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_services + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_list_services_with_metadata` + interceptor in new development instead of the `post_list_services` interceptor. + When both interceptors are used, this `post_list_services_with_metadata` interceptor runs after the + `post_list_services` interceptor. The (possibly modified) response returned by + `post_list_services` will be passed to + `post_list_services_with_metadata`. + """ + return response, metadata + def pre_move_table_to_database( self, request: metastore.MoveTableToDatabaseRequest, @@ -547,12 +848,35 @@ def post_move_table_to_database( ) -> operations_pb2.Operation: """Post-rpc interceptor for move_table_to_database - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_move_table_to_database_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_move_table_to_database` interceptor runs + before the `post_move_table_to_database_with_metadata` interceptor. """ return response + def post_move_table_to_database_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for move_table_to_database + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_move_table_to_database_with_metadata` + interceptor in new development instead of the `post_move_table_to_database` interceptor. + When both interceptors are used, this `post_move_table_to_database_with_metadata` interceptor runs after the + `post_move_table_to_database` interceptor. The (possibly modified) response returned by + `post_move_table_to_database` will be passed to + `post_move_table_to_database_with_metadata`. + """ + return response, metadata + def pre_query_metadata( self, request: metastore.QueryMetadataRequest, @@ -570,12 +894,35 @@ def post_query_metadata( ) -> operations_pb2.Operation: """Post-rpc interceptor for query_metadata - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_query_metadata_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_query_metadata` interceptor runs + before the `post_query_metadata_with_metadata` interceptor. """ return response + def post_query_metadata_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for query_metadata + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_query_metadata_with_metadata` + interceptor in new development instead of the `post_query_metadata` interceptor. + When both interceptors are used, this `post_query_metadata_with_metadata` interceptor runs after the + `post_query_metadata` interceptor. The (possibly modified) response returned by + `post_query_metadata` will be passed to + `post_query_metadata_with_metadata`. + """ + return response, metadata + def pre_restore_service( self, request: metastore.RestoreServiceRequest, @@ -595,12 +942,35 @@ def post_restore_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for restore_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_restore_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_restore_service` interceptor runs + before the `post_restore_service_with_metadata` interceptor. """ return response + def post_restore_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for restore_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_restore_service_with_metadata` + interceptor in new development instead of the `post_restore_service` interceptor. + When both interceptors are used, this `post_restore_service_with_metadata` interceptor runs after the + `post_restore_service` interceptor. The (possibly modified) response returned by + `post_restore_service` will be passed to + `post_restore_service_with_metadata`. + """ + return response, metadata + def pre_update_metadata_import( self, request: metastore.UpdateMetadataImportRequest, @@ -620,12 +990,35 @@ def post_update_metadata_import( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_metadata_import - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_metadata_import_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_update_metadata_import` interceptor runs + before the `post_update_metadata_import_with_metadata` interceptor. """ return response + def post_update_metadata_import_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_metadata_import + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_update_metadata_import_with_metadata` + interceptor in new development instead of the `post_update_metadata_import` interceptor. + When both interceptors are used, this `post_update_metadata_import_with_metadata` interceptor runs after the + `post_update_metadata_import` interceptor. The (possibly modified) response returned by + `post_update_metadata_import` will be passed to + `post_update_metadata_import_with_metadata`. + """ + return response, metadata + def pre_update_service( self, request: metastore.UpdateServiceRequest, @@ -643,12 +1036,35 @@ def post_update_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_update_service` interceptor runs + before the `post_update_service_with_metadata` interceptor. """ return response + def post_update_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_update_service_with_metadata` + interceptor in new development instead of the `post_update_service` interceptor. + When both interceptors are used, this `post_update_service_with_metadata` interceptor runs after the + `post_update_service` interceptor. The (possibly modified) response returned by + `post_update_service` will be passed to + `post_update_service_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -1158,6 +1574,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_alter_metadata_resource_location(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_alter_metadata_resource_location_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1306,6 +1729,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_backup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_backup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1459,6 +1886,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_metadata_import(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_metadata_import_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1608,6 +2039,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1750,6 +2185,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_backup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_backup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1893,6 +2332,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2042,6 +2485,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_metadata(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_metadata_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2183,6 +2630,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_backup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_backup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2329,6 +2780,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_metadata_import(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_metadata_import_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2472,6 +2927,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2615,6 +3074,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_backups(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_backups_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2763,6 +3226,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_metadata_imports(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_metadata_imports_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2908,6 +3375,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_services(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_services_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3061,6 +3532,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_move_table_to_database(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_move_table_to_database_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3210,6 +3685,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_query_metadata(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_query_metadata_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3358,6 +3837,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_restore_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_restore_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3511,6 +3994,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_metadata_import(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_metadata_import_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3660,6 +4147,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore_federation/client.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore_federation/client.py index 43f8b93d47f8..6cc6470fe8b5 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore_federation/client.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore_federation/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -517,6 +519,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1434,16 +1463,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1489,16 +1522,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -1721,16 +1758,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1843,16 +1884,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -1903,16 +1948,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_location( self, @@ -1958,16 +2007,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2013,16 +2066,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore_federation/transports/rest.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore_federation/transports/rest.py index ed961bcdfe5a..2b80a3dd2ae2 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore_federation/transports/rest.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1/services/dataproc_metastore_federation/transports/rest.py @@ -138,12 +138,35 @@ def post_create_federation( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_create_federation` interceptor runs + before the `post_create_federation_with_metadata` interceptor. """ return response + def post_create_federation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_create_federation_with_metadata` + interceptor in new development instead of the `post_create_federation` interceptor. + When both interceptors are used, this `post_create_federation_with_metadata` interceptor runs after the + `post_create_federation` interceptor. The (possibly modified) response returned by + `post_create_federation` will be passed to + `post_create_federation_with_metadata`. + """ + return response, metadata + def pre_delete_federation( self, request: metastore_federation.DeleteFederationRequest, @@ -164,12 +187,35 @@ def post_delete_federation( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_delete_federation` interceptor runs + before the `post_delete_federation_with_metadata` interceptor. """ return response + def post_delete_federation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_delete_federation_with_metadata` + interceptor in new development instead of the `post_delete_federation` interceptor. + When both interceptors are used, this `post_delete_federation_with_metadata` interceptor runs after the + `post_delete_federation` interceptor. The (possibly modified) response returned by + `post_delete_federation` will be passed to + `post_delete_federation_with_metadata`. + """ + return response, metadata + def pre_get_federation( self, request: metastore_federation.GetFederationRequest, @@ -190,12 +236,37 @@ def post_get_federation( ) -> metastore_federation.Federation: """Post-rpc interceptor for get_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_get_federation` interceptor runs + before the `post_get_federation_with_metadata` interceptor. """ return response + def post_get_federation_with_metadata( + self, + response: metastore_federation.Federation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore_federation.Federation, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_get_federation_with_metadata` + interceptor in new development instead of the `post_get_federation` interceptor. + When both interceptors are used, this `post_get_federation_with_metadata` interceptor runs after the + `post_get_federation` interceptor. The (possibly modified) response returned by + `post_get_federation` will be passed to + `post_get_federation_with_metadata`. + """ + return response, metadata + def pre_list_federations( self, request: metastore_federation.ListFederationsRequest, @@ -216,12 +287,38 @@ def post_list_federations( ) -> metastore_federation.ListFederationsResponse: """Post-rpc interceptor for list_federations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_federations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_list_federations` interceptor runs + before the `post_list_federations_with_metadata` interceptor. """ return response + def post_list_federations_with_metadata( + self, + response: metastore_federation.ListFederationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore_federation.ListFederationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_federations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_list_federations_with_metadata` + interceptor in new development instead of the `post_list_federations` interceptor. + When both interceptors are used, this `post_list_federations_with_metadata` interceptor runs after the + `post_list_federations` interceptor. The (possibly modified) response returned by + `post_list_federations` will be passed to + `post_list_federations_with_metadata`. + """ + return response, metadata + def pre_update_federation( self, request: metastore_federation.UpdateFederationRequest, @@ -242,12 +339,35 @@ def post_update_federation( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_update_federation` interceptor runs + before the `post_update_federation_with_metadata` interceptor. """ return response + def post_update_federation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_update_federation_with_metadata` + interceptor in new development instead of the `post_update_federation` interceptor. + When both interceptors are used, this `post_update_federation_with_metadata` interceptor runs after the + `post_update_federation` interceptor. The (possibly modified) response returned by + `post_update_federation` will be passed to + `post_update_federation_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -750,6 +870,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -894,6 +1018,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1039,6 +1167,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1184,6 +1316,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_federations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_federations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1336,6 +1472,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/gapic_version.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/gapic_version.py index 007d6040cbe0..558c8aab67c5 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/gapic_version.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore/client.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore/client.py index 5dbf81c8c3d6..5aa8975736f1 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore/client.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -627,6 +629,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -3192,16 +3221,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -3247,16 +3280,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -3479,16 +3516,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -3601,16 +3642,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -3661,16 +3706,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_location( self, @@ -3716,16 +3765,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -3771,16 +3824,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore/transports/rest.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore/transports/rest.py index 8d87107ccdbf..2551e1e924d1 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore/transports/rest.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore/transports/rest.py @@ -250,12 +250,35 @@ def post_alter_metadata_resource_location( ) -> operations_pb2.Operation: """Post-rpc interceptor for alter_metadata_resource_location - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_alter_metadata_resource_location_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_alter_metadata_resource_location` interceptor runs + before the `post_alter_metadata_resource_location_with_metadata` interceptor. """ return response + def post_alter_metadata_resource_location_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for alter_metadata_resource_location + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_alter_metadata_resource_location_with_metadata` + interceptor in new development instead of the `post_alter_metadata_resource_location` interceptor. + When both interceptors are used, this `post_alter_metadata_resource_location_with_metadata` interceptor runs after the + `post_alter_metadata_resource_location` interceptor. The (possibly modified) response returned by + `post_alter_metadata_resource_location` will be passed to + `post_alter_metadata_resource_location_with_metadata`. + """ + return response, metadata + def pre_create_backup( self, request: metastore.CreateBackupRequest, @@ -273,12 +296,35 @@ def post_create_backup( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_backup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_backup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_create_backup` interceptor runs + before the `post_create_backup_with_metadata` interceptor. """ return response + def post_create_backup_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_backup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_create_backup_with_metadata` + interceptor in new development instead of the `post_create_backup` interceptor. + When both interceptors are used, this `post_create_backup_with_metadata` interceptor runs after the + `post_create_backup` interceptor. The (possibly modified) response returned by + `post_create_backup` will be passed to + `post_create_backup_with_metadata`. + """ + return response, metadata + def pre_create_metadata_import( self, request: metastore.CreateMetadataImportRequest, @@ -298,12 +344,35 @@ def post_create_metadata_import( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_metadata_import - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_metadata_import_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_create_metadata_import` interceptor runs + before the `post_create_metadata_import_with_metadata` interceptor. """ return response + def post_create_metadata_import_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_metadata_import + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_create_metadata_import_with_metadata` + interceptor in new development instead of the `post_create_metadata_import` interceptor. + When both interceptors are used, this `post_create_metadata_import_with_metadata` interceptor runs after the + `post_create_metadata_import` interceptor. The (possibly modified) response returned by + `post_create_metadata_import` will be passed to + `post_create_metadata_import_with_metadata`. + """ + return response, metadata + def pre_create_service( self, request: metastore.CreateServiceRequest, @@ -321,12 +390,35 @@ def post_create_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_create_service` interceptor runs + before the `post_create_service_with_metadata` interceptor. """ return response + def post_create_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_create_service_with_metadata` + interceptor in new development instead of the `post_create_service` interceptor. + When both interceptors are used, this `post_create_service_with_metadata` interceptor runs after the + `post_create_service` interceptor. The (possibly modified) response returned by + `post_create_service` will be passed to + `post_create_service_with_metadata`. + """ + return response, metadata + def pre_delete_backup( self, request: metastore.DeleteBackupRequest, @@ -344,12 +436,35 @@ def post_delete_backup( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_backup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_backup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_delete_backup` interceptor runs + before the `post_delete_backup_with_metadata` interceptor. """ return response + def post_delete_backup_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_backup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_delete_backup_with_metadata` + interceptor in new development instead of the `post_delete_backup` interceptor. + When both interceptors are used, this `post_delete_backup_with_metadata` interceptor runs after the + `post_delete_backup` interceptor. The (possibly modified) response returned by + `post_delete_backup` will be passed to + `post_delete_backup_with_metadata`. + """ + return response, metadata + def pre_delete_service( self, request: metastore.DeleteServiceRequest, @@ -367,12 +482,35 @@ def post_delete_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_delete_service` interceptor runs + before the `post_delete_service_with_metadata` interceptor. """ return response + def post_delete_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_delete_service_with_metadata` + interceptor in new development instead of the `post_delete_service` interceptor. + When both interceptors are used, this `post_delete_service_with_metadata` interceptor runs after the + `post_delete_service` interceptor. The (possibly modified) response returned by + `post_delete_service` will be passed to + `post_delete_service_with_metadata`. + """ + return response, metadata + def pre_export_metadata( self, request: metastore.ExportMetadataRequest, @@ -392,12 +530,35 @@ def post_export_metadata( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_metadata - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_metadata_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_export_metadata` interceptor runs + before the `post_export_metadata_with_metadata` interceptor. """ return response + def post_export_metadata_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_metadata + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_export_metadata_with_metadata` + interceptor in new development instead of the `post_export_metadata` interceptor. + When both interceptors are used, this `post_export_metadata_with_metadata` interceptor runs after the + `post_export_metadata` interceptor. The (possibly modified) response returned by + `post_export_metadata` will be passed to + `post_export_metadata_with_metadata`. + """ + return response, metadata + def pre_get_backup( self, request: metastore.GetBackupRequest, @@ -413,12 +574,35 @@ def pre_get_backup( def post_get_backup(self, response: metastore.Backup) -> metastore.Backup: """Post-rpc interceptor for get_backup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_backup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_get_backup` interceptor runs + before the `post_get_backup_with_metadata` interceptor. """ return response + def post_get_backup_with_metadata( + self, + response: metastore.Backup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.Backup, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_backup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_get_backup_with_metadata` + interceptor in new development instead of the `post_get_backup` interceptor. + When both interceptors are used, this `post_get_backup_with_metadata` interceptor runs after the + `post_get_backup` interceptor. The (possibly modified) response returned by + `post_get_backup` will be passed to + `post_get_backup_with_metadata`. + """ + return response, metadata + def pre_get_metadata_import( self, request: metastore.GetMetadataImportRequest, @@ -438,12 +622,35 @@ def post_get_metadata_import( ) -> metastore.MetadataImport: """Post-rpc interceptor for get_metadata_import - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_metadata_import_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_get_metadata_import` interceptor runs + before the `post_get_metadata_import_with_metadata` interceptor. """ return response + def post_get_metadata_import_with_metadata( + self, + response: metastore.MetadataImport, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.MetadataImport, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_metadata_import + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_get_metadata_import_with_metadata` + interceptor in new development instead of the `post_get_metadata_import` interceptor. + When both interceptors are used, this `post_get_metadata_import_with_metadata` interceptor runs after the + `post_get_metadata_import` interceptor. The (possibly modified) response returned by + `post_get_metadata_import` will be passed to + `post_get_metadata_import_with_metadata`. + """ + return response, metadata + def pre_get_service( self, request: metastore.GetServiceRequest, @@ -459,12 +666,35 @@ def pre_get_service( def post_get_service(self, response: metastore.Service) -> metastore.Service: """Post-rpc interceptor for get_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_get_service` interceptor runs + before the `post_get_service_with_metadata` interceptor. """ return response + def post_get_service_with_metadata( + self, + response: metastore.Service, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.Service, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_get_service_with_metadata` + interceptor in new development instead of the `post_get_service` interceptor. + When both interceptors are used, this `post_get_service_with_metadata` interceptor runs after the + `post_get_service` interceptor. The (possibly modified) response returned by + `post_get_service` will be passed to + `post_get_service_with_metadata`. + """ + return response, metadata + def pre_list_backups( self, request: metastore.ListBackupsRequest, @@ -482,12 +712,35 @@ def post_list_backups( ) -> metastore.ListBackupsResponse: """Post-rpc interceptor for list_backups - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_backups_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_list_backups` interceptor runs + before the `post_list_backups_with_metadata` interceptor. """ return response + def post_list_backups_with_metadata( + self, + response: metastore.ListBackupsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.ListBackupsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_backups + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_list_backups_with_metadata` + interceptor in new development instead of the `post_list_backups` interceptor. + When both interceptors are used, this `post_list_backups_with_metadata` interceptor runs after the + `post_list_backups` interceptor. The (possibly modified) response returned by + `post_list_backups` will be passed to + `post_list_backups_with_metadata`. + """ + return response, metadata + def pre_list_metadata_imports( self, request: metastore.ListMetadataImportsRequest, @@ -507,12 +760,37 @@ def post_list_metadata_imports( ) -> metastore.ListMetadataImportsResponse: """Post-rpc interceptor for list_metadata_imports - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_metadata_imports_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_list_metadata_imports` interceptor runs + before the `post_list_metadata_imports_with_metadata` interceptor. """ return response + def post_list_metadata_imports_with_metadata( + self, + response: metastore.ListMetadataImportsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore.ListMetadataImportsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_metadata_imports + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_list_metadata_imports_with_metadata` + interceptor in new development instead of the `post_list_metadata_imports` interceptor. + When both interceptors are used, this `post_list_metadata_imports_with_metadata` interceptor runs after the + `post_list_metadata_imports` interceptor. The (possibly modified) response returned by + `post_list_metadata_imports` will be passed to + `post_list_metadata_imports_with_metadata`. + """ + return response, metadata + def pre_list_services( self, request: metastore.ListServicesRequest, @@ -530,12 +808,35 @@ def post_list_services( ) -> metastore.ListServicesResponse: """Post-rpc interceptor for list_services - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_services_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_list_services` interceptor runs + before the `post_list_services_with_metadata` interceptor. """ return response + def post_list_services_with_metadata( + self, + response: metastore.ListServicesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.ListServicesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_services + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_list_services_with_metadata` + interceptor in new development instead of the `post_list_services` interceptor. + When both interceptors are used, this `post_list_services_with_metadata` interceptor runs after the + `post_list_services` interceptor. The (possibly modified) response returned by + `post_list_services` will be passed to + `post_list_services_with_metadata`. + """ + return response, metadata + def pre_move_table_to_database( self, request: metastore.MoveTableToDatabaseRequest, @@ -555,12 +856,35 @@ def post_move_table_to_database( ) -> operations_pb2.Operation: """Post-rpc interceptor for move_table_to_database - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_move_table_to_database_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_move_table_to_database` interceptor runs + before the `post_move_table_to_database_with_metadata` interceptor. """ return response + def post_move_table_to_database_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for move_table_to_database + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_move_table_to_database_with_metadata` + interceptor in new development instead of the `post_move_table_to_database` interceptor. + When both interceptors are used, this `post_move_table_to_database_with_metadata` interceptor runs after the + `post_move_table_to_database` interceptor. The (possibly modified) response returned by + `post_move_table_to_database` will be passed to + `post_move_table_to_database_with_metadata`. + """ + return response, metadata + def pre_query_metadata( self, request: metastore.QueryMetadataRequest, @@ -578,12 +902,35 @@ def post_query_metadata( ) -> operations_pb2.Operation: """Post-rpc interceptor for query_metadata - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_query_metadata_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_query_metadata` interceptor runs + before the `post_query_metadata_with_metadata` interceptor. """ return response + def post_query_metadata_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for query_metadata + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_query_metadata_with_metadata` + interceptor in new development instead of the `post_query_metadata` interceptor. + When both interceptors are used, this `post_query_metadata_with_metadata` interceptor runs after the + `post_query_metadata` interceptor. The (possibly modified) response returned by + `post_query_metadata` will be passed to + `post_query_metadata_with_metadata`. + """ + return response, metadata + def pre_remove_iam_policy( self, request: metastore.RemoveIamPolicyRequest, @@ -603,12 +950,37 @@ def post_remove_iam_policy( ) -> metastore.RemoveIamPolicyResponse: """Post-rpc interceptor for remove_iam_policy - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_remove_iam_policy_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_remove_iam_policy` interceptor runs + before the `post_remove_iam_policy_with_metadata` interceptor. """ return response + def post_remove_iam_policy_with_metadata( + self, + response: metastore.RemoveIamPolicyResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore.RemoveIamPolicyResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for remove_iam_policy + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_remove_iam_policy_with_metadata` + interceptor in new development instead of the `post_remove_iam_policy` interceptor. + When both interceptors are used, this `post_remove_iam_policy_with_metadata` interceptor runs after the + `post_remove_iam_policy` interceptor. The (possibly modified) response returned by + `post_remove_iam_policy` will be passed to + `post_remove_iam_policy_with_metadata`. + """ + return response, metadata + def pre_restore_service( self, request: metastore.RestoreServiceRequest, @@ -628,12 +1000,35 @@ def post_restore_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for restore_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_restore_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_restore_service` interceptor runs + before the `post_restore_service_with_metadata` interceptor. """ return response + def post_restore_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for restore_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_restore_service_with_metadata` + interceptor in new development instead of the `post_restore_service` interceptor. + When both interceptors are used, this `post_restore_service_with_metadata` interceptor runs after the + `post_restore_service` interceptor. The (possibly modified) response returned by + `post_restore_service` will be passed to + `post_restore_service_with_metadata`. + """ + return response, metadata + def pre_update_metadata_import( self, request: metastore.UpdateMetadataImportRequest, @@ -653,12 +1048,35 @@ def post_update_metadata_import( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_metadata_import - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_metadata_import_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_update_metadata_import` interceptor runs + before the `post_update_metadata_import_with_metadata` interceptor. """ return response + def post_update_metadata_import_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_metadata_import + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_update_metadata_import_with_metadata` + interceptor in new development instead of the `post_update_metadata_import` interceptor. + When both interceptors are used, this `post_update_metadata_import_with_metadata` interceptor runs after the + `post_update_metadata_import` interceptor. The (possibly modified) response returned by + `post_update_metadata_import` will be passed to + `post_update_metadata_import_with_metadata`. + """ + return response, metadata + def pre_update_service( self, request: metastore.UpdateServiceRequest, @@ -676,12 +1094,35 @@ def post_update_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_update_service` interceptor runs + before the `post_update_service_with_metadata` interceptor. """ return response + def post_update_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_update_service_with_metadata` + interceptor in new development instead of the `post_update_service` interceptor. + When both interceptors are used, this `post_update_service_with_metadata` interceptor runs after the + `post_update_service` interceptor. The (possibly modified) response returned by + `post_update_service` will be passed to + `post_update_service_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -1191,6 +1632,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_alter_metadata_resource_location(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_alter_metadata_resource_location_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1339,6 +1787,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_backup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_backup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1492,6 +1944,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_metadata_import(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_metadata_import_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1641,6 +2097,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1783,6 +2243,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_backup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_backup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1926,6 +2390,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2075,6 +2543,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_metadata(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_metadata_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2216,6 +2688,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_backup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_backup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2362,6 +2838,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_metadata_import(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_metadata_import_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2505,6 +2985,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2648,6 +3132,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_backups(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_backups_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2796,6 +3284,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_metadata_imports(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_metadata_imports_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2941,6 +3433,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_services(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_services_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3094,6 +3590,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_move_table_to_database(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_move_table_to_database_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3243,6 +3743,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_query_metadata(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_query_metadata_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3395,6 +3899,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_remove_iam_policy(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_remove_iam_policy_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3545,6 +4053,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_restore_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_restore_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3698,6 +4210,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_metadata_import(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_metadata_import_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3847,6 +4363,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore_federation/client.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore_federation/client.py index 3e36593e5b05..4ecb6e74b256 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore_federation/client.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore_federation/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -517,6 +519,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1434,16 +1463,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1489,16 +1522,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -1721,16 +1758,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1843,16 +1884,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -1903,16 +1948,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_location( self, @@ -1958,16 +2007,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2013,16 +2066,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore_federation/transports/rest.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore_federation/transports/rest.py index 4be6fa9975c3..b634251081db 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore_federation/transports/rest.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1alpha/services/dataproc_metastore_federation/transports/rest.py @@ -138,12 +138,35 @@ def post_create_federation( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_create_federation` interceptor runs + before the `post_create_federation_with_metadata` interceptor. """ return response + def post_create_federation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_create_federation_with_metadata` + interceptor in new development instead of the `post_create_federation` interceptor. + When both interceptors are used, this `post_create_federation_with_metadata` interceptor runs after the + `post_create_federation` interceptor. The (possibly modified) response returned by + `post_create_federation` will be passed to + `post_create_federation_with_metadata`. + """ + return response, metadata + def pre_delete_federation( self, request: metastore_federation.DeleteFederationRequest, @@ -164,12 +187,35 @@ def post_delete_federation( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_delete_federation` interceptor runs + before the `post_delete_federation_with_metadata` interceptor. """ return response + def post_delete_federation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_delete_federation_with_metadata` + interceptor in new development instead of the `post_delete_federation` interceptor. + When both interceptors are used, this `post_delete_federation_with_metadata` interceptor runs after the + `post_delete_federation` interceptor. The (possibly modified) response returned by + `post_delete_federation` will be passed to + `post_delete_federation_with_metadata`. + """ + return response, metadata + def pre_get_federation( self, request: metastore_federation.GetFederationRequest, @@ -190,12 +236,37 @@ def post_get_federation( ) -> metastore_federation.Federation: """Post-rpc interceptor for get_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_get_federation` interceptor runs + before the `post_get_federation_with_metadata` interceptor. """ return response + def post_get_federation_with_metadata( + self, + response: metastore_federation.Federation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore_federation.Federation, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_get_federation_with_metadata` + interceptor in new development instead of the `post_get_federation` interceptor. + When both interceptors are used, this `post_get_federation_with_metadata` interceptor runs after the + `post_get_federation` interceptor. The (possibly modified) response returned by + `post_get_federation` will be passed to + `post_get_federation_with_metadata`. + """ + return response, metadata + def pre_list_federations( self, request: metastore_federation.ListFederationsRequest, @@ -216,12 +287,38 @@ def post_list_federations( ) -> metastore_federation.ListFederationsResponse: """Post-rpc interceptor for list_federations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_federations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_list_federations` interceptor runs + before the `post_list_federations_with_metadata` interceptor. """ return response + def post_list_federations_with_metadata( + self, + response: metastore_federation.ListFederationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore_federation.ListFederationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_federations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_list_federations_with_metadata` + interceptor in new development instead of the `post_list_federations` interceptor. + When both interceptors are used, this `post_list_federations_with_metadata` interceptor runs after the + `post_list_federations` interceptor. The (possibly modified) response returned by + `post_list_federations` will be passed to + `post_list_federations_with_metadata`. + """ + return response, metadata + def pre_update_federation( self, request: metastore_federation.UpdateFederationRequest, @@ -242,12 +339,35 @@ def post_update_federation( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_update_federation` interceptor runs + before the `post_update_federation_with_metadata` interceptor. """ return response + def post_update_federation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_update_federation_with_metadata` + interceptor in new development instead of the `post_update_federation` interceptor. + When both interceptors are used, this `post_update_federation_with_metadata` interceptor runs after the + `post_update_federation` interceptor. The (possibly modified) response returned by + `post_update_federation` will be passed to + `post_update_federation_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -750,6 +870,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -894,6 +1018,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1039,6 +1167,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1184,6 +1316,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_federations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_federations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1336,6 +1472,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/gapic_version.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/gapic_version.py index 007d6040cbe0..558c8aab67c5 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/gapic_version.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.17.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore/client.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore/client.py index 10aa27d56cab..b5be6a297c87 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore/client.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -627,6 +629,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -3192,16 +3221,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -3247,16 +3280,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -3479,16 +3516,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -3601,16 +3642,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -3661,16 +3706,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_location( self, @@ -3716,16 +3765,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -3771,16 +3824,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore/transports/rest.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore/transports/rest.py index 856a669588ce..942dbed1d7f2 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore/transports/rest.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore/transports/rest.py @@ -250,12 +250,35 @@ def post_alter_metadata_resource_location( ) -> operations_pb2.Operation: """Post-rpc interceptor for alter_metadata_resource_location - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_alter_metadata_resource_location_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_alter_metadata_resource_location` interceptor runs + before the `post_alter_metadata_resource_location_with_metadata` interceptor. """ return response + def post_alter_metadata_resource_location_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for alter_metadata_resource_location + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_alter_metadata_resource_location_with_metadata` + interceptor in new development instead of the `post_alter_metadata_resource_location` interceptor. + When both interceptors are used, this `post_alter_metadata_resource_location_with_metadata` interceptor runs after the + `post_alter_metadata_resource_location` interceptor. The (possibly modified) response returned by + `post_alter_metadata_resource_location` will be passed to + `post_alter_metadata_resource_location_with_metadata`. + """ + return response, metadata + def pre_create_backup( self, request: metastore.CreateBackupRequest, @@ -273,12 +296,35 @@ def post_create_backup( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_backup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_backup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_create_backup` interceptor runs + before the `post_create_backup_with_metadata` interceptor. """ return response + def post_create_backup_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_backup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_create_backup_with_metadata` + interceptor in new development instead of the `post_create_backup` interceptor. + When both interceptors are used, this `post_create_backup_with_metadata` interceptor runs after the + `post_create_backup` interceptor. The (possibly modified) response returned by + `post_create_backup` will be passed to + `post_create_backup_with_metadata`. + """ + return response, metadata + def pre_create_metadata_import( self, request: metastore.CreateMetadataImportRequest, @@ -298,12 +344,35 @@ def post_create_metadata_import( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_metadata_import - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_metadata_import_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_create_metadata_import` interceptor runs + before the `post_create_metadata_import_with_metadata` interceptor. """ return response + def post_create_metadata_import_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_metadata_import + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_create_metadata_import_with_metadata` + interceptor in new development instead of the `post_create_metadata_import` interceptor. + When both interceptors are used, this `post_create_metadata_import_with_metadata` interceptor runs after the + `post_create_metadata_import` interceptor. The (possibly modified) response returned by + `post_create_metadata_import` will be passed to + `post_create_metadata_import_with_metadata`. + """ + return response, metadata + def pre_create_service( self, request: metastore.CreateServiceRequest, @@ -321,12 +390,35 @@ def post_create_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_create_service` interceptor runs + before the `post_create_service_with_metadata` interceptor. """ return response + def post_create_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_create_service_with_metadata` + interceptor in new development instead of the `post_create_service` interceptor. + When both interceptors are used, this `post_create_service_with_metadata` interceptor runs after the + `post_create_service` interceptor. The (possibly modified) response returned by + `post_create_service` will be passed to + `post_create_service_with_metadata`. + """ + return response, metadata + def pre_delete_backup( self, request: metastore.DeleteBackupRequest, @@ -344,12 +436,35 @@ def post_delete_backup( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_backup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_backup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_delete_backup` interceptor runs + before the `post_delete_backup_with_metadata` interceptor. """ return response + def post_delete_backup_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_backup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_delete_backup_with_metadata` + interceptor in new development instead of the `post_delete_backup` interceptor. + When both interceptors are used, this `post_delete_backup_with_metadata` interceptor runs after the + `post_delete_backup` interceptor. The (possibly modified) response returned by + `post_delete_backup` will be passed to + `post_delete_backup_with_metadata`. + """ + return response, metadata + def pre_delete_service( self, request: metastore.DeleteServiceRequest, @@ -367,12 +482,35 @@ def post_delete_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_delete_service` interceptor runs + before the `post_delete_service_with_metadata` interceptor. """ return response + def post_delete_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_delete_service_with_metadata` + interceptor in new development instead of the `post_delete_service` interceptor. + When both interceptors are used, this `post_delete_service_with_metadata` interceptor runs after the + `post_delete_service` interceptor. The (possibly modified) response returned by + `post_delete_service` will be passed to + `post_delete_service_with_metadata`. + """ + return response, metadata + def pre_export_metadata( self, request: metastore.ExportMetadataRequest, @@ -392,12 +530,35 @@ def post_export_metadata( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_metadata - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_metadata_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_export_metadata` interceptor runs + before the `post_export_metadata_with_metadata` interceptor. """ return response + def post_export_metadata_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_metadata + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_export_metadata_with_metadata` + interceptor in new development instead of the `post_export_metadata` interceptor. + When both interceptors are used, this `post_export_metadata_with_metadata` interceptor runs after the + `post_export_metadata` interceptor. The (possibly modified) response returned by + `post_export_metadata` will be passed to + `post_export_metadata_with_metadata`. + """ + return response, metadata + def pre_get_backup( self, request: metastore.GetBackupRequest, @@ -413,12 +574,35 @@ def pre_get_backup( def post_get_backup(self, response: metastore.Backup) -> metastore.Backup: """Post-rpc interceptor for get_backup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_backup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_get_backup` interceptor runs + before the `post_get_backup_with_metadata` interceptor. """ return response + def post_get_backup_with_metadata( + self, + response: metastore.Backup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.Backup, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_backup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_get_backup_with_metadata` + interceptor in new development instead of the `post_get_backup` interceptor. + When both interceptors are used, this `post_get_backup_with_metadata` interceptor runs after the + `post_get_backup` interceptor. The (possibly modified) response returned by + `post_get_backup` will be passed to + `post_get_backup_with_metadata`. + """ + return response, metadata + def pre_get_metadata_import( self, request: metastore.GetMetadataImportRequest, @@ -438,12 +622,35 @@ def post_get_metadata_import( ) -> metastore.MetadataImport: """Post-rpc interceptor for get_metadata_import - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_metadata_import_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_get_metadata_import` interceptor runs + before the `post_get_metadata_import_with_metadata` interceptor. """ return response + def post_get_metadata_import_with_metadata( + self, + response: metastore.MetadataImport, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.MetadataImport, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_metadata_import + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_get_metadata_import_with_metadata` + interceptor in new development instead of the `post_get_metadata_import` interceptor. + When both interceptors are used, this `post_get_metadata_import_with_metadata` interceptor runs after the + `post_get_metadata_import` interceptor. The (possibly modified) response returned by + `post_get_metadata_import` will be passed to + `post_get_metadata_import_with_metadata`. + """ + return response, metadata + def pre_get_service( self, request: metastore.GetServiceRequest, @@ -459,12 +666,35 @@ def pre_get_service( def post_get_service(self, response: metastore.Service) -> metastore.Service: """Post-rpc interceptor for get_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_get_service` interceptor runs + before the `post_get_service_with_metadata` interceptor. """ return response + def post_get_service_with_metadata( + self, + response: metastore.Service, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.Service, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_get_service_with_metadata` + interceptor in new development instead of the `post_get_service` interceptor. + When both interceptors are used, this `post_get_service_with_metadata` interceptor runs after the + `post_get_service` interceptor. The (possibly modified) response returned by + `post_get_service` will be passed to + `post_get_service_with_metadata`. + """ + return response, metadata + def pre_list_backups( self, request: metastore.ListBackupsRequest, @@ -482,12 +712,35 @@ def post_list_backups( ) -> metastore.ListBackupsResponse: """Post-rpc interceptor for list_backups - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_backups_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_list_backups` interceptor runs + before the `post_list_backups_with_metadata` interceptor. """ return response + def post_list_backups_with_metadata( + self, + response: metastore.ListBackupsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.ListBackupsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_backups + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_list_backups_with_metadata` + interceptor in new development instead of the `post_list_backups` interceptor. + When both interceptors are used, this `post_list_backups_with_metadata` interceptor runs after the + `post_list_backups` interceptor. The (possibly modified) response returned by + `post_list_backups` will be passed to + `post_list_backups_with_metadata`. + """ + return response, metadata + def pre_list_metadata_imports( self, request: metastore.ListMetadataImportsRequest, @@ -507,12 +760,37 @@ def post_list_metadata_imports( ) -> metastore.ListMetadataImportsResponse: """Post-rpc interceptor for list_metadata_imports - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_metadata_imports_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_list_metadata_imports` interceptor runs + before the `post_list_metadata_imports_with_metadata` interceptor. """ return response + def post_list_metadata_imports_with_metadata( + self, + response: metastore.ListMetadataImportsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore.ListMetadataImportsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_metadata_imports + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_list_metadata_imports_with_metadata` + interceptor in new development instead of the `post_list_metadata_imports` interceptor. + When both interceptors are used, this `post_list_metadata_imports_with_metadata` interceptor runs after the + `post_list_metadata_imports` interceptor. The (possibly modified) response returned by + `post_list_metadata_imports` will be passed to + `post_list_metadata_imports_with_metadata`. + """ + return response, metadata + def pre_list_services( self, request: metastore.ListServicesRequest, @@ -530,12 +808,35 @@ def post_list_services( ) -> metastore.ListServicesResponse: """Post-rpc interceptor for list_services - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_services_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_list_services` interceptor runs + before the `post_list_services_with_metadata` interceptor. """ return response + def post_list_services_with_metadata( + self, + response: metastore.ListServicesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[metastore.ListServicesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_services + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_list_services_with_metadata` + interceptor in new development instead of the `post_list_services` interceptor. + When both interceptors are used, this `post_list_services_with_metadata` interceptor runs after the + `post_list_services` interceptor. The (possibly modified) response returned by + `post_list_services` will be passed to + `post_list_services_with_metadata`. + """ + return response, metadata + def pre_move_table_to_database( self, request: metastore.MoveTableToDatabaseRequest, @@ -555,12 +856,35 @@ def post_move_table_to_database( ) -> operations_pb2.Operation: """Post-rpc interceptor for move_table_to_database - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_move_table_to_database_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_move_table_to_database` interceptor runs + before the `post_move_table_to_database_with_metadata` interceptor. """ return response + def post_move_table_to_database_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for move_table_to_database + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_move_table_to_database_with_metadata` + interceptor in new development instead of the `post_move_table_to_database` interceptor. + When both interceptors are used, this `post_move_table_to_database_with_metadata` interceptor runs after the + `post_move_table_to_database` interceptor. The (possibly modified) response returned by + `post_move_table_to_database` will be passed to + `post_move_table_to_database_with_metadata`. + """ + return response, metadata + def pre_query_metadata( self, request: metastore.QueryMetadataRequest, @@ -578,12 +902,35 @@ def post_query_metadata( ) -> operations_pb2.Operation: """Post-rpc interceptor for query_metadata - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_query_metadata_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_query_metadata` interceptor runs + before the `post_query_metadata_with_metadata` interceptor. """ return response + def post_query_metadata_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for query_metadata + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_query_metadata_with_metadata` + interceptor in new development instead of the `post_query_metadata` interceptor. + When both interceptors are used, this `post_query_metadata_with_metadata` interceptor runs after the + `post_query_metadata` interceptor. The (possibly modified) response returned by + `post_query_metadata` will be passed to + `post_query_metadata_with_metadata`. + """ + return response, metadata + def pre_remove_iam_policy( self, request: metastore.RemoveIamPolicyRequest, @@ -603,12 +950,37 @@ def post_remove_iam_policy( ) -> metastore.RemoveIamPolicyResponse: """Post-rpc interceptor for remove_iam_policy - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_remove_iam_policy_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_remove_iam_policy` interceptor runs + before the `post_remove_iam_policy_with_metadata` interceptor. """ return response + def post_remove_iam_policy_with_metadata( + self, + response: metastore.RemoveIamPolicyResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore.RemoveIamPolicyResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for remove_iam_policy + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_remove_iam_policy_with_metadata` + interceptor in new development instead of the `post_remove_iam_policy` interceptor. + When both interceptors are used, this `post_remove_iam_policy_with_metadata` interceptor runs after the + `post_remove_iam_policy` interceptor. The (possibly modified) response returned by + `post_remove_iam_policy` will be passed to + `post_remove_iam_policy_with_metadata`. + """ + return response, metadata + def pre_restore_service( self, request: metastore.RestoreServiceRequest, @@ -628,12 +1000,35 @@ def post_restore_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for restore_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_restore_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_restore_service` interceptor runs + before the `post_restore_service_with_metadata` interceptor. """ return response + def post_restore_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for restore_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_restore_service_with_metadata` + interceptor in new development instead of the `post_restore_service` interceptor. + When both interceptors are used, this `post_restore_service_with_metadata` interceptor runs after the + `post_restore_service` interceptor. The (possibly modified) response returned by + `post_restore_service` will be passed to + `post_restore_service_with_metadata`. + """ + return response, metadata + def pre_update_metadata_import( self, request: metastore.UpdateMetadataImportRequest, @@ -653,12 +1048,35 @@ def post_update_metadata_import( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_metadata_import - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_metadata_import_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_update_metadata_import` interceptor runs + before the `post_update_metadata_import_with_metadata` interceptor. """ return response + def post_update_metadata_import_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_metadata_import + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_update_metadata_import_with_metadata` + interceptor in new development instead of the `post_update_metadata_import` interceptor. + When both interceptors are used, this `post_update_metadata_import_with_metadata` interceptor runs after the + `post_update_metadata_import` interceptor. The (possibly modified) response returned by + `post_update_metadata_import` will be passed to + `post_update_metadata_import_with_metadata`. + """ + return response, metadata + def pre_update_service( self, request: metastore.UpdateServiceRequest, @@ -676,12 +1094,35 @@ def post_update_service( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_service - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_service_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastore server but before - it is returned to user code. + it is returned to user code. This `post_update_service` interceptor runs + before the `post_update_service_with_metadata` interceptor. """ return response + def post_update_service_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_service + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastore server but before it is returned to user code. + + We recommend only using this `post_update_service_with_metadata` + interceptor in new development instead of the `post_update_service` interceptor. + When both interceptors are used, this `post_update_service_with_metadata` interceptor runs after the + `post_update_service` interceptor. The (possibly modified) response returned by + `post_update_service` will be passed to + `post_update_service_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -1191,6 +1632,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_alter_metadata_resource_location(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_alter_metadata_resource_location_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1339,6 +1787,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_backup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_backup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1492,6 +1944,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_metadata_import(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_metadata_import_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1641,6 +2097,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1783,6 +2243,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_backup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_backup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1926,6 +2390,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2075,6 +2543,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_metadata(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_metadata_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2216,6 +2688,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_backup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_backup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2362,6 +2838,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_metadata_import(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_metadata_import_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2505,6 +2985,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2648,6 +3132,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_backups(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_backups_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2796,6 +3284,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_metadata_imports(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_metadata_imports_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2941,6 +3433,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_services(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_services_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3094,6 +3590,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_move_table_to_database(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_move_table_to_database_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3243,6 +3743,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_query_metadata(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_query_metadata_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3395,6 +3899,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_remove_iam_policy(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_remove_iam_policy_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3545,6 +4053,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_restore_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_restore_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3698,6 +4210,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_metadata_import(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_metadata_import_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3847,6 +4363,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_service(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_service_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore_federation/client.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore_federation/client.py index 480805965138..5b154f5d2c96 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore_federation/client.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore_federation/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -517,6 +519,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1434,16 +1463,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1489,16 +1522,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -1721,16 +1758,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1843,16 +1884,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -1903,16 +1948,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_location( self, @@ -1958,16 +2007,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2013,16 +2066,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore_federation/transports/rest.py b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore_federation/transports/rest.py index 29e1260cc6e2..c1da06a58781 100644 --- a/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore_federation/transports/rest.py +++ b/packages/google-cloud-dataproc-metastore/google/cloud/metastore_v1beta/services/dataproc_metastore_federation/transports/rest.py @@ -138,12 +138,35 @@ def post_create_federation( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_create_federation` interceptor runs + before the `post_create_federation_with_metadata` interceptor. """ return response + def post_create_federation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_create_federation_with_metadata` + interceptor in new development instead of the `post_create_federation` interceptor. + When both interceptors are used, this `post_create_federation_with_metadata` interceptor runs after the + `post_create_federation` interceptor. The (possibly modified) response returned by + `post_create_federation` will be passed to + `post_create_federation_with_metadata`. + """ + return response, metadata + def pre_delete_federation( self, request: metastore_federation.DeleteFederationRequest, @@ -164,12 +187,35 @@ def post_delete_federation( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_delete_federation` interceptor runs + before the `post_delete_federation_with_metadata` interceptor. """ return response + def post_delete_federation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_delete_federation_with_metadata` + interceptor in new development instead of the `post_delete_federation` interceptor. + When both interceptors are used, this `post_delete_federation_with_metadata` interceptor runs after the + `post_delete_federation` interceptor. The (possibly modified) response returned by + `post_delete_federation` will be passed to + `post_delete_federation_with_metadata`. + """ + return response, metadata + def pre_get_federation( self, request: metastore_federation.GetFederationRequest, @@ -190,12 +236,37 @@ def post_get_federation( ) -> metastore_federation.Federation: """Post-rpc interceptor for get_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_get_federation` interceptor runs + before the `post_get_federation_with_metadata` interceptor. """ return response + def post_get_federation_with_metadata( + self, + response: metastore_federation.Federation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore_federation.Federation, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_get_federation_with_metadata` + interceptor in new development instead of the `post_get_federation` interceptor. + When both interceptors are used, this `post_get_federation_with_metadata` interceptor runs after the + `post_get_federation` interceptor. The (possibly modified) response returned by + `post_get_federation` will be passed to + `post_get_federation_with_metadata`. + """ + return response, metadata + def pre_list_federations( self, request: metastore_federation.ListFederationsRequest, @@ -216,12 +287,38 @@ def post_list_federations( ) -> metastore_federation.ListFederationsResponse: """Post-rpc interceptor for list_federations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_federations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_list_federations` interceptor runs + before the `post_list_federations_with_metadata` interceptor. """ return response + def post_list_federations_with_metadata( + self, + response: metastore_federation.ListFederationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + metastore_federation.ListFederationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_federations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_list_federations_with_metadata` + interceptor in new development instead of the `post_list_federations` interceptor. + When both interceptors are used, this `post_list_federations_with_metadata` interceptor runs after the + `post_list_federations` interceptor. The (possibly modified) response returned by + `post_list_federations` will be passed to + `post_list_federations_with_metadata`. + """ + return response, metadata + def pre_update_federation( self, request: metastore_federation.UpdateFederationRequest, @@ -242,12 +339,35 @@ def post_update_federation( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_federation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_federation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataprocMetastoreFederation server but before - it is returned to user code. + it is returned to user code. This `post_update_federation` interceptor runs + before the `post_update_federation_with_metadata` interceptor. """ return response + def post_update_federation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_federation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataprocMetastoreFederation server but before it is returned to user code. + + We recommend only using this `post_update_federation_with_metadata` + interceptor in new development instead of the `post_update_federation` interceptor. + When both interceptors are used, this `post_update_federation_with_metadata` interceptor runs after the + `post_update_federation` interceptor. The (possibly modified) response returned by + `post_update_federation` will be passed to + `post_update_federation_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -750,6 +870,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -894,6 +1018,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1039,6 +1167,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1184,6 +1316,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_federations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_federations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1336,6 +1472,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_federation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_federation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1.json b/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1.json index ba05a3c7cbba..a1409ff0b020 100644 --- a/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1.json +++ b/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dataproc-metastore", - "version": "1.17.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1alpha.json b/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1alpha.json index f047479b9f21..2e7667ce048f 100644 --- a/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1alpha.json +++ b/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dataproc-metastore", - "version": "1.17.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1beta.json b/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1beta.json index 94eb5dcb868f..8f741b2fab3f 100644 --- a/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1beta.json +++ b/packages/google-cloud-dataproc-metastore/samples/generated_samples/snippet_metadata_google.cloud.metastore.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dataproc-metastore", - "version": "1.17.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1/test_dataproc_metastore.py b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1/test_dataproc_metastore.py index 89df5f01663a..e7d24120ce8f 100644 --- a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1/test_dataproc_metastore.py +++ b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1/test_dataproc_metastore.py @@ -79,6 +79,13 @@ ) from google.cloud.metastore_v1.types import metastore +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -346,6 +353,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataprocMetastoreClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataprocMetastoreClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -12242,10 +12292,13 @@ def test_list_services_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_list_services" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_list_services_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_list_services" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ListServicesRequest.pb(metastore.ListServicesRequest()) transcode.return_value = { "method": "post", @@ -12269,6 +12322,7 @@ def test_list_services_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.ListServicesResponse() + post_with_metadata.return_value = metastore.ListServicesResponse(), metadata client.list_services( request, @@ -12280,6 +12334,7 @@ def test_list_services_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_service_rest_bad_request(request_type=metastore.GetServiceRequest): @@ -12382,10 +12437,13 @@ def test_get_service_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_get_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_get_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_get_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.GetServiceRequest.pb(metastore.GetServiceRequest()) transcode.return_value = { "method": "post", @@ -12407,6 +12465,7 @@ def test_get_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.Service() + post_with_metadata.return_value = metastore.Service(), metadata client.get_service( request, @@ -12418,6 +12477,7 @@ def test_get_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_service_rest_bad_request(request_type=metastore.CreateServiceRequest): @@ -12624,10 +12684,13 @@ def test_create_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_create_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_create_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_create_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.CreateServiceRequest.pb(metastore.CreateServiceRequest()) transcode.return_value = { "method": "post", @@ -12649,6 +12712,7 @@ def test_create_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_service( request, @@ -12660,6 +12724,7 @@ def test_create_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_service_rest_bad_request(request_type=metastore.UpdateServiceRequest): @@ -12870,10 +12935,13 @@ def test_update_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_update_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_update_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_update_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.UpdateServiceRequest.pb(metastore.UpdateServiceRequest()) transcode.return_value = { "method": "post", @@ -12895,6 +12963,7 @@ def test_update_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_service( request, @@ -12906,6 +12975,7 @@ def test_update_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_service_rest_bad_request(request_type=metastore.DeleteServiceRequest): @@ -12984,10 +13054,13 @@ def test_delete_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_delete_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_delete_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_delete_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.DeleteServiceRequest.pb(metastore.DeleteServiceRequest()) transcode.return_value = { "method": "post", @@ -13009,6 +13082,7 @@ def test_delete_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_service( request, @@ -13020,6 +13094,7 @@ def test_delete_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_metadata_imports_rest_bad_request( @@ -13106,10 +13181,14 @@ def test_list_metadata_imports_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_list_metadata_imports" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_list_metadata_imports_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_list_metadata_imports" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ListMetadataImportsRequest.pb( metastore.ListMetadataImportsRequest() ) @@ -13135,6 +13214,10 @@ def test_list_metadata_imports_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.ListMetadataImportsResponse() + post_with_metadata.return_value = ( + metastore.ListMetadataImportsResponse(), + metadata, + ) client.list_metadata_imports( request, @@ -13146,6 +13229,7 @@ def test_list_metadata_imports_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_metadata_import_rest_bad_request( @@ -13238,10 +13322,14 @@ def test_get_metadata_import_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_get_metadata_import" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_get_metadata_import_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_get_metadata_import" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.GetMetadataImportRequest.pb( metastore.GetMetadataImportRequest() ) @@ -13265,6 +13353,7 @@ def test_get_metadata_import_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.MetadataImport() + post_with_metadata.return_value = metastore.MetadataImport(), metadata client.get_metadata_import( request, @@ -13276,6 +13365,7 @@ def test_get_metadata_import_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_metadata_import_rest_bad_request( @@ -13437,10 +13527,14 @@ def test_create_metadata_import_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_create_metadata_import" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_create_metadata_import_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_create_metadata_import" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.CreateMetadataImportRequest.pb( metastore.CreateMetadataImportRequest() ) @@ -13464,6 +13558,7 @@ def test_create_metadata_import_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_metadata_import( request, @@ -13475,6 +13570,7 @@ def test_create_metadata_import_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_metadata_import_rest_bad_request( @@ -13644,10 +13740,14 @@ def test_update_metadata_import_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_update_metadata_import" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_update_metadata_import_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_update_metadata_import" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.UpdateMetadataImportRequest.pb( metastore.UpdateMetadataImportRequest() ) @@ -13671,6 +13771,7 @@ def test_update_metadata_import_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_metadata_import( request, @@ -13682,6 +13783,7 @@ def test_update_metadata_import_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_metadata_rest_bad_request(request_type=metastore.ExportMetadataRequest): @@ -13760,10 +13862,14 @@ def test_export_metadata_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_export_metadata" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_export_metadata_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_export_metadata" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ExportMetadataRequest.pb( metastore.ExportMetadataRequest() ) @@ -13787,6 +13893,7 @@ def test_export_metadata_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_metadata( request, @@ -13798,6 +13905,7 @@ def test_export_metadata_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_restore_service_rest_bad_request(request_type=metastore.RestoreServiceRequest): @@ -13876,10 +13984,14 @@ def test_restore_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_restore_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_restore_service_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_restore_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.RestoreServiceRequest.pb( metastore.RestoreServiceRequest() ) @@ -13903,6 +14015,7 @@ def test_restore_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.restore_service( request, @@ -13914,6 +14027,7 @@ def test_restore_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_backups_rest_bad_request(request_type=metastore.ListBackupsRequest): @@ -13998,10 +14112,13 @@ def test_list_backups_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_list_backups" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_list_backups_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_list_backups" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ListBackupsRequest.pb(metastore.ListBackupsRequest()) transcode.return_value = { "method": "post", @@ -14025,6 +14142,7 @@ def test_list_backups_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.ListBackupsResponse() + post_with_metadata.return_value = metastore.ListBackupsResponse(), metadata client.list_backups( request, @@ -14036,6 +14154,7 @@ def test_list_backups_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_backup_rest_bad_request(request_type=metastore.GetBackupRequest): @@ -14128,10 +14247,13 @@ def test_get_backup_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_get_backup" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_get_backup_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_get_backup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.GetBackupRequest.pb(metastore.GetBackupRequest()) transcode.return_value = { "method": "post", @@ -14153,6 +14275,7 @@ def test_get_backup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.Backup() + post_with_metadata.return_value = metastore.Backup(), metadata client.get_backup( request, @@ -14164,6 +14287,7 @@ def test_get_backup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_backup_rest_bad_request(request_type=metastore.CreateBackupRequest): @@ -14381,10 +14505,13 @@ def test_create_backup_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_create_backup" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_create_backup_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_create_backup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.CreateBackupRequest.pb(metastore.CreateBackupRequest()) transcode.return_value = { "method": "post", @@ -14406,6 +14533,7 @@ def test_create_backup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_backup( request, @@ -14417,6 +14545,7 @@ def test_create_backup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_backup_rest_bad_request(request_type=metastore.DeleteBackupRequest): @@ -14499,10 +14628,13 @@ def test_delete_backup_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_delete_backup" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_delete_backup_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_delete_backup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.DeleteBackupRequest.pb(metastore.DeleteBackupRequest()) transcode.return_value = { "method": "post", @@ -14524,6 +14656,7 @@ def test_delete_backup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_backup( request, @@ -14535,6 +14668,7 @@ def test_delete_backup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_query_metadata_rest_bad_request(request_type=metastore.QueryMetadataRequest): @@ -14613,10 +14747,13 @@ def test_query_metadata_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_query_metadata" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_query_metadata_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_query_metadata" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.QueryMetadataRequest.pb(metastore.QueryMetadataRequest()) transcode.return_value = { "method": "post", @@ -14638,6 +14775,7 @@ def test_query_metadata_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.query_metadata( request, @@ -14649,6 +14787,7 @@ def test_query_metadata_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_move_table_to_database_rest_bad_request( @@ -14729,10 +14868,14 @@ def test_move_table_to_database_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_move_table_to_database" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_move_table_to_database_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_move_table_to_database" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.MoveTableToDatabaseRequest.pb( metastore.MoveTableToDatabaseRequest() ) @@ -14756,6 +14899,7 @@ def test_move_table_to_database_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.move_table_to_database( request, @@ -14767,6 +14911,7 @@ def test_move_table_to_database_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_alter_metadata_resource_location_rest_bad_request( @@ -14848,11 +14993,15 @@ def test_alter_metadata_resource_location_rest_interceptors(null_interceptor): transports.DataprocMetastoreRestInterceptor, "post_alter_metadata_resource_location", ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_alter_metadata_resource_location_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_alter_metadata_resource_location", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.AlterMetadataResourceLocationRequest.pb( metastore.AlterMetadataResourceLocationRequest() ) @@ -14876,6 +15025,7 @@ def test_alter_metadata_resource_location_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.alter_metadata_resource_location( request, @@ -14887,6 +15037,7 @@ def test_alter_metadata_resource_location_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1/test_dataproc_metastore_federation.py b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1/test_dataproc_metastore_federation.py index b095518768bc..053ca6c61449 100644 --- a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1/test_dataproc_metastore_federation.py +++ b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1/test_dataproc_metastore_federation.py @@ -77,6 +77,13 @@ ) from google.cloud.metastore_v1.types import metastore, metastore_federation +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -360,6 +367,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataprocMetastoreFederationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataprocMetastoreFederationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4606,10 +4656,14 @@ def test_list_federations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_list_federations" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_list_federations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_list_federations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.ListFederationsRequest.pb( metastore_federation.ListFederationsRequest() ) @@ -4635,6 +4689,10 @@ def test_list_federations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore_federation.ListFederationsResponse() + post_with_metadata.return_value = ( + metastore_federation.ListFederationsResponse(), + metadata, + ) client.list_federations( request, @@ -4646,6 +4704,7 @@ def test_list_federations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_federation_rest_bad_request( @@ -4740,10 +4799,14 @@ def test_get_federation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_get_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_get_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_get_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.GetFederationRequest.pb( metastore_federation.GetFederationRequest() ) @@ -4769,6 +4832,7 @@ def test_get_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore_federation.Federation() + post_with_metadata.return_value = metastore_federation.Federation(), metadata client.get_federation( request, @@ -4780,6 +4844,7 @@ def test_get_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_federation_rest_bad_request( @@ -4939,10 +5004,14 @@ def test_create_federation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_create_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_create_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_create_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.CreateFederationRequest.pb( metastore_federation.CreateFederationRequest() ) @@ -4966,6 +5035,7 @@ def test_create_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_federation( request, @@ -4977,6 +5047,7 @@ def test_create_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_federation_rest_bad_request( @@ -5140,10 +5211,14 @@ def test_update_federation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_update_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_update_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_update_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.UpdateFederationRequest.pb( metastore_federation.UpdateFederationRequest() ) @@ -5167,6 +5242,7 @@ def test_update_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_federation( request, @@ -5178,6 +5254,7 @@ def test_update_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_federation_rest_bad_request( @@ -5258,10 +5335,14 @@ def test_delete_federation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_delete_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_delete_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_delete_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.DeleteFederationRequest.pb( metastore_federation.DeleteFederationRequest() ) @@ -5285,6 +5366,7 @@ def test_delete_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_federation( request, @@ -5296,6 +5378,7 @@ def test_delete_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1alpha/test_dataproc_metastore.py b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1alpha/test_dataproc_metastore.py index 7aeb2d72bd89..9bcc9fdffaba 100644 --- a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1alpha/test_dataproc_metastore.py +++ b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1alpha/test_dataproc_metastore.py @@ -79,6 +79,13 @@ ) from google.cloud.metastore_v1alpha.types import metastore +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -346,6 +353,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataprocMetastoreClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataprocMetastoreClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -12674,10 +12724,13 @@ def test_list_services_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_list_services" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_list_services_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_list_services" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ListServicesRequest.pb(metastore.ListServicesRequest()) transcode.return_value = { "method": "post", @@ -12701,6 +12754,7 @@ def test_list_services_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.ListServicesResponse() + post_with_metadata.return_value = metastore.ListServicesResponse(), metadata client.list_services( request, @@ -12712,6 +12766,7 @@ def test_list_services_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_service_rest_bad_request(request_type=metastore.GetServiceRequest): @@ -12814,10 +12869,13 @@ def test_get_service_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_get_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_get_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_get_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.GetServiceRequest.pb(metastore.GetServiceRequest()) transcode.return_value = { "method": "post", @@ -12839,6 +12897,7 @@ def test_get_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.Service() + post_with_metadata.return_value = metastore.Service(), metadata client.get_service( request, @@ -12850,6 +12909,7 @@ def test_get_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_service_rest_bad_request(request_type=metastore.CreateServiceRequest): @@ -13061,10 +13121,13 @@ def test_create_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_create_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_create_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_create_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.CreateServiceRequest.pb(metastore.CreateServiceRequest()) transcode.return_value = { "method": "post", @@ -13086,6 +13149,7 @@ def test_create_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_service( request, @@ -13097,6 +13161,7 @@ def test_create_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_service_rest_bad_request(request_type=metastore.UpdateServiceRequest): @@ -13312,10 +13377,13 @@ def test_update_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_update_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_update_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_update_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.UpdateServiceRequest.pb(metastore.UpdateServiceRequest()) transcode.return_value = { "method": "post", @@ -13337,6 +13405,7 @@ def test_update_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_service( request, @@ -13348,6 +13417,7 @@ def test_update_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_service_rest_bad_request(request_type=metastore.DeleteServiceRequest): @@ -13426,10 +13496,13 @@ def test_delete_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_delete_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_delete_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_delete_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.DeleteServiceRequest.pb(metastore.DeleteServiceRequest()) transcode.return_value = { "method": "post", @@ -13451,6 +13524,7 @@ def test_delete_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_service( request, @@ -13462,6 +13536,7 @@ def test_delete_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_metadata_imports_rest_bad_request( @@ -13548,10 +13623,14 @@ def test_list_metadata_imports_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_list_metadata_imports" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_list_metadata_imports_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_list_metadata_imports" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ListMetadataImportsRequest.pb( metastore.ListMetadataImportsRequest() ) @@ -13577,6 +13656,10 @@ def test_list_metadata_imports_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.ListMetadataImportsResponse() + post_with_metadata.return_value = ( + metastore.ListMetadataImportsResponse(), + metadata, + ) client.list_metadata_imports( request, @@ -13588,6 +13671,7 @@ def test_list_metadata_imports_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_metadata_import_rest_bad_request( @@ -13680,10 +13764,14 @@ def test_get_metadata_import_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_get_metadata_import" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_get_metadata_import_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_get_metadata_import" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.GetMetadataImportRequest.pb( metastore.GetMetadataImportRequest() ) @@ -13707,6 +13795,7 @@ def test_get_metadata_import_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.MetadataImport() + post_with_metadata.return_value = metastore.MetadataImport(), metadata client.get_metadata_import( request, @@ -13718,6 +13807,7 @@ def test_get_metadata_import_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_metadata_import_rest_bad_request( @@ -13879,10 +13969,14 @@ def test_create_metadata_import_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_create_metadata_import" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_create_metadata_import_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_create_metadata_import" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.CreateMetadataImportRequest.pb( metastore.CreateMetadataImportRequest() ) @@ -13906,6 +14000,7 @@ def test_create_metadata_import_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_metadata_import( request, @@ -13917,6 +14012,7 @@ def test_create_metadata_import_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_metadata_import_rest_bad_request( @@ -14086,10 +14182,14 @@ def test_update_metadata_import_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_update_metadata_import" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_update_metadata_import_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_update_metadata_import" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.UpdateMetadataImportRequest.pb( metastore.UpdateMetadataImportRequest() ) @@ -14113,6 +14213,7 @@ def test_update_metadata_import_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_metadata_import( request, @@ -14124,6 +14225,7 @@ def test_update_metadata_import_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_metadata_rest_bad_request(request_type=metastore.ExportMetadataRequest): @@ -14202,10 +14304,14 @@ def test_export_metadata_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_export_metadata" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_export_metadata_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_export_metadata" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ExportMetadataRequest.pb( metastore.ExportMetadataRequest() ) @@ -14229,6 +14335,7 @@ def test_export_metadata_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_metadata( request, @@ -14240,6 +14347,7 @@ def test_export_metadata_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_restore_service_rest_bad_request(request_type=metastore.RestoreServiceRequest): @@ -14318,10 +14426,14 @@ def test_restore_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_restore_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_restore_service_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_restore_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.RestoreServiceRequest.pb( metastore.RestoreServiceRequest() ) @@ -14345,6 +14457,7 @@ def test_restore_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.restore_service( request, @@ -14356,6 +14469,7 @@ def test_restore_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_backups_rest_bad_request(request_type=metastore.ListBackupsRequest): @@ -14440,10 +14554,13 @@ def test_list_backups_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_list_backups" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_list_backups_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_list_backups" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ListBackupsRequest.pb(metastore.ListBackupsRequest()) transcode.return_value = { "method": "post", @@ -14467,6 +14584,7 @@ def test_list_backups_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.ListBackupsResponse() + post_with_metadata.return_value = metastore.ListBackupsResponse(), metadata client.list_backups( request, @@ -14478,6 +14596,7 @@ def test_list_backups_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_backup_rest_bad_request(request_type=metastore.GetBackupRequest): @@ -14570,10 +14689,13 @@ def test_get_backup_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_get_backup" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_get_backup_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_get_backup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.GetBackupRequest.pb(metastore.GetBackupRequest()) transcode.return_value = { "method": "post", @@ -14595,6 +14717,7 @@ def test_get_backup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.Backup() + post_with_metadata.return_value = metastore.Backup(), metadata client.get_backup( request, @@ -14606,6 +14729,7 @@ def test_get_backup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_backup_rest_bad_request(request_type=metastore.CreateBackupRequest): @@ -14828,10 +14952,13 @@ def test_create_backup_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_create_backup" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_create_backup_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_create_backup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.CreateBackupRequest.pb(metastore.CreateBackupRequest()) transcode.return_value = { "method": "post", @@ -14853,6 +14980,7 @@ def test_create_backup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_backup( request, @@ -14864,6 +14992,7 @@ def test_create_backup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_backup_rest_bad_request(request_type=metastore.DeleteBackupRequest): @@ -14946,10 +15075,13 @@ def test_delete_backup_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_delete_backup" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_delete_backup_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_delete_backup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.DeleteBackupRequest.pb(metastore.DeleteBackupRequest()) transcode.return_value = { "method": "post", @@ -14971,6 +15103,7 @@ def test_delete_backup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_backup( request, @@ -14982,6 +15115,7 @@ def test_delete_backup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_remove_iam_policy_rest_bad_request( @@ -15070,10 +15204,14 @@ def test_remove_iam_policy_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_remove_iam_policy" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_remove_iam_policy_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_remove_iam_policy" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.RemoveIamPolicyRequest.pb( metastore.RemoveIamPolicyRequest() ) @@ -15099,6 +15237,7 @@ def test_remove_iam_policy_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.RemoveIamPolicyResponse() + post_with_metadata.return_value = metastore.RemoveIamPolicyResponse(), metadata client.remove_iam_policy( request, @@ -15110,6 +15249,7 @@ def test_remove_iam_policy_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_query_metadata_rest_bad_request(request_type=metastore.QueryMetadataRequest): @@ -15188,10 +15328,13 @@ def test_query_metadata_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_query_metadata" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_query_metadata_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_query_metadata" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.QueryMetadataRequest.pb(metastore.QueryMetadataRequest()) transcode.return_value = { "method": "post", @@ -15213,6 +15356,7 @@ def test_query_metadata_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.query_metadata( request, @@ -15224,6 +15368,7 @@ def test_query_metadata_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_move_table_to_database_rest_bad_request( @@ -15304,10 +15449,14 @@ def test_move_table_to_database_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_move_table_to_database" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_move_table_to_database_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_move_table_to_database" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.MoveTableToDatabaseRequest.pb( metastore.MoveTableToDatabaseRequest() ) @@ -15331,6 +15480,7 @@ def test_move_table_to_database_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.move_table_to_database( request, @@ -15342,6 +15492,7 @@ def test_move_table_to_database_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_alter_metadata_resource_location_rest_bad_request( @@ -15423,11 +15574,15 @@ def test_alter_metadata_resource_location_rest_interceptors(null_interceptor): transports.DataprocMetastoreRestInterceptor, "post_alter_metadata_resource_location", ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_alter_metadata_resource_location_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_alter_metadata_resource_location", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.AlterMetadataResourceLocationRequest.pb( metastore.AlterMetadataResourceLocationRequest() ) @@ -15451,6 +15606,7 @@ def test_alter_metadata_resource_location_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.alter_metadata_resource_location( request, @@ -15462,6 +15618,7 @@ def test_alter_metadata_resource_location_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1alpha/test_dataproc_metastore_federation.py b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1alpha/test_dataproc_metastore_federation.py index fcc0a14c2e23..2c92319a594f 100644 --- a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1alpha/test_dataproc_metastore_federation.py +++ b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1alpha/test_dataproc_metastore_federation.py @@ -77,6 +77,13 @@ ) from google.cloud.metastore_v1alpha.types import metastore, metastore_federation +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -360,6 +367,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataprocMetastoreFederationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataprocMetastoreFederationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4606,10 +4656,14 @@ def test_list_federations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_list_federations" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_list_federations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_list_federations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.ListFederationsRequest.pb( metastore_federation.ListFederationsRequest() ) @@ -4635,6 +4689,10 @@ def test_list_federations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore_federation.ListFederationsResponse() + post_with_metadata.return_value = ( + metastore_federation.ListFederationsResponse(), + metadata, + ) client.list_federations( request, @@ -4646,6 +4704,7 @@ def test_list_federations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_federation_rest_bad_request( @@ -4740,10 +4799,14 @@ def test_get_federation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_get_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_get_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_get_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.GetFederationRequest.pb( metastore_federation.GetFederationRequest() ) @@ -4769,6 +4832,7 @@ def test_get_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore_federation.Federation() + post_with_metadata.return_value = metastore_federation.Federation(), metadata client.get_federation( request, @@ -4780,6 +4844,7 @@ def test_get_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_federation_rest_bad_request( @@ -4939,10 +5004,14 @@ def test_create_federation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_create_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_create_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_create_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.CreateFederationRequest.pb( metastore_federation.CreateFederationRequest() ) @@ -4966,6 +5035,7 @@ def test_create_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_federation( request, @@ -4977,6 +5047,7 @@ def test_create_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_federation_rest_bad_request( @@ -5140,10 +5211,14 @@ def test_update_federation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_update_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_update_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_update_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.UpdateFederationRequest.pb( metastore_federation.UpdateFederationRequest() ) @@ -5167,6 +5242,7 @@ def test_update_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_federation( request, @@ -5178,6 +5254,7 @@ def test_update_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_federation_rest_bad_request( @@ -5258,10 +5335,14 @@ def test_delete_federation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_delete_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_delete_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_delete_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.DeleteFederationRequest.pb( metastore_federation.DeleteFederationRequest() ) @@ -5285,6 +5366,7 @@ def test_delete_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_federation( request, @@ -5296,6 +5378,7 @@ def test_delete_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1beta/test_dataproc_metastore.py b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1beta/test_dataproc_metastore.py index cf9131ad25dd..0303ff4426cf 100644 --- a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1beta/test_dataproc_metastore.py +++ b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1beta/test_dataproc_metastore.py @@ -79,6 +79,13 @@ ) from google.cloud.metastore_v1beta.types import metastore +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -346,6 +353,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataprocMetastoreClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataprocMetastoreClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -12674,10 +12724,13 @@ def test_list_services_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_list_services" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_list_services_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_list_services" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ListServicesRequest.pb(metastore.ListServicesRequest()) transcode.return_value = { "method": "post", @@ -12701,6 +12754,7 @@ def test_list_services_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.ListServicesResponse() + post_with_metadata.return_value = metastore.ListServicesResponse(), metadata client.list_services( request, @@ -12712,6 +12766,7 @@ def test_list_services_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_service_rest_bad_request(request_type=metastore.GetServiceRequest): @@ -12814,10 +12869,13 @@ def test_get_service_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_get_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_get_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_get_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.GetServiceRequest.pb(metastore.GetServiceRequest()) transcode.return_value = { "method": "post", @@ -12839,6 +12897,7 @@ def test_get_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.Service() + post_with_metadata.return_value = metastore.Service(), metadata client.get_service( request, @@ -12850,6 +12909,7 @@ def test_get_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_service_rest_bad_request(request_type=metastore.CreateServiceRequest): @@ -13061,10 +13121,13 @@ def test_create_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_create_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_create_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_create_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.CreateServiceRequest.pb(metastore.CreateServiceRequest()) transcode.return_value = { "method": "post", @@ -13086,6 +13149,7 @@ def test_create_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_service( request, @@ -13097,6 +13161,7 @@ def test_create_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_service_rest_bad_request(request_type=metastore.UpdateServiceRequest): @@ -13312,10 +13377,13 @@ def test_update_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_update_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_update_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_update_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.UpdateServiceRequest.pb(metastore.UpdateServiceRequest()) transcode.return_value = { "method": "post", @@ -13337,6 +13405,7 @@ def test_update_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_service( request, @@ -13348,6 +13417,7 @@ def test_update_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_service_rest_bad_request(request_type=metastore.DeleteServiceRequest): @@ -13426,10 +13496,13 @@ def test_delete_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_delete_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_delete_service_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_delete_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.DeleteServiceRequest.pb(metastore.DeleteServiceRequest()) transcode.return_value = { "method": "post", @@ -13451,6 +13524,7 @@ def test_delete_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_service( request, @@ -13462,6 +13536,7 @@ def test_delete_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_metadata_imports_rest_bad_request( @@ -13548,10 +13623,14 @@ def test_list_metadata_imports_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_list_metadata_imports" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_list_metadata_imports_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_list_metadata_imports" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ListMetadataImportsRequest.pb( metastore.ListMetadataImportsRequest() ) @@ -13577,6 +13656,10 @@ def test_list_metadata_imports_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.ListMetadataImportsResponse() + post_with_metadata.return_value = ( + metastore.ListMetadataImportsResponse(), + metadata, + ) client.list_metadata_imports( request, @@ -13588,6 +13671,7 @@ def test_list_metadata_imports_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_metadata_import_rest_bad_request( @@ -13680,10 +13764,14 @@ def test_get_metadata_import_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_get_metadata_import" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_get_metadata_import_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_get_metadata_import" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.GetMetadataImportRequest.pb( metastore.GetMetadataImportRequest() ) @@ -13707,6 +13795,7 @@ def test_get_metadata_import_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.MetadataImport() + post_with_metadata.return_value = metastore.MetadataImport(), metadata client.get_metadata_import( request, @@ -13718,6 +13807,7 @@ def test_get_metadata_import_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_metadata_import_rest_bad_request( @@ -13879,10 +13969,14 @@ def test_create_metadata_import_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_create_metadata_import" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_create_metadata_import_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_create_metadata_import" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.CreateMetadataImportRequest.pb( metastore.CreateMetadataImportRequest() ) @@ -13906,6 +14000,7 @@ def test_create_metadata_import_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_metadata_import( request, @@ -13917,6 +14012,7 @@ def test_create_metadata_import_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_metadata_import_rest_bad_request( @@ -14086,10 +14182,14 @@ def test_update_metadata_import_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_update_metadata_import" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_update_metadata_import_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_update_metadata_import" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.UpdateMetadataImportRequest.pb( metastore.UpdateMetadataImportRequest() ) @@ -14113,6 +14213,7 @@ def test_update_metadata_import_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_metadata_import( request, @@ -14124,6 +14225,7 @@ def test_update_metadata_import_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_metadata_rest_bad_request(request_type=metastore.ExportMetadataRequest): @@ -14202,10 +14304,14 @@ def test_export_metadata_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_export_metadata" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_export_metadata_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_export_metadata" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ExportMetadataRequest.pb( metastore.ExportMetadataRequest() ) @@ -14229,6 +14335,7 @@ def test_export_metadata_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_metadata( request, @@ -14240,6 +14347,7 @@ def test_export_metadata_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_restore_service_rest_bad_request(request_type=metastore.RestoreServiceRequest): @@ -14318,10 +14426,14 @@ def test_restore_service_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_restore_service" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_restore_service_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_restore_service" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.RestoreServiceRequest.pb( metastore.RestoreServiceRequest() ) @@ -14345,6 +14457,7 @@ def test_restore_service_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.restore_service( request, @@ -14356,6 +14469,7 @@ def test_restore_service_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_backups_rest_bad_request(request_type=metastore.ListBackupsRequest): @@ -14440,10 +14554,13 @@ def test_list_backups_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_list_backups" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_list_backups_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_list_backups" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.ListBackupsRequest.pb(metastore.ListBackupsRequest()) transcode.return_value = { "method": "post", @@ -14467,6 +14584,7 @@ def test_list_backups_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.ListBackupsResponse() + post_with_metadata.return_value = metastore.ListBackupsResponse(), metadata client.list_backups( request, @@ -14478,6 +14596,7 @@ def test_list_backups_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_backup_rest_bad_request(request_type=metastore.GetBackupRequest): @@ -14570,10 +14689,13 @@ def test_get_backup_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_get_backup" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_get_backup_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_get_backup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.GetBackupRequest.pb(metastore.GetBackupRequest()) transcode.return_value = { "method": "post", @@ -14595,6 +14717,7 @@ def test_get_backup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.Backup() + post_with_metadata.return_value = metastore.Backup(), metadata client.get_backup( request, @@ -14606,6 +14729,7 @@ def test_get_backup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_backup_rest_bad_request(request_type=metastore.CreateBackupRequest): @@ -14828,10 +14952,13 @@ def test_create_backup_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_create_backup" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_create_backup_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_create_backup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.CreateBackupRequest.pb(metastore.CreateBackupRequest()) transcode.return_value = { "method": "post", @@ -14853,6 +14980,7 @@ def test_create_backup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_backup( request, @@ -14864,6 +14992,7 @@ def test_create_backup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_backup_rest_bad_request(request_type=metastore.DeleteBackupRequest): @@ -14946,10 +15075,13 @@ def test_delete_backup_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_delete_backup" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_delete_backup_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_delete_backup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.DeleteBackupRequest.pb(metastore.DeleteBackupRequest()) transcode.return_value = { "method": "post", @@ -14971,6 +15103,7 @@ def test_delete_backup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_backup( request, @@ -14982,6 +15115,7 @@ def test_delete_backup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_remove_iam_policy_rest_bad_request( @@ -15070,10 +15204,14 @@ def test_remove_iam_policy_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_remove_iam_policy" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_remove_iam_policy_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_remove_iam_policy" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.RemoveIamPolicyRequest.pb( metastore.RemoveIamPolicyRequest() ) @@ -15099,6 +15237,7 @@ def test_remove_iam_policy_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore.RemoveIamPolicyResponse() + post_with_metadata.return_value = metastore.RemoveIamPolicyResponse(), metadata client.remove_iam_policy( request, @@ -15110,6 +15249,7 @@ def test_remove_iam_policy_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_query_metadata_rest_bad_request(request_type=metastore.QueryMetadataRequest): @@ -15188,10 +15328,13 @@ def test_query_metadata_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_query_metadata" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, "post_query_metadata_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_query_metadata" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.QueryMetadataRequest.pb(metastore.QueryMetadataRequest()) transcode.return_value = { "method": "post", @@ -15213,6 +15356,7 @@ def test_query_metadata_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.query_metadata( request, @@ -15224,6 +15368,7 @@ def test_query_metadata_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_move_table_to_database_rest_bad_request( @@ -15304,10 +15449,14 @@ def test_move_table_to_database_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreRestInterceptor, "post_move_table_to_database" ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_move_table_to_database_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_move_table_to_database" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.MoveTableToDatabaseRequest.pb( metastore.MoveTableToDatabaseRequest() ) @@ -15331,6 +15480,7 @@ def test_move_table_to_database_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.move_table_to_database( request, @@ -15342,6 +15492,7 @@ def test_move_table_to_database_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_alter_metadata_resource_location_rest_bad_request( @@ -15423,11 +15574,15 @@ def test_alter_metadata_resource_location_rest_interceptors(null_interceptor): transports.DataprocMetastoreRestInterceptor, "post_alter_metadata_resource_location", ) as post, mock.patch.object( + transports.DataprocMetastoreRestInterceptor, + "post_alter_metadata_resource_location_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreRestInterceptor, "pre_alter_metadata_resource_location", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore.AlterMetadataResourceLocationRequest.pb( metastore.AlterMetadataResourceLocationRequest() ) @@ -15451,6 +15606,7 @@ def test_alter_metadata_resource_location_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.alter_metadata_resource_location( request, @@ -15462,6 +15618,7 @@ def test_alter_metadata_resource_location_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1beta/test_dataproc_metastore_federation.py b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1beta/test_dataproc_metastore_federation.py index a37404d5f243..d62df1ff4835 100644 --- a/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1beta/test_dataproc_metastore_federation.py +++ b/packages/google-cloud-dataproc-metastore/tests/unit/gapic/metastore_v1beta/test_dataproc_metastore_federation.py @@ -77,6 +77,13 @@ ) from google.cloud.metastore_v1beta.types import metastore, metastore_federation +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -360,6 +367,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataprocMetastoreFederationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataprocMetastoreFederationClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4606,10 +4656,14 @@ def test_list_federations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_list_federations" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_list_federations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_list_federations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.ListFederationsRequest.pb( metastore_federation.ListFederationsRequest() ) @@ -4635,6 +4689,10 @@ def test_list_federations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore_federation.ListFederationsResponse() + post_with_metadata.return_value = ( + metastore_federation.ListFederationsResponse(), + metadata, + ) client.list_federations( request, @@ -4646,6 +4704,7 @@ def test_list_federations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_federation_rest_bad_request( @@ -4740,10 +4799,14 @@ def test_get_federation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_get_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_get_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_get_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.GetFederationRequest.pb( metastore_federation.GetFederationRequest() ) @@ -4769,6 +4832,7 @@ def test_get_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = metastore_federation.Federation() + post_with_metadata.return_value = metastore_federation.Federation(), metadata client.get_federation( request, @@ -4780,6 +4844,7 @@ def test_get_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_federation_rest_bad_request( @@ -4939,10 +5004,14 @@ def test_create_federation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_create_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_create_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_create_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.CreateFederationRequest.pb( metastore_federation.CreateFederationRequest() ) @@ -4966,6 +5035,7 @@ def test_create_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_federation( request, @@ -4977,6 +5047,7 @@ def test_create_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_federation_rest_bad_request( @@ -5140,10 +5211,14 @@ def test_update_federation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_update_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_update_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_update_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.UpdateFederationRequest.pb( metastore_federation.UpdateFederationRequest() ) @@ -5167,6 +5242,7 @@ def test_update_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_federation( request, @@ -5178,6 +5254,7 @@ def test_update_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_federation_rest_bad_request( @@ -5258,10 +5335,14 @@ def test_delete_federation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "post_delete_federation" ) as post, mock.patch.object( + transports.DataprocMetastoreFederationRestInterceptor, + "post_delete_federation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataprocMetastoreFederationRestInterceptor, "pre_delete_federation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = metastore_federation.DeleteFederationRequest.pb( metastore_federation.DeleteFederationRequest() ) @@ -5285,6 +5366,7 @@ def test_delete_federation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_federation( request, @@ -5296,6 +5378,7 @@ def test_delete_federation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc/gapic_version.py b/packages/google-cloud-dataproc/google/cloud/dataproc/gapic_version.py index ae9c1a794e9e..558c8aab67c5 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc/gapic_version.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "5.16.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/gapic_version.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/gapic_version.py index ae9c1a794e9e..558c8aab67c5 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/gapic_version.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "5.16.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/autoscaling_policy_service/client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/autoscaling_policy_service/client.py index 35592336fce0..bb440a591fbd 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/autoscaling_policy_service/client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/autoscaling_policy_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -492,6 +494,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1371,16 +1400,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1426,16 +1459,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -1658,16 +1695,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1780,16 +1821,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -1840,16 +1885,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/autoscaling_policy_service/transports/rest.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/autoscaling_policy_service/transports/rest.py index 5368c32fcf8f..e0a8198ddf7f 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/autoscaling_policy_service/transports/rest.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/autoscaling_policy_service/transports/rest.py @@ -134,12 +134,37 @@ def post_create_autoscaling_policy( ) -> autoscaling_policies.AutoscalingPolicy: """Post-rpc interceptor for create_autoscaling_policy - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_autoscaling_policy_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AutoscalingPolicyService server but before - it is returned to user code. + it is returned to user code. This `post_create_autoscaling_policy` interceptor runs + before the `post_create_autoscaling_policy_with_metadata` interceptor. """ return response + def post_create_autoscaling_policy_with_metadata( + self, + response: autoscaling_policies.AutoscalingPolicy, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + autoscaling_policies.AutoscalingPolicy, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_autoscaling_policy + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AutoscalingPolicyService server but before it is returned to user code. + + We recommend only using this `post_create_autoscaling_policy_with_metadata` + interceptor in new development instead of the `post_create_autoscaling_policy` interceptor. + When both interceptors are used, this `post_create_autoscaling_policy_with_metadata` interceptor runs after the + `post_create_autoscaling_policy` interceptor. The (possibly modified) response returned by + `post_create_autoscaling_policy` will be passed to + `post_create_autoscaling_policy_with_metadata`. + """ + return response, metadata + def pre_delete_autoscaling_policy( self, request: autoscaling_policies.DeleteAutoscalingPolicyRequest, @@ -175,12 +200,37 @@ def post_get_autoscaling_policy( ) -> autoscaling_policies.AutoscalingPolicy: """Post-rpc interceptor for get_autoscaling_policy - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_autoscaling_policy_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AutoscalingPolicyService server but before - it is returned to user code. + it is returned to user code. This `post_get_autoscaling_policy` interceptor runs + before the `post_get_autoscaling_policy_with_metadata` interceptor. """ return response + def post_get_autoscaling_policy_with_metadata( + self, + response: autoscaling_policies.AutoscalingPolicy, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + autoscaling_policies.AutoscalingPolicy, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_autoscaling_policy + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AutoscalingPolicyService server but before it is returned to user code. + + We recommend only using this `post_get_autoscaling_policy_with_metadata` + interceptor in new development instead of the `post_get_autoscaling_policy` interceptor. + When both interceptors are used, this `post_get_autoscaling_policy_with_metadata` interceptor runs after the + `post_get_autoscaling_policy` interceptor. The (possibly modified) response returned by + `post_get_autoscaling_policy` will be passed to + `post_get_autoscaling_policy_with_metadata`. + """ + return response, metadata + def pre_list_autoscaling_policies( self, request: autoscaling_policies.ListAutoscalingPoliciesRequest, @@ -201,12 +251,38 @@ def post_list_autoscaling_policies( ) -> autoscaling_policies.ListAutoscalingPoliciesResponse: """Post-rpc interceptor for list_autoscaling_policies - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_autoscaling_policies_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AutoscalingPolicyService server but before - it is returned to user code. + it is returned to user code. This `post_list_autoscaling_policies` interceptor runs + before the `post_list_autoscaling_policies_with_metadata` interceptor. """ return response + def post_list_autoscaling_policies_with_metadata( + self, + response: autoscaling_policies.ListAutoscalingPoliciesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + autoscaling_policies.ListAutoscalingPoliciesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_autoscaling_policies + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AutoscalingPolicyService server but before it is returned to user code. + + We recommend only using this `post_list_autoscaling_policies_with_metadata` + interceptor in new development instead of the `post_list_autoscaling_policies` interceptor. + When both interceptors are used, this `post_list_autoscaling_policies_with_metadata` interceptor runs after the + `post_list_autoscaling_policies` interceptor. The (possibly modified) response returned by + `post_list_autoscaling_policies` will be passed to + `post_list_autoscaling_policies_with_metadata`. + """ + return response, metadata + def pre_update_autoscaling_policy( self, request: autoscaling_policies.UpdateAutoscalingPolicyRequest, @@ -227,12 +303,37 @@ def post_update_autoscaling_policy( ) -> autoscaling_policies.AutoscalingPolicy: """Post-rpc interceptor for update_autoscaling_policy - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_autoscaling_policy_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AutoscalingPolicyService server but before - it is returned to user code. + it is returned to user code. This `post_update_autoscaling_policy` interceptor runs + before the `post_update_autoscaling_policy_with_metadata` interceptor. """ return response + def post_update_autoscaling_policy_with_metadata( + self, + response: autoscaling_policies.AutoscalingPolicy, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + autoscaling_policies.AutoscalingPolicy, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_autoscaling_policy + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AutoscalingPolicyService server but before it is returned to user code. + + We recommend only using this `post_update_autoscaling_policy_with_metadata` + interceptor in new development instead of the `post_update_autoscaling_policy` interceptor. + When both interceptors are used, this `post_update_autoscaling_policy_with_metadata` interceptor runs after the + `post_update_autoscaling_policy` interceptor. The (possibly modified) response returned by + `post_update_autoscaling_policy` will be passed to + `post_update_autoscaling_policy_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, @@ -618,6 +719,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_autoscaling_policy(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_autoscaling_policy_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -878,6 +983,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_autoscaling_policy(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_autoscaling_policy_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1026,6 +1135,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_autoscaling_policies(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_autoscaling_policies_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1182,6 +1295,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_autoscaling_policy(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_autoscaling_policy_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/batch_controller/client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/batch_controller/client.py index 11a6a8ff080e..ed6668f3d44f 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/batch_controller/client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/batch_controller/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -515,6 +517,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1236,16 +1265,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1291,16 +1324,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -1523,16 +1560,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1645,16 +1686,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -1705,16 +1750,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/batch_controller/transports/rest.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/batch_controller/transports/rest.py index b9d59a6f4f5a..f5409f69a8c1 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/batch_controller/transports/rest.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/batch_controller/transports/rest.py @@ -123,12 +123,35 @@ def post_create_batch( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_batch - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_batch_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the BatchController server but before - it is returned to user code. + it is returned to user code. This `post_create_batch` interceptor runs + before the `post_create_batch_with_metadata` interceptor. """ return response + def post_create_batch_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_batch + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the BatchController server but before it is returned to user code. + + We recommend only using this `post_create_batch_with_metadata` + interceptor in new development instead of the `post_create_batch` interceptor. + When both interceptors are used, this `post_create_batch_with_metadata` interceptor runs after the + `post_create_batch` interceptor. The (possibly modified) response returned by + `post_create_batch` will be passed to + `post_create_batch_with_metadata`. + """ + return response, metadata + def pre_delete_batch( self, request: batches.DeleteBatchRequest, @@ -156,12 +179,33 @@ def pre_get_batch( def post_get_batch(self, response: batches.Batch) -> batches.Batch: """Post-rpc interceptor for get_batch - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_batch_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the BatchController server but before - it is returned to user code. + it is returned to user code. This `post_get_batch` interceptor runs + before the `post_get_batch_with_metadata` interceptor. """ return response + def post_get_batch_with_metadata( + self, response: batches.Batch, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[batches.Batch, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_batch + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the BatchController server but before it is returned to user code. + + We recommend only using this `post_get_batch_with_metadata` + interceptor in new development instead of the `post_get_batch` interceptor. + When both interceptors are used, this `post_get_batch_with_metadata` interceptor runs after the + `post_get_batch` interceptor. The (possibly modified) response returned by + `post_get_batch` will be passed to + `post_get_batch_with_metadata`. + """ + return response, metadata + def pre_list_batches( self, request: batches.ListBatchesRequest, @@ -179,12 +223,35 @@ def post_list_batches( ) -> batches.ListBatchesResponse: """Post-rpc interceptor for list_batches - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_batches_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the BatchController server but before - it is returned to user code. + it is returned to user code. This `post_list_batches` interceptor runs + before the `post_list_batches_with_metadata` interceptor. """ return response + def post_list_batches_with_metadata( + self, + response: batches.ListBatchesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[batches.ListBatchesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_batches + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the BatchController server but before it is returned to user code. + + We recommend only using this `post_list_batches_with_metadata` + interceptor in new development instead of the `post_list_batches` interceptor. + When both interceptors are used, this `post_list_batches_with_metadata` interceptor runs after the + `post_list_batches` interceptor. The (possibly modified) response returned by + `post_list_batches` will be passed to + `post_list_batches_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, @@ -634,6 +701,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_batch(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_batch_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -887,6 +958,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_batch(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_batch_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1028,6 +1103,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_batches(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_batches_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/cluster_controller/client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/cluster_controller/client.py index 7f772f804de9..51d1bd162595 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/cluster_controller/client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/cluster_controller/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -564,6 +566,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2033,16 +2062,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2088,16 +2121,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -2320,16 +2357,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -2442,16 +2483,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -2502,16 +2547,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/cluster_controller/transports/rest.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/cluster_controller/transports/rest.py index 0f4f79dbd767..1ca2319a7c40 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/cluster_controller/transports/rest.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/cluster_controller/transports/rest.py @@ -158,12 +158,35 @@ def post_create_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ClusterController server but before - it is returned to user code. + it is returned to user code. This `post_create_cluster` interceptor runs + before the `post_create_cluster_with_metadata` interceptor. """ return response + def post_create_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ClusterController server but before it is returned to user code. + + We recommend only using this `post_create_cluster_with_metadata` + interceptor in new development instead of the `post_create_cluster` interceptor. + When both interceptors are used, this `post_create_cluster_with_metadata` interceptor runs after the + `post_create_cluster` interceptor. The (possibly modified) response returned by + `post_create_cluster` will be passed to + `post_create_cluster_with_metadata`. + """ + return response, metadata + def pre_delete_cluster( self, request: clusters.DeleteClusterRequest, @@ -181,12 +204,35 @@ def post_delete_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ClusterController server but before - it is returned to user code. + it is returned to user code. This `post_delete_cluster` interceptor runs + before the `post_delete_cluster_with_metadata` interceptor. """ return response + def post_delete_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ClusterController server but before it is returned to user code. + + We recommend only using this `post_delete_cluster_with_metadata` + interceptor in new development instead of the `post_delete_cluster` interceptor. + When both interceptors are used, this `post_delete_cluster_with_metadata` interceptor runs after the + `post_delete_cluster` interceptor. The (possibly modified) response returned by + `post_delete_cluster` will be passed to + `post_delete_cluster_with_metadata`. + """ + return response, metadata + def pre_diagnose_cluster( self, request: clusters.DiagnoseClusterRequest, @@ -206,12 +252,35 @@ def post_diagnose_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for diagnose_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_diagnose_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ClusterController server but before - it is returned to user code. + it is returned to user code. This `post_diagnose_cluster` interceptor runs + before the `post_diagnose_cluster_with_metadata` interceptor. """ return response + def post_diagnose_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for diagnose_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ClusterController server but before it is returned to user code. + + We recommend only using this `post_diagnose_cluster_with_metadata` + interceptor in new development instead of the `post_diagnose_cluster` interceptor. + When both interceptors are used, this `post_diagnose_cluster_with_metadata` interceptor runs after the + `post_diagnose_cluster` interceptor. The (possibly modified) response returned by + `post_diagnose_cluster` will be passed to + `post_diagnose_cluster_with_metadata`. + """ + return response, metadata + def pre_get_cluster( self, request: clusters.GetClusterRequest, @@ -227,12 +296,35 @@ def pre_get_cluster( def post_get_cluster(self, response: clusters.Cluster) -> clusters.Cluster: """Post-rpc interceptor for get_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ClusterController server but before - it is returned to user code. + it is returned to user code. This `post_get_cluster` interceptor runs + before the `post_get_cluster_with_metadata` interceptor. """ return response + def post_get_cluster_with_metadata( + self, + response: clusters.Cluster, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[clusters.Cluster, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ClusterController server but before it is returned to user code. + + We recommend only using this `post_get_cluster_with_metadata` + interceptor in new development instead of the `post_get_cluster` interceptor. + When both interceptors are used, this `post_get_cluster_with_metadata` interceptor runs after the + `post_get_cluster` interceptor. The (possibly modified) response returned by + `post_get_cluster` will be passed to + `post_get_cluster_with_metadata`. + """ + return response, metadata + def pre_list_clusters( self, request: clusters.ListClustersRequest, @@ -250,12 +342,35 @@ def post_list_clusters( ) -> clusters.ListClustersResponse: """Post-rpc interceptor for list_clusters - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_clusters_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ClusterController server but before - it is returned to user code. + it is returned to user code. This `post_list_clusters` interceptor runs + before the `post_list_clusters_with_metadata` interceptor. """ return response + def post_list_clusters_with_metadata( + self, + response: clusters.ListClustersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[clusters.ListClustersResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_clusters + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ClusterController server but before it is returned to user code. + + We recommend only using this `post_list_clusters_with_metadata` + interceptor in new development instead of the `post_list_clusters` interceptor. + When both interceptors are used, this `post_list_clusters_with_metadata` interceptor runs after the + `post_list_clusters` interceptor. The (possibly modified) response returned by + `post_list_clusters` will be passed to + `post_list_clusters_with_metadata`. + """ + return response, metadata + def pre_start_cluster( self, request: clusters.StartClusterRequest, @@ -273,12 +388,35 @@ def post_start_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for start_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_start_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ClusterController server but before - it is returned to user code. + it is returned to user code. This `post_start_cluster` interceptor runs + before the `post_start_cluster_with_metadata` interceptor. """ return response + def post_start_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for start_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ClusterController server but before it is returned to user code. + + We recommend only using this `post_start_cluster_with_metadata` + interceptor in new development instead of the `post_start_cluster` interceptor. + When both interceptors are used, this `post_start_cluster_with_metadata` interceptor runs after the + `post_start_cluster` interceptor. The (possibly modified) response returned by + `post_start_cluster` will be passed to + `post_start_cluster_with_metadata`. + """ + return response, metadata + def pre_stop_cluster( self, request: clusters.StopClusterRequest, @@ -296,12 +434,35 @@ def post_stop_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for stop_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_stop_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ClusterController server but before - it is returned to user code. + it is returned to user code. This `post_stop_cluster` interceptor runs + before the `post_stop_cluster_with_metadata` interceptor. """ return response + def post_stop_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for stop_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ClusterController server but before it is returned to user code. + + We recommend only using this `post_stop_cluster_with_metadata` + interceptor in new development instead of the `post_stop_cluster` interceptor. + When both interceptors are used, this `post_stop_cluster_with_metadata` interceptor runs after the + `post_stop_cluster` interceptor. The (possibly modified) response returned by + `post_stop_cluster` will be passed to + `post_stop_cluster_with_metadata`. + """ + return response, metadata + def pre_update_cluster( self, request: clusters.UpdateClusterRequest, @@ -319,12 +480,35 @@ def post_update_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ClusterController server but before - it is returned to user code. + it is returned to user code. This `post_update_cluster` interceptor runs + before the `post_update_cluster_with_metadata` interceptor. """ return response + def post_update_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ClusterController server but before it is returned to user code. + + We recommend only using this `post_update_cluster_with_metadata` + interceptor in new development instead of the `post_update_cluster` interceptor. + When both interceptors are used, this `post_update_cluster_with_metadata` interceptor runs after the + `post_update_cluster` interceptor. The (possibly modified) response returned by + `post_update_cluster` will be passed to + `post_update_cluster_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, @@ -775,6 +959,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -917,6 +1105,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1068,6 +1260,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_diagnose_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_diagnose_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1213,6 +1409,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1356,6 +1556,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_clusters(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_clusters_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1503,6 +1707,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_start_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_start_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1650,6 +1858,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_stop_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_stop_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1798,6 +2010,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/client.py index d635c5aa83d8..f53e0998ffd4 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -466,6 +468,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1639,16 +1668,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1694,16 +1727,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -1926,16 +1963,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -2048,16 +2089,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -2108,16 +2153,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/transports/rest.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/transports/rest.py index caf87e6364a7..3137961c022c 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/transports/rest.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/job_controller/transports/rest.py @@ -145,12 +145,33 @@ def pre_cancel_job( def post_cancel_job(self, response: jobs.Job) -> jobs.Job: """Post-rpc interceptor for cancel_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_cancel_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobController server but before - it is returned to user code. + it is returned to user code. This `post_cancel_job` interceptor runs + before the `post_cancel_job_with_metadata` interceptor. """ return response + def post_cancel_job_with_metadata( + self, response: jobs.Job, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[jobs.Job, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for cancel_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobController server but before it is returned to user code. + + We recommend only using this `post_cancel_job_with_metadata` + interceptor in new development instead of the `post_cancel_job` interceptor. + When both interceptors are used, this `post_cancel_job_with_metadata` interceptor runs after the + `post_cancel_job` interceptor. The (possibly modified) response returned by + `post_cancel_job` will be passed to + `post_cancel_job_with_metadata`. + """ + return response, metadata + def pre_delete_job( self, request: jobs.DeleteJobRequest, @@ -178,12 +199,33 @@ def pre_get_job( def post_get_job(self, response: jobs.Job) -> jobs.Job: """Post-rpc interceptor for get_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobController server but before - it is returned to user code. + it is returned to user code. This `post_get_job` interceptor runs + before the `post_get_job_with_metadata` interceptor. """ return response + def post_get_job_with_metadata( + self, response: jobs.Job, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[jobs.Job, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobController server but before it is returned to user code. + + We recommend only using this `post_get_job_with_metadata` + interceptor in new development instead of the `post_get_job` interceptor. + When both interceptors are used, this `post_get_job_with_metadata` interceptor runs after the + `post_get_job` interceptor. The (possibly modified) response returned by + `post_get_job` will be passed to + `post_get_job_with_metadata`. + """ + return response, metadata + def pre_list_jobs( self, request: jobs.ListJobsRequest, @@ -199,12 +241,35 @@ def pre_list_jobs( def post_list_jobs(self, response: jobs.ListJobsResponse) -> jobs.ListJobsResponse: """Post-rpc interceptor for list_jobs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_jobs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobController server but before - it is returned to user code. + it is returned to user code. This `post_list_jobs` interceptor runs + before the `post_list_jobs_with_metadata` interceptor. """ return response + def post_list_jobs_with_metadata( + self, + response: jobs.ListJobsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[jobs.ListJobsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_jobs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobController server but before it is returned to user code. + + We recommend only using this `post_list_jobs_with_metadata` + interceptor in new development instead of the `post_list_jobs` interceptor. + When both interceptors are used, this `post_list_jobs_with_metadata` interceptor runs after the + `post_list_jobs` interceptor. The (possibly modified) response returned by + `post_list_jobs` will be passed to + `post_list_jobs_with_metadata`. + """ + return response, metadata + def pre_submit_job( self, request: jobs.SubmitJobRequest, @@ -220,12 +285,33 @@ def pre_submit_job( def post_submit_job(self, response: jobs.Job) -> jobs.Job: """Post-rpc interceptor for submit_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_submit_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobController server but before - it is returned to user code. + it is returned to user code. This `post_submit_job` interceptor runs + before the `post_submit_job_with_metadata` interceptor. """ return response + def post_submit_job_with_metadata( + self, response: jobs.Job, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[jobs.Job, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for submit_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobController server but before it is returned to user code. + + We recommend only using this `post_submit_job_with_metadata` + interceptor in new development instead of the `post_submit_job` interceptor. + When both interceptors are used, this `post_submit_job_with_metadata` interceptor runs after the + `post_submit_job` interceptor. The (possibly modified) response returned by + `post_submit_job` will be passed to + `post_submit_job_with_metadata`. + """ + return response, metadata + def pre_submit_job_as_operation( self, request: jobs.SubmitJobRequest, @@ -243,12 +329,35 @@ def post_submit_job_as_operation( ) -> operations_pb2.Operation: """Post-rpc interceptor for submit_job_as_operation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_submit_job_as_operation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobController server but before - it is returned to user code. + it is returned to user code. This `post_submit_job_as_operation` interceptor runs + before the `post_submit_job_as_operation_with_metadata` interceptor. """ return response + def post_submit_job_as_operation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for submit_job_as_operation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobController server but before it is returned to user code. + + We recommend only using this `post_submit_job_as_operation_with_metadata` + interceptor in new development instead of the `post_submit_job_as_operation` interceptor. + When both interceptors are used, this `post_submit_job_as_operation_with_metadata` interceptor runs after the + `post_submit_job_as_operation` interceptor. The (possibly modified) response returned by + `post_submit_job_as_operation` will be passed to + `post_submit_job_as_operation_with_metadata`. + """ + return response, metadata + def pre_update_job( self, request: jobs.UpdateJobRequest, @@ -264,12 +373,33 @@ def pre_update_job( def post_update_job(self, response: jobs.Job) -> jobs.Job: """Post-rpc interceptor for update_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the JobController server but before - it is returned to user code. + it is returned to user code. This `post_update_job` interceptor runs + before the `post_update_job_with_metadata` interceptor. """ return response + def post_update_job_with_metadata( + self, response: jobs.Job, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[jobs.Job, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the JobController server but before it is returned to user code. + + We recommend only using this `post_update_job_with_metadata` + interceptor in new development instead of the `post_update_job` interceptor. + When both interceptors are used, this `post_update_job_with_metadata` interceptor runs after the + `post_update_job` interceptor. The (possibly modified) response returned by + `post_update_job` will be passed to + `post_update_job_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, @@ -723,6 +853,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_cancel_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_cancel_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -976,6 +1110,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1120,6 +1258,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_jobs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_jobs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1272,6 +1414,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_submit_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_submit_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1421,6 +1567,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_submit_job_as_operation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_submit_job_as_operation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1573,6 +1723,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/node_group_controller/client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/node_group_controller/client.py index 16f48142eb9a..5c08ef818030 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/node_group_controller/client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/node_group_controller/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -493,6 +495,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1148,16 +1177,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1203,16 +1236,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -1435,16 +1472,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1557,16 +1598,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -1617,16 +1662,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/node_group_controller/transports/rest.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/node_group_controller/transports/rest.py index 50d0d98b4649..516f05afd6b0 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/node_group_controller/transports/rest.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/node_group_controller/transports/rest.py @@ -120,12 +120,35 @@ def post_create_node_group( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_node_group - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_node_group_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the NodeGroupController server but before - it is returned to user code. + it is returned to user code. This `post_create_node_group` interceptor runs + before the `post_create_node_group_with_metadata` interceptor. """ return response + def post_create_node_group_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_node_group + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the NodeGroupController server but before it is returned to user code. + + We recommend only using this `post_create_node_group_with_metadata` + interceptor in new development instead of the `post_create_node_group` interceptor. + When both interceptors are used, this `post_create_node_group_with_metadata` interceptor runs after the + `post_create_node_group` interceptor. The (possibly modified) response returned by + `post_create_node_group` will be passed to + `post_create_node_group_with_metadata`. + """ + return response, metadata + def pre_get_node_group( self, request: node_groups.GetNodeGroupRequest, @@ -143,12 +166,35 @@ def pre_get_node_group( def post_get_node_group(self, response: clusters.NodeGroup) -> clusters.NodeGroup: """Post-rpc interceptor for get_node_group - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_node_group_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the NodeGroupController server but before - it is returned to user code. + it is returned to user code. This `post_get_node_group` interceptor runs + before the `post_get_node_group_with_metadata` interceptor. """ return response + def post_get_node_group_with_metadata( + self, + response: clusters.NodeGroup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[clusters.NodeGroup, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_node_group + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the NodeGroupController server but before it is returned to user code. + + We recommend only using this `post_get_node_group_with_metadata` + interceptor in new development instead of the `post_get_node_group` interceptor. + When both interceptors are used, this `post_get_node_group_with_metadata` interceptor runs after the + `post_get_node_group` interceptor. The (possibly modified) response returned by + `post_get_node_group` will be passed to + `post_get_node_group_with_metadata`. + """ + return response, metadata + def pre_resize_node_group( self, request: node_groups.ResizeNodeGroupRequest, @@ -168,12 +214,35 @@ def post_resize_node_group( ) -> operations_pb2.Operation: """Post-rpc interceptor for resize_node_group - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_resize_node_group_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the NodeGroupController server but before - it is returned to user code. + it is returned to user code. This `post_resize_node_group` interceptor runs + before the `post_resize_node_group_with_metadata` interceptor. """ return response + def post_resize_node_group_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for resize_node_group + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the NodeGroupController server but before it is returned to user code. + + We recommend only using this `post_resize_node_group_with_metadata` + interceptor in new development instead of the `post_resize_node_group` interceptor. + When both interceptors are used, this `post_resize_node_group_with_metadata` interceptor runs after the + `post_resize_node_group` interceptor. The (possibly modified) response returned by + `post_resize_node_group` will be passed to + `post_resize_node_group_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, @@ -626,6 +695,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_node_group(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_node_group_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -771,6 +844,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_node_group(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_node_group_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -921,6 +998,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_resize_node_group(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_resize_node_group_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_controller/client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_controller/client.py index eb72e4000be9..85a3cde3169d 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_controller/client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_controller/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -537,6 +539,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1407,16 +1436,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1462,16 +1495,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -1694,16 +1731,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1816,16 +1857,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -1876,16 +1921,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_controller/transports/rest.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_controller/transports/rest.py index 7da55caf4d68..faf081e98f82 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_controller/transports/rest.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_controller/transports/rest.py @@ -134,12 +134,35 @@ def post_create_session( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionController server but before - it is returned to user code. + it is returned to user code. This `post_create_session` interceptor runs + before the `post_create_session_with_metadata` interceptor. """ return response + def post_create_session_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionController server but before it is returned to user code. + + We recommend only using this `post_create_session_with_metadata` + interceptor in new development instead of the `post_create_session` interceptor. + When both interceptors are used, this `post_create_session_with_metadata` interceptor runs after the + `post_create_session` interceptor. The (possibly modified) response returned by + `post_create_session` will be passed to + `post_create_session_with_metadata`. + """ + return response, metadata + def pre_delete_session( self, request: sessions.DeleteSessionRequest, @@ -157,12 +180,35 @@ def post_delete_session( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionController server but before - it is returned to user code. + it is returned to user code. This `post_delete_session` interceptor runs + before the `post_delete_session_with_metadata` interceptor. """ return response + def post_delete_session_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionController server but before it is returned to user code. + + We recommend only using this `post_delete_session_with_metadata` + interceptor in new development instead of the `post_delete_session` interceptor. + When both interceptors are used, this `post_delete_session_with_metadata` interceptor runs after the + `post_delete_session` interceptor. The (possibly modified) response returned by + `post_delete_session` will be passed to + `post_delete_session_with_metadata`. + """ + return response, metadata + def pre_get_session( self, request: sessions.GetSessionRequest, @@ -178,12 +224,35 @@ def pre_get_session( def post_get_session(self, response: sessions.Session) -> sessions.Session: """Post-rpc interceptor for get_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionController server but before - it is returned to user code. + it is returned to user code. This `post_get_session` interceptor runs + before the `post_get_session_with_metadata` interceptor. """ return response + def post_get_session_with_metadata( + self, + response: sessions.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[sessions.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionController server but before it is returned to user code. + + We recommend only using this `post_get_session_with_metadata` + interceptor in new development instead of the `post_get_session` interceptor. + When both interceptors are used, this `post_get_session_with_metadata` interceptor runs after the + `post_get_session` interceptor. The (possibly modified) response returned by + `post_get_session` will be passed to + `post_get_session_with_metadata`. + """ + return response, metadata + def pre_list_sessions( self, request: sessions.ListSessionsRequest, @@ -201,12 +270,35 @@ def post_list_sessions( ) -> sessions.ListSessionsResponse: """Post-rpc interceptor for list_sessions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_sessions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionController server but before - it is returned to user code. + it is returned to user code. This `post_list_sessions` interceptor runs + before the `post_list_sessions_with_metadata` interceptor. """ return response + def post_list_sessions_with_metadata( + self, + response: sessions.ListSessionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[sessions.ListSessionsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_sessions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionController server but before it is returned to user code. + + We recommend only using this `post_list_sessions_with_metadata` + interceptor in new development instead of the `post_list_sessions` interceptor. + When both interceptors are used, this `post_list_sessions_with_metadata` interceptor runs after the + `post_list_sessions` interceptor. The (possibly modified) response returned by + `post_list_sessions` will be passed to + `post_list_sessions_with_metadata`. + """ + return response, metadata + def pre_terminate_session( self, request: sessions.TerminateSessionRequest, @@ -226,12 +318,35 @@ def post_terminate_session( ) -> operations_pb2.Operation: """Post-rpc interceptor for terminate_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_terminate_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionController server but before - it is returned to user code. + it is returned to user code. This `post_terminate_session` interceptor runs + before the `post_terminate_session_with_metadata` interceptor. """ return response + def post_terminate_session_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for terminate_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionController server but before it is returned to user code. + + We recommend only using this `post_terminate_session_with_metadata` + interceptor in new development instead of the `post_terminate_session` interceptor. + When both interceptors are used, this `post_terminate_session_with_metadata` interceptor runs after the + `post_terminate_session` interceptor. The (possibly modified) response returned by + `post_terminate_session` will be passed to + `post_terminate_session_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, @@ -682,6 +797,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -824,6 +943,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -965,6 +1088,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1106,6 +1233,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_sessions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sessions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1257,6 +1388,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_terminate_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_terminate_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_template_controller/client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_template_controller/client.py index 700e27d8cb88..df32d216b828 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_template_controller/client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_template_controller/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -515,6 +517,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1333,16 +1362,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1388,16 +1421,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -1620,16 +1657,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -1742,16 +1783,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -1802,16 +1847,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_template_controller/transports/rest.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_template_controller/transports/rest.py index eaf6b7730a31..58c9ecfe5c05 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_template_controller/transports/rest.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/session_template_controller/transports/rest.py @@ -134,12 +134,37 @@ def post_create_session_template( ) -> session_templates.SessionTemplate: """Post-rpc interceptor for create_session_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_session_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionTemplateController server but before - it is returned to user code. + it is returned to user code. This `post_create_session_template` interceptor runs + before the `post_create_session_template_with_metadata` interceptor. """ return response + def post_create_session_template_with_metadata( + self, + response: session_templates.SessionTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_templates.SessionTemplate, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_session_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionTemplateController server but before it is returned to user code. + + We recommend only using this `post_create_session_template_with_metadata` + interceptor in new development instead of the `post_create_session_template` interceptor. + When both interceptors are used, this `post_create_session_template_with_metadata` interceptor runs after the + `post_create_session_template` interceptor. The (possibly modified) response returned by + `post_create_session_template` will be passed to + `post_create_session_template_with_metadata`. + """ + return response, metadata + def pre_delete_session_template( self, request: session_templates.DeleteSessionTemplateRequest, @@ -175,12 +200,37 @@ def post_get_session_template( ) -> session_templates.SessionTemplate: """Post-rpc interceptor for get_session_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_session_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionTemplateController server but before - it is returned to user code. + it is returned to user code. This `post_get_session_template` interceptor runs + before the `post_get_session_template_with_metadata` interceptor. """ return response + def post_get_session_template_with_metadata( + self, + response: session_templates.SessionTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_templates.SessionTemplate, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_session_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionTemplateController server but before it is returned to user code. + + We recommend only using this `post_get_session_template_with_metadata` + interceptor in new development instead of the `post_get_session_template` interceptor. + When both interceptors are used, this `post_get_session_template_with_metadata` interceptor runs after the + `post_get_session_template` interceptor. The (possibly modified) response returned by + `post_get_session_template` will be passed to + `post_get_session_template_with_metadata`. + """ + return response, metadata + def pre_list_session_templates( self, request: session_templates.ListSessionTemplatesRequest, @@ -201,12 +251,38 @@ def post_list_session_templates( ) -> session_templates.ListSessionTemplatesResponse: """Post-rpc interceptor for list_session_templates - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_session_templates_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionTemplateController server but before - it is returned to user code. + it is returned to user code. This `post_list_session_templates` interceptor runs + before the `post_list_session_templates_with_metadata` interceptor. """ return response + def post_list_session_templates_with_metadata( + self, + response: session_templates.ListSessionTemplatesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_templates.ListSessionTemplatesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_session_templates + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionTemplateController server but before it is returned to user code. + + We recommend only using this `post_list_session_templates_with_metadata` + interceptor in new development instead of the `post_list_session_templates` interceptor. + When both interceptors are used, this `post_list_session_templates_with_metadata` interceptor runs after the + `post_list_session_templates` interceptor. The (possibly modified) response returned by + `post_list_session_templates` will be passed to + `post_list_session_templates_with_metadata`. + """ + return response, metadata + def pre_update_session_template( self, request: session_templates.UpdateSessionTemplateRequest, @@ -227,12 +303,37 @@ def post_update_session_template( ) -> session_templates.SessionTemplate: """Post-rpc interceptor for update_session_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_session_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionTemplateController server but before - it is returned to user code. + it is returned to user code. This `post_update_session_template` interceptor runs + before the `post_update_session_template_with_metadata` interceptor. """ return response + def post_update_session_template_with_metadata( + self, + response: session_templates.SessionTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_templates.SessionTemplate, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_session_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionTemplateController server but before it is returned to user code. + + We recommend only using this `post_update_session_template_with_metadata` + interceptor in new development instead of the `post_update_session_template` interceptor. + When both interceptors are used, this `post_update_session_template_with_metadata` interceptor runs after the + `post_update_session_template` interceptor. The (possibly modified) response returned by + `post_update_session_template` will be passed to + `post_update_session_template_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, @@ -620,6 +721,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_session_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_session_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -878,6 +983,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_session_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_session_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1024,6 +1133,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_session_templates(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_session_templates_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1178,6 +1291,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_session_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_session_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/workflow_template_service/client.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/workflow_template_service/client.py index 5a2df2aa2e4e..9a4eac8e3138 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/workflow_template_service/client.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/workflow_template_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -567,6 +569,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1811,16 +1840,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1866,16 +1899,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -2098,16 +2135,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -2220,16 +2261,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -2280,16 +2325,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/workflow_template_service/transports/rest.py b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/workflow_template_service/transports/rest.py index 525d3c00b6d1..95397cff990d 100644 --- a/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/workflow_template_service/transports/rest.py +++ b/packages/google-cloud-dataproc/google/cloud/dataproc_v1/services/workflow_template_service/transports/rest.py @@ -150,12 +150,37 @@ def post_create_workflow_template( ) -> workflow_templates.WorkflowTemplate: """Post-rpc interceptor for create_workflow_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_workflow_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the WorkflowTemplateService server but before - it is returned to user code. + it is returned to user code. This `post_create_workflow_template` interceptor runs + before the `post_create_workflow_template_with_metadata` interceptor. """ return response + def post_create_workflow_template_with_metadata( + self, + response: workflow_templates.WorkflowTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + workflow_templates.WorkflowTemplate, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_workflow_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the WorkflowTemplateService server but before it is returned to user code. + + We recommend only using this `post_create_workflow_template_with_metadata` + interceptor in new development instead of the `post_create_workflow_template` interceptor. + When both interceptors are used, this `post_create_workflow_template_with_metadata` interceptor runs after the + `post_create_workflow_template` interceptor. The (possibly modified) response returned by + `post_create_workflow_template` will be passed to + `post_create_workflow_template_with_metadata`. + """ + return response, metadata + def pre_delete_workflow_template( self, request: workflow_templates.DeleteWorkflowTemplateRequest, @@ -191,12 +216,37 @@ def post_get_workflow_template( ) -> workflow_templates.WorkflowTemplate: """Post-rpc interceptor for get_workflow_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_workflow_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the WorkflowTemplateService server but before - it is returned to user code. + it is returned to user code. This `post_get_workflow_template` interceptor runs + before the `post_get_workflow_template_with_metadata` interceptor. """ return response + def post_get_workflow_template_with_metadata( + self, + response: workflow_templates.WorkflowTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + workflow_templates.WorkflowTemplate, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_workflow_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the WorkflowTemplateService server but before it is returned to user code. + + We recommend only using this `post_get_workflow_template_with_metadata` + interceptor in new development instead of the `post_get_workflow_template` interceptor. + When both interceptors are used, this `post_get_workflow_template_with_metadata` interceptor runs after the + `post_get_workflow_template` interceptor. The (possibly modified) response returned by + `post_get_workflow_template` will be passed to + `post_get_workflow_template_with_metadata`. + """ + return response, metadata + def pre_instantiate_inline_workflow_template( self, request: workflow_templates.InstantiateInlineWorkflowTemplateRequest, @@ -217,12 +267,35 @@ def post_instantiate_inline_workflow_template( ) -> operations_pb2.Operation: """Post-rpc interceptor for instantiate_inline_workflow_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_instantiate_inline_workflow_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the WorkflowTemplateService server but before - it is returned to user code. + it is returned to user code. This `post_instantiate_inline_workflow_template` interceptor runs + before the `post_instantiate_inline_workflow_template_with_metadata` interceptor. """ return response + def post_instantiate_inline_workflow_template_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for instantiate_inline_workflow_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the WorkflowTemplateService server but before it is returned to user code. + + We recommend only using this `post_instantiate_inline_workflow_template_with_metadata` + interceptor in new development instead of the `post_instantiate_inline_workflow_template` interceptor. + When both interceptors are used, this `post_instantiate_inline_workflow_template_with_metadata` interceptor runs after the + `post_instantiate_inline_workflow_template` interceptor. The (possibly modified) response returned by + `post_instantiate_inline_workflow_template` will be passed to + `post_instantiate_inline_workflow_template_with_metadata`. + """ + return response, metadata + def pre_instantiate_workflow_template( self, request: workflow_templates.InstantiateWorkflowTemplateRequest, @@ -243,12 +316,35 @@ def post_instantiate_workflow_template( ) -> operations_pb2.Operation: """Post-rpc interceptor for instantiate_workflow_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_instantiate_workflow_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the WorkflowTemplateService server but before - it is returned to user code. + it is returned to user code. This `post_instantiate_workflow_template` interceptor runs + before the `post_instantiate_workflow_template_with_metadata` interceptor. """ return response + def post_instantiate_workflow_template_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for instantiate_workflow_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the WorkflowTemplateService server but before it is returned to user code. + + We recommend only using this `post_instantiate_workflow_template_with_metadata` + interceptor in new development instead of the `post_instantiate_workflow_template` interceptor. + When both interceptors are used, this `post_instantiate_workflow_template_with_metadata` interceptor runs after the + `post_instantiate_workflow_template` interceptor. The (possibly modified) response returned by + `post_instantiate_workflow_template` will be passed to + `post_instantiate_workflow_template_with_metadata`. + """ + return response, metadata + def pre_list_workflow_templates( self, request: workflow_templates.ListWorkflowTemplatesRequest, @@ -269,12 +365,38 @@ def post_list_workflow_templates( ) -> workflow_templates.ListWorkflowTemplatesResponse: """Post-rpc interceptor for list_workflow_templates - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_workflow_templates_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the WorkflowTemplateService server but before - it is returned to user code. + it is returned to user code. This `post_list_workflow_templates` interceptor runs + before the `post_list_workflow_templates_with_metadata` interceptor. """ return response + def post_list_workflow_templates_with_metadata( + self, + response: workflow_templates.ListWorkflowTemplatesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + workflow_templates.ListWorkflowTemplatesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_workflow_templates + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the WorkflowTemplateService server but before it is returned to user code. + + We recommend only using this `post_list_workflow_templates_with_metadata` + interceptor in new development instead of the `post_list_workflow_templates` interceptor. + When both interceptors are used, this `post_list_workflow_templates_with_metadata` interceptor runs after the + `post_list_workflow_templates` interceptor. The (possibly modified) response returned by + `post_list_workflow_templates` will be passed to + `post_list_workflow_templates_with_metadata`. + """ + return response, metadata + def pre_update_workflow_template( self, request: workflow_templates.UpdateWorkflowTemplateRequest, @@ -295,12 +417,37 @@ def post_update_workflow_template( ) -> workflow_templates.WorkflowTemplate: """Post-rpc interceptor for update_workflow_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_workflow_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the WorkflowTemplateService server but before - it is returned to user code. + it is returned to user code. This `post_update_workflow_template` interceptor runs + before the `post_update_workflow_template_with_metadata` interceptor. """ return response + def post_update_workflow_template_with_metadata( + self, + response: workflow_templates.WorkflowTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + workflow_templates.WorkflowTemplate, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_workflow_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the WorkflowTemplateService server but before it is returned to user code. + + We recommend only using this `post_update_workflow_template_with_metadata` + interceptor in new development instead of the `post_update_workflow_template` interceptor. + When both interceptors are used, this `post_update_workflow_template_with_metadata` interceptor runs after the + `post_update_workflow_template` interceptor. The (possibly modified) response returned by + `post_update_workflow_template` will be passed to + `post_update_workflow_template_with_metadata`. + """ + return response, metadata + def pre_get_iam_policy( self, request: iam_policy_pb2.GetIamPolicyRequest, @@ -755,6 +902,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_workflow_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_workflow_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1017,6 +1168,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_workflow_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_workflow_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1176,6 +1331,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_instantiate_inline_workflow_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_instantiate_inline_workflow_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1330,6 +1492,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_instantiate_workflow_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_instantiate_workflow_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1476,6 +1645,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_workflow_templates(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_workflow_templates_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1632,6 +1805,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_workflow_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_workflow_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dataproc/samples/generated_samples/snippet_metadata_google.cloud.dataproc.v1.json b/packages/google-cloud-dataproc/samples/generated_samples/snippet_metadata_google.cloud.dataproc.v1.json index 58522e93787a..0b7171f0c4e8 100644 --- a/packages/google-cloud-dataproc/samples/generated_samples/snippet_metadata_google.cloud.dataproc.v1.json +++ b/packages/google-cloud-dataproc/samples/generated_samples/snippet_metadata_google.cloud.dataproc.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dataproc", - "version": "5.16.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_autoscaling_policy_service.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_autoscaling_policy_service.py index 72b78dd09615..4df4a9cad22c 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_autoscaling_policy_service.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_autoscaling_policy_service.py @@ -65,6 +65,13 @@ ) from google.cloud.dataproc_v1.types import autoscaling_policies +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -340,6 +347,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AutoscalingPolicyServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AutoscalingPolicyServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4633,11 +4683,15 @@ def test_create_autoscaling_policy_rest_interceptors(null_interceptor): transports.AutoscalingPolicyServiceRestInterceptor, "post_create_autoscaling_policy", ) as post, mock.patch.object( + transports.AutoscalingPolicyServiceRestInterceptor, + "post_create_autoscaling_policy_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AutoscalingPolicyServiceRestInterceptor, "pre_create_autoscaling_policy", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = autoscaling_policies.CreateAutoscalingPolicyRequest.pb( autoscaling_policies.CreateAutoscalingPolicyRequest() ) @@ -4663,6 +4717,10 @@ def test_create_autoscaling_policy_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = autoscaling_policies.AutoscalingPolicy() + post_with_metadata.return_value = ( + autoscaling_policies.AutoscalingPolicy(), + metadata, + ) client.create_autoscaling_policy( request, @@ -4674,6 +4732,7 @@ def test_create_autoscaling_policy_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_autoscaling_policy_rest_bad_request( @@ -4855,11 +4914,15 @@ def test_update_autoscaling_policy_rest_interceptors(null_interceptor): transports.AutoscalingPolicyServiceRestInterceptor, "post_update_autoscaling_policy", ) as post, mock.patch.object( + transports.AutoscalingPolicyServiceRestInterceptor, + "post_update_autoscaling_policy_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AutoscalingPolicyServiceRestInterceptor, "pre_update_autoscaling_policy", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = autoscaling_policies.UpdateAutoscalingPolicyRequest.pb( autoscaling_policies.UpdateAutoscalingPolicyRequest() ) @@ -4885,6 +4948,10 @@ def test_update_autoscaling_policy_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = autoscaling_policies.AutoscalingPolicy() + post_with_metadata.return_value = ( + autoscaling_policies.AutoscalingPolicy(), + metadata, + ) client.update_autoscaling_policy( request, @@ -4896,6 +4963,7 @@ def test_update_autoscaling_policy_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_autoscaling_policy_rest_bad_request( @@ -4987,10 +5055,14 @@ def test_get_autoscaling_policy_rest_interceptors(null_interceptor): transports.AutoscalingPolicyServiceRestInterceptor, "post_get_autoscaling_policy", ) as post, mock.patch.object( + transports.AutoscalingPolicyServiceRestInterceptor, + "post_get_autoscaling_policy_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AutoscalingPolicyServiceRestInterceptor, "pre_get_autoscaling_policy" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = autoscaling_policies.GetAutoscalingPolicyRequest.pb( autoscaling_policies.GetAutoscalingPolicyRequest() ) @@ -5016,6 +5088,10 @@ def test_get_autoscaling_policy_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = autoscaling_policies.AutoscalingPolicy() + post_with_metadata.return_value = ( + autoscaling_policies.AutoscalingPolicy(), + metadata, + ) client.get_autoscaling_policy( request, @@ -5027,6 +5103,7 @@ def test_get_autoscaling_policy_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_autoscaling_policies_rest_bad_request( @@ -5114,11 +5191,15 @@ def test_list_autoscaling_policies_rest_interceptors(null_interceptor): transports.AutoscalingPolicyServiceRestInterceptor, "post_list_autoscaling_policies", ) as post, mock.patch.object( + transports.AutoscalingPolicyServiceRestInterceptor, + "post_list_autoscaling_policies_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AutoscalingPolicyServiceRestInterceptor, "pre_list_autoscaling_policies", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = autoscaling_policies.ListAutoscalingPoliciesRequest.pb( autoscaling_policies.ListAutoscalingPoliciesRequest() ) @@ -5144,6 +5225,10 @@ def test_list_autoscaling_policies_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = autoscaling_policies.ListAutoscalingPoliciesResponse() + post_with_metadata.return_value = ( + autoscaling_policies.ListAutoscalingPoliciesResponse(), + metadata, + ) client.list_autoscaling_policies( request, @@ -5155,6 +5240,7 @@ def test_list_autoscaling_policies_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_autoscaling_policy_rest_bad_request( diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_batch_controller.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_batch_controller.py index b788edab02b0..380b9c84b9c6 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_batch_controller.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_batch_controller.py @@ -75,6 +75,13 @@ ) from google.cloud.dataproc_v1.types import batches, operations, shared +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -333,6 +340,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = BatchControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = BatchControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3975,10 +4025,13 @@ def test_create_batch_rest_interceptors(null_interceptor): ), mock.patch.object( transports.BatchControllerRestInterceptor, "post_create_batch" ) as post, mock.patch.object( + transports.BatchControllerRestInterceptor, "post_create_batch_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.BatchControllerRestInterceptor, "pre_create_batch" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = batches.CreateBatchRequest.pb(batches.CreateBatchRequest()) transcode.return_value = { "method": "post", @@ -4000,6 +4053,7 @@ def test_create_batch_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_batch( request, @@ -4011,6 +4065,7 @@ def test_create_batch_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_batch_rest_bad_request(request_type=batches.GetBatchRequest): @@ -4103,10 +4158,13 @@ def test_get_batch_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.BatchControllerRestInterceptor, "post_get_batch" ) as post, mock.patch.object( + transports.BatchControllerRestInterceptor, "post_get_batch_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.BatchControllerRestInterceptor, "pre_get_batch" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = batches.GetBatchRequest.pb(batches.GetBatchRequest()) transcode.return_value = { "method": "post", @@ -4128,6 +4186,7 @@ def test_get_batch_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = batches.Batch() + post_with_metadata.return_value = batches.Batch(), metadata client.get_batch( request, @@ -4139,6 +4198,7 @@ def test_get_batch_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_batches_rest_bad_request(request_type=batches.ListBatchesRequest): @@ -4223,10 +4283,13 @@ def test_list_batches_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.BatchControllerRestInterceptor, "post_list_batches" ) as post, mock.patch.object( + transports.BatchControllerRestInterceptor, "post_list_batches_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.BatchControllerRestInterceptor, "pre_list_batches" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = batches.ListBatchesRequest.pb(batches.ListBatchesRequest()) transcode.return_value = { "method": "post", @@ -4250,6 +4313,7 @@ def test_list_batches_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = batches.ListBatchesResponse() + post_with_metadata.return_value = batches.ListBatchesResponse(), metadata client.list_batches( request, @@ -4261,6 +4325,7 @@ def test_list_batches_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_batch_rest_bad_request(request_type=batches.DeleteBatchRequest): diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_cluster_controller.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_cluster_controller.py index 4f581dc72faf..9710ef540b26 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_cluster_controller.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_cluster_controller.py @@ -78,6 +78,13 @@ ) from google.cloud.dataproc_v1.types import clusters, operations, shared +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -345,6 +352,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ClusterControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ClusterControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6435,10 +6485,13 @@ def test_create_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ClusterControllerRestInterceptor, "post_create_cluster" ) as post, mock.patch.object( + transports.ClusterControllerRestInterceptor, "post_create_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ClusterControllerRestInterceptor, "pre_create_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = clusters.CreateClusterRequest.pb(clusters.CreateClusterRequest()) transcode.return_value = { "method": "post", @@ -6460,6 +6513,7 @@ def test_create_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_cluster( request, @@ -6471,6 +6525,7 @@ def test_create_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_cluster_rest_bad_request(request_type=clusters.UpdateClusterRequest): @@ -6841,10 +6896,13 @@ def test_update_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ClusterControllerRestInterceptor, "post_update_cluster" ) as post, mock.patch.object( + transports.ClusterControllerRestInterceptor, "post_update_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ClusterControllerRestInterceptor, "pre_update_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = clusters.UpdateClusterRequest.pb(clusters.UpdateClusterRequest()) transcode.return_value = { "method": "post", @@ -6866,6 +6924,7 @@ def test_update_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_cluster( request, @@ -6877,6 +6936,7 @@ def test_update_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_stop_cluster_rest_bad_request(request_type=clusters.StopClusterRequest): @@ -6963,10 +7023,13 @@ def test_stop_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ClusterControllerRestInterceptor, "post_stop_cluster" ) as post, mock.patch.object( + transports.ClusterControllerRestInterceptor, "post_stop_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ClusterControllerRestInterceptor, "pre_stop_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = clusters.StopClusterRequest.pb(clusters.StopClusterRequest()) transcode.return_value = { "method": "post", @@ -6988,6 +7051,7 @@ def test_stop_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.stop_cluster( request, @@ -6999,6 +7063,7 @@ def test_stop_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_start_cluster_rest_bad_request(request_type=clusters.StartClusterRequest): @@ -7085,10 +7150,13 @@ def test_start_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ClusterControllerRestInterceptor, "post_start_cluster" ) as post, mock.patch.object( + transports.ClusterControllerRestInterceptor, "post_start_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ClusterControllerRestInterceptor, "pre_start_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = clusters.StartClusterRequest.pb(clusters.StartClusterRequest()) transcode.return_value = { "method": "post", @@ -7110,6 +7178,7 @@ def test_start_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.start_cluster( request, @@ -7121,6 +7190,7 @@ def test_start_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_cluster_rest_bad_request(request_type=clusters.DeleteClusterRequest): @@ -7207,10 +7277,13 @@ def test_delete_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ClusterControllerRestInterceptor, "post_delete_cluster" ) as post, mock.patch.object( + transports.ClusterControllerRestInterceptor, "post_delete_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ClusterControllerRestInterceptor, "pre_delete_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = clusters.DeleteClusterRequest.pb(clusters.DeleteClusterRequest()) transcode.return_value = { "method": "post", @@ -7232,6 +7305,7 @@ def test_delete_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_cluster( request, @@ -7243,6 +7317,7 @@ def test_delete_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_cluster_rest_bad_request(request_type=clusters.GetClusterRequest): @@ -7337,10 +7412,13 @@ def test_get_cluster_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ClusterControllerRestInterceptor, "post_get_cluster" ) as post, mock.patch.object( + transports.ClusterControllerRestInterceptor, "post_get_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ClusterControllerRestInterceptor, "pre_get_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = clusters.GetClusterRequest.pb(clusters.GetClusterRequest()) transcode.return_value = { "method": "post", @@ -7362,6 +7440,7 @@ def test_get_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = clusters.Cluster() + post_with_metadata.return_value = clusters.Cluster(), metadata client.get_cluster( request, @@ -7373,6 +7452,7 @@ def test_get_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_clusters_rest_bad_request(request_type=clusters.ListClustersRequest): @@ -7455,10 +7535,13 @@ def test_list_clusters_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ClusterControllerRestInterceptor, "post_list_clusters" ) as post, mock.patch.object( + transports.ClusterControllerRestInterceptor, "post_list_clusters_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ClusterControllerRestInterceptor, "pre_list_clusters" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = clusters.ListClustersRequest.pb(clusters.ListClustersRequest()) transcode.return_value = { "method": "post", @@ -7482,6 +7565,7 @@ def test_list_clusters_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = clusters.ListClustersResponse() + post_with_metadata.return_value = clusters.ListClustersResponse(), metadata client.list_clusters( request, @@ -7493,6 +7577,7 @@ def test_list_clusters_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_diagnose_cluster_rest_bad_request( @@ -7581,10 +7666,14 @@ def test_diagnose_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ClusterControllerRestInterceptor, "post_diagnose_cluster" ) as post, mock.patch.object( + transports.ClusterControllerRestInterceptor, + "post_diagnose_cluster_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ClusterControllerRestInterceptor, "pre_diagnose_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = clusters.DiagnoseClusterRequest.pb( clusters.DiagnoseClusterRequest() ) @@ -7608,6 +7697,7 @@ def test_diagnose_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.diagnose_cluster( request, @@ -7619,6 +7709,7 @@ def test_diagnose_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_iam_policy_rest_bad_request( diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_job_controller.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_job_controller.py index b93c80f4d648..fac61670f4b8 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_job_controller.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_job_controller.py @@ -75,6 +75,13 @@ ) from google.cloud.dataproc_v1.types import jobs +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -329,6 +336,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = JobControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = JobControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5624,10 +5674,13 @@ def test_submit_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobControllerRestInterceptor, "post_submit_job" ) as post, mock.patch.object( + transports.JobControllerRestInterceptor, "post_submit_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobControllerRestInterceptor, "pre_submit_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.SubmitJobRequest.pb(jobs.SubmitJobRequest()) transcode.return_value = { "method": "post", @@ -5649,6 +5702,7 @@ def test_submit_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.Job() + post_with_metadata.return_value = jobs.Job(), metadata client.submit_job( request, @@ -5660,6 +5714,7 @@ def test_submit_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_submit_job_as_operation_rest_bad_request(request_type=jobs.SubmitJobRequest): @@ -5738,10 +5793,14 @@ def test_submit_job_as_operation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.JobControllerRestInterceptor, "post_submit_job_as_operation" ) as post, mock.patch.object( + transports.JobControllerRestInterceptor, + "post_submit_job_as_operation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.JobControllerRestInterceptor, "pre_submit_job_as_operation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.SubmitJobRequest.pb(jobs.SubmitJobRequest()) transcode.return_value = { "method": "post", @@ -5763,6 +5822,7 @@ def test_submit_job_as_operation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.submit_job_as_operation( request, @@ -5774,6 +5834,7 @@ def test_submit_job_as_operation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_job_rest_bad_request(request_type=jobs.GetJobRequest): @@ -5862,10 +5923,13 @@ def test_get_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobControllerRestInterceptor, "post_get_job" ) as post, mock.patch.object( + transports.JobControllerRestInterceptor, "post_get_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobControllerRestInterceptor, "pre_get_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.GetJobRequest.pb(jobs.GetJobRequest()) transcode.return_value = { "method": "post", @@ -5887,6 +5951,7 @@ def test_get_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.Job() + post_with_metadata.return_value = jobs.Job(), metadata client.get_job( request, @@ -5898,6 +5963,7 @@ def test_get_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_jobs_rest_bad_request(request_type=jobs.ListJobsRequest): @@ -5982,10 +6048,13 @@ def test_list_jobs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobControllerRestInterceptor, "post_list_jobs" ) as post, mock.patch.object( + transports.JobControllerRestInterceptor, "post_list_jobs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobControllerRestInterceptor, "pre_list_jobs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.ListJobsRequest.pb(jobs.ListJobsRequest()) transcode.return_value = { "method": "post", @@ -6007,6 +6076,7 @@ def test_list_jobs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.ListJobsResponse() + post_with_metadata.return_value = jobs.ListJobsResponse(), metadata client.list_jobs( request, @@ -6018,6 +6088,7 @@ def test_list_jobs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_job_rest_bad_request(request_type=jobs.UpdateJobRequest): @@ -6293,10 +6364,13 @@ def test_update_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobControllerRestInterceptor, "post_update_job" ) as post, mock.patch.object( + transports.JobControllerRestInterceptor, "post_update_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobControllerRestInterceptor, "pre_update_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.UpdateJobRequest.pb(jobs.UpdateJobRequest()) transcode.return_value = { "method": "post", @@ -6318,6 +6392,7 @@ def test_update_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.Job() + post_with_metadata.return_value = jobs.Job(), metadata client.update_job( request, @@ -6329,6 +6404,7 @@ def test_update_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_job_rest_bad_request(request_type=jobs.CancelJobRequest): @@ -6417,10 +6493,13 @@ def test_cancel_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.JobControllerRestInterceptor, "post_cancel_job" ) as post, mock.patch.object( + transports.JobControllerRestInterceptor, "post_cancel_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.JobControllerRestInterceptor, "pre_cancel_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = jobs.CancelJobRequest.pb(jobs.CancelJobRequest()) transcode.return_value = { "method": "post", @@ -6442,6 +6521,7 @@ def test_cancel_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = jobs.Job() + post_with_metadata.return_value = jobs.Job(), metadata client.cancel_job( request, @@ -6453,6 +6533,7 @@ def test_cancel_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_job_rest_bad_request(request_type=jobs.DeleteJobRequest): diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_node_group_controller.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_node_group_controller.py index b53f1cebabe6..3703cf8dbf5f 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_node_group_controller.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_node_group_controller.py @@ -73,6 +73,13 @@ ) from google.cloud.dataproc_v1.types import clusters, node_groups, operations +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -346,6 +353,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = NodeGroupControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = NodeGroupControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3240,10 +3290,14 @@ def test_create_node_group_rest_interceptors(null_interceptor): ), mock.patch.object( transports.NodeGroupControllerRestInterceptor, "post_create_node_group" ) as post, mock.patch.object( + transports.NodeGroupControllerRestInterceptor, + "post_create_node_group_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.NodeGroupControllerRestInterceptor, "pre_create_node_group" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = node_groups.CreateNodeGroupRequest.pb( node_groups.CreateNodeGroupRequest() ) @@ -3267,6 +3321,7 @@ def test_create_node_group_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_node_group( request, @@ -3278,6 +3333,7 @@ def test_create_node_group_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_resize_node_group_rest_bad_request( @@ -3362,10 +3418,14 @@ def test_resize_node_group_rest_interceptors(null_interceptor): ), mock.patch.object( transports.NodeGroupControllerRestInterceptor, "post_resize_node_group" ) as post, mock.patch.object( + transports.NodeGroupControllerRestInterceptor, + "post_resize_node_group_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.NodeGroupControllerRestInterceptor, "pre_resize_node_group" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = node_groups.ResizeNodeGroupRequest.pb( node_groups.ResizeNodeGroupRequest() ) @@ -3389,6 +3449,7 @@ def test_resize_node_group_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.resize_node_group( request, @@ -3400,6 +3461,7 @@ def test_resize_node_group_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_node_group_rest_bad_request(request_type=node_groups.GetNodeGroupRequest): @@ -3488,10 +3550,14 @@ def test_get_node_group_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.NodeGroupControllerRestInterceptor, "post_get_node_group" ) as post, mock.patch.object( + transports.NodeGroupControllerRestInterceptor, + "post_get_node_group_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.NodeGroupControllerRestInterceptor, "pre_get_node_group" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = node_groups.GetNodeGroupRequest.pb( node_groups.GetNodeGroupRequest() ) @@ -3515,6 +3581,7 @@ def test_get_node_group_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = clusters.NodeGroup() + post_with_metadata.return_value = clusters.NodeGroup(), metadata client.get_node_group( request, @@ -3526,6 +3593,7 @@ def test_get_node_group_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_iam_policy_rest_bad_request( diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_session_controller.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_session_controller.py index 810ca34f0f08..3ffe81dcabae 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_session_controller.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_session_controller.py @@ -75,6 +75,13 @@ ) from google.cloud.dataproc_v1.types import operations, sessions, shared +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -342,6 +349,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4582,10 +4632,13 @@ def test_create_session_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SessionControllerRestInterceptor, "post_create_session" ) as post, mock.patch.object( + transports.SessionControllerRestInterceptor, "post_create_session_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionControllerRestInterceptor, "pre_create_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sessions.CreateSessionRequest.pb(sessions.CreateSessionRequest()) transcode.return_value = { "method": "post", @@ -4607,6 +4660,7 @@ def test_create_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_session( request, @@ -4618,6 +4672,7 @@ def test_create_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_session_rest_bad_request(request_type=sessions.GetSessionRequest): @@ -4712,10 +4767,13 @@ def test_get_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionControllerRestInterceptor, "post_get_session" ) as post, mock.patch.object( + transports.SessionControllerRestInterceptor, "post_get_session_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionControllerRestInterceptor, "pre_get_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sessions.GetSessionRequest.pb(sessions.GetSessionRequest()) transcode.return_value = { "method": "post", @@ -4737,6 +4795,7 @@ def test_get_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sessions.Session() + post_with_metadata.return_value = sessions.Session(), metadata client.get_session( request, @@ -4748,6 +4807,7 @@ def test_get_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_sessions_rest_bad_request(request_type=sessions.ListSessionsRequest): @@ -4830,10 +4890,13 @@ def test_list_sessions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionControllerRestInterceptor, "post_list_sessions" ) as post, mock.patch.object( + transports.SessionControllerRestInterceptor, "post_list_sessions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionControllerRestInterceptor, "pre_list_sessions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sessions.ListSessionsRequest.pb(sessions.ListSessionsRequest()) transcode.return_value = { "method": "post", @@ -4857,6 +4920,7 @@ def test_list_sessions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sessions.ListSessionsResponse() + post_with_metadata.return_value = sessions.ListSessionsResponse(), metadata client.list_sessions( request, @@ -4868,6 +4932,7 @@ def test_list_sessions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_terminate_session_rest_bad_request( @@ -4948,10 +5013,14 @@ def test_terminate_session_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SessionControllerRestInterceptor, "post_terminate_session" ) as post, mock.patch.object( + transports.SessionControllerRestInterceptor, + "post_terminate_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionControllerRestInterceptor, "pre_terminate_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sessions.TerminateSessionRequest.pb( sessions.TerminateSessionRequest() ) @@ -4975,6 +5044,7 @@ def test_terminate_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.terminate_session( request, @@ -4986,6 +5056,7 @@ def test_terminate_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_session_rest_bad_request(request_type=sessions.DeleteSessionRequest): @@ -5064,10 +5135,13 @@ def test_delete_session_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SessionControllerRestInterceptor, "post_delete_session" ) as post, mock.patch.object( + transports.SessionControllerRestInterceptor, "post_delete_session_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionControllerRestInterceptor, "pre_delete_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sessions.DeleteSessionRequest.pb(sessions.DeleteSessionRequest()) transcode.return_value = { "method": "post", @@ -5089,6 +5163,7 @@ def test_delete_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_session( request, @@ -5100,6 +5175,7 @@ def test_delete_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_iam_policy_rest_bad_request( diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_session_template_controller.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_session_template_controller.py index 55d26f5297d9..c07b79e7b281 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_session_template_controller.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_session_template_controller.py @@ -66,6 +66,13 @@ ) from google.cloud.dataproc_v1.types import session_templates, sessions, shared +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -345,6 +352,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionTemplateControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionTemplateControllerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4687,11 +4737,15 @@ def test_create_session_template_rest_interceptors(null_interceptor): transports.SessionTemplateControllerRestInterceptor, "post_create_session_template", ) as post, mock.patch.object( + transports.SessionTemplateControllerRestInterceptor, + "post_create_session_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionTemplateControllerRestInterceptor, "pre_create_session_template", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_templates.CreateSessionTemplateRequest.pb( session_templates.CreateSessionTemplateRequest() ) @@ -4717,6 +4771,7 @@ def test_create_session_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_templates.SessionTemplate() + post_with_metadata.return_value = session_templates.SessionTemplate(), metadata client.create_session_template( request, @@ -4728,6 +4783,7 @@ def test_create_session_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_session_template_rest_bad_request( @@ -4935,11 +4991,15 @@ def test_update_session_template_rest_interceptors(null_interceptor): transports.SessionTemplateControllerRestInterceptor, "post_update_session_template", ) as post, mock.patch.object( + transports.SessionTemplateControllerRestInterceptor, + "post_update_session_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionTemplateControllerRestInterceptor, "pre_update_session_template", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_templates.UpdateSessionTemplateRequest.pb( session_templates.UpdateSessionTemplateRequest() ) @@ -4965,6 +5025,7 @@ def test_update_session_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_templates.SessionTemplate() + post_with_metadata.return_value = session_templates.SessionTemplate(), metadata client.update_session_template( request, @@ -4976,6 +5037,7 @@ def test_update_session_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_session_template_rest_bad_request( @@ -5070,10 +5132,14 @@ def test_get_session_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionTemplateControllerRestInterceptor, "post_get_session_template" ) as post, mock.patch.object( + transports.SessionTemplateControllerRestInterceptor, + "post_get_session_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionTemplateControllerRestInterceptor, "pre_get_session_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_templates.GetSessionTemplateRequest.pb( session_templates.GetSessionTemplateRequest() ) @@ -5099,6 +5165,7 @@ def test_get_session_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_templates.SessionTemplate() + post_with_metadata.return_value = session_templates.SessionTemplate(), metadata client.get_session_template( request, @@ -5110,6 +5177,7 @@ def test_get_session_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_session_templates_rest_bad_request( @@ -5195,11 +5263,15 @@ def test_list_session_templates_rest_interceptors(null_interceptor): transports.SessionTemplateControllerRestInterceptor, "post_list_session_templates", ) as post, mock.patch.object( + transports.SessionTemplateControllerRestInterceptor, + "post_list_session_templates_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionTemplateControllerRestInterceptor, "pre_list_session_templates", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_templates.ListSessionTemplatesRequest.pb( session_templates.ListSessionTemplatesRequest() ) @@ -5225,6 +5297,10 @@ def test_list_session_templates_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_templates.ListSessionTemplatesResponse() + post_with_metadata.return_value = ( + session_templates.ListSessionTemplatesResponse(), + metadata, + ) client.list_session_templates( request, @@ -5236,6 +5312,7 @@ def test_list_session_templates_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_session_template_rest_bad_request( diff --git a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_workflow_template_service.py b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_workflow_template_service.py index 3840b6261733..a05587f8b553 100644 --- a/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_workflow_template_service.py +++ b/packages/google-cloud-dataproc/tests/unit/gapic/dataproc_v1/test_workflow_template_service.py @@ -76,6 +76,13 @@ ) from google.cloud.dataproc_v1.types import clusters, jobs, shared, workflow_templates +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -351,6 +358,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = WorkflowTemplateServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = WorkflowTemplateServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6146,11 +6196,15 @@ def test_create_workflow_template_rest_interceptors(null_interceptor): transports.WorkflowTemplateServiceRestInterceptor, "post_create_workflow_template", ) as post, mock.patch.object( + transports.WorkflowTemplateServiceRestInterceptor, + "post_create_workflow_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.WorkflowTemplateServiceRestInterceptor, "pre_create_workflow_template", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = workflow_templates.CreateWorkflowTemplateRequest.pb( workflow_templates.CreateWorkflowTemplateRequest() ) @@ -6176,6 +6230,10 @@ def test_create_workflow_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = workflow_templates.WorkflowTemplate() + post_with_metadata.return_value = ( + workflow_templates.WorkflowTemplate(), + metadata, + ) client.create_workflow_template( request, @@ -6187,6 +6245,7 @@ def test_create_workflow_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_workflow_template_rest_bad_request( @@ -6279,10 +6338,14 @@ def test_get_workflow_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.WorkflowTemplateServiceRestInterceptor, "post_get_workflow_template" ) as post, mock.patch.object( + transports.WorkflowTemplateServiceRestInterceptor, + "post_get_workflow_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.WorkflowTemplateServiceRestInterceptor, "pre_get_workflow_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = workflow_templates.GetWorkflowTemplateRequest.pb( workflow_templates.GetWorkflowTemplateRequest() ) @@ -6308,6 +6371,10 @@ def test_get_workflow_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = workflow_templates.WorkflowTemplate() + post_with_metadata.return_value = ( + workflow_templates.WorkflowTemplate(), + metadata, + ) client.get_workflow_template( request, @@ -6319,6 +6386,7 @@ def test_get_workflow_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_instantiate_workflow_template_rest_bad_request( @@ -6404,11 +6472,15 @@ def test_instantiate_workflow_template_rest_interceptors(null_interceptor): transports.WorkflowTemplateServiceRestInterceptor, "post_instantiate_workflow_template", ) as post, mock.patch.object( + transports.WorkflowTemplateServiceRestInterceptor, + "post_instantiate_workflow_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.WorkflowTemplateServiceRestInterceptor, "pre_instantiate_workflow_template", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = workflow_templates.InstantiateWorkflowTemplateRequest.pb( workflow_templates.InstantiateWorkflowTemplateRequest() ) @@ -6432,6 +6504,7 @@ def test_instantiate_workflow_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.instantiate_workflow_template( request, @@ -6443,6 +6516,7 @@ def test_instantiate_workflow_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_instantiate_inline_workflow_template_rest_bad_request( @@ -6896,11 +6970,15 @@ def test_instantiate_inline_workflow_template_rest_interceptors(null_interceptor transports.WorkflowTemplateServiceRestInterceptor, "post_instantiate_inline_workflow_template", ) as post, mock.patch.object( + transports.WorkflowTemplateServiceRestInterceptor, + "post_instantiate_inline_workflow_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.WorkflowTemplateServiceRestInterceptor, "pre_instantiate_inline_workflow_template", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = workflow_templates.InstantiateInlineWorkflowTemplateRequest.pb( workflow_templates.InstantiateInlineWorkflowTemplateRequest() ) @@ -6924,6 +7002,7 @@ def test_instantiate_inline_workflow_template_rest_interceptors(null_interceptor ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.instantiate_inline_workflow_template( request, @@ -6935,6 +7014,7 @@ def test_instantiate_inline_workflow_template_rest_interceptors(null_interceptor pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_workflow_template_rest_bad_request( @@ -7402,11 +7482,15 @@ def test_update_workflow_template_rest_interceptors(null_interceptor): transports.WorkflowTemplateServiceRestInterceptor, "post_update_workflow_template", ) as post, mock.patch.object( + transports.WorkflowTemplateServiceRestInterceptor, + "post_update_workflow_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.WorkflowTemplateServiceRestInterceptor, "pre_update_workflow_template", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = workflow_templates.UpdateWorkflowTemplateRequest.pb( workflow_templates.UpdateWorkflowTemplateRequest() ) @@ -7432,6 +7516,10 @@ def test_update_workflow_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = workflow_templates.WorkflowTemplate() + post_with_metadata.return_value = ( + workflow_templates.WorkflowTemplate(), + metadata, + ) client.update_workflow_template( request, @@ -7443,6 +7531,7 @@ def test_update_workflow_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_workflow_templates_rest_bad_request( @@ -7530,10 +7619,14 @@ def test_list_workflow_templates_rest_interceptors(null_interceptor): transports.WorkflowTemplateServiceRestInterceptor, "post_list_workflow_templates", ) as post, mock.patch.object( + transports.WorkflowTemplateServiceRestInterceptor, + "post_list_workflow_templates_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.WorkflowTemplateServiceRestInterceptor, "pre_list_workflow_templates" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = workflow_templates.ListWorkflowTemplatesRequest.pb( workflow_templates.ListWorkflowTemplatesRequest() ) @@ -7559,6 +7652,10 @@ def test_list_workflow_templates_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = workflow_templates.ListWorkflowTemplatesResponse() + post_with_metadata.return_value = ( + workflow_templates.ListWorkflowTemplatesResponse(), + metadata, + ) client.list_workflow_templates( request, @@ -7570,6 +7667,7 @@ def test_list_workflow_templates_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_workflow_template_rest_bad_request( diff --git a/packages/google-cloud-datastream/datastream-v1-py.tar.gz b/packages/google-cloud-datastream/datastream-v1-py.tar.gz new file mode 100644 index 000000000000..b087310916e2 Binary files /dev/null and b/packages/google-cloud-datastream/datastream-v1-py.tar.gz differ diff --git a/packages/google-cloud-datastream/google/cloud/datastream/gapic_version.py b/packages/google-cloud-datastream/google/cloud/datastream/gapic_version.py index 739fdfae141c..558c8aab67c5 100644 --- a/packages/google-cloud-datastream/google/cloud/datastream/gapic_version.py +++ b/packages/google-cloud-datastream/google/cloud/datastream/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datastream/google/cloud/datastream_v1/gapic_version.py b/packages/google-cloud-datastream/google/cloud/datastream_v1/gapic_version.py index 739fdfae141c..558c8aab67c5 100644 --- a/packages/google-cloud-datastream/google/cloud/datastream_v1/gapic_version.py +++ b/packages/google-cloud-datastream/google/cloud/datastream_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datastream/google/cloud/datastream_v1/services/datastream/client.py b/packages/google-cloud-datastream/google/cloud/datastream_v1/services/datastream/client.py index 8920b70eccae..b80613bebd61 100644 --- a/packages/google-cloud-datastream/google/cloud/datastream_v1/services/datastream/client.py +++ b/packages/google-cloud-datastream/google/cloud/datastream_v1/services/datastream/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -603,6 +605,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -4010,16 +4039,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -4065,16 +4098,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -4231,16 +4268,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -4286,16 +4327,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-datastream/google/cloud/datastream_v1/services/datastream/transports/rest.py b/packages/google-cloud-datastream/google/cloud/datastream_v1/services/datastream/transports/rest.py index 9424c2bcdcaf..4b1dab2f9825 100644 --- a/packages/google-cloud-datastream/google/cloud/datastream_v1/services/datastream/transports/rest.py +++ b/packages/google-cloud-datastream/google/cloud/datastream_v1/services/datastream/transports/rest.py @@ -306,12 +306,35 @@ def post_create_connection_profile( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_create_connection_profile` interceptor runs + before the `post_create_connection_profile_with_metadata` interceptor. """ return response + def post_create_connection_profile_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_create_connection_profile_with_metadata` + interceptor in new development instead of the `post_create_connection_profile` interceptor. + When both interceptors are used, this `post_create_connection_profile_with_metadata` interceptor runs after the + `post_create_connection_profile` interceptor. The (possibly modified) response returned by + `post_create_connection_profile` will be passed to + `post_create_connection_profile_with_metadata`. + """ + return response, metadata + def pre_create_private_connection( self, request: datastream.CreatePrivateConnectionRequest, @@ -332,12 +355,35 @@ def post_create_private_connection( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_private_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_private_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_create_private_connection` interceptor runs + before the `post_create_private_connection_with_metadata` interceptor. """ return response + def post_create_private_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_private_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_create_private_connection_with_metadata` + interceptor in new development instead of the `post_create_private_connection` interceptor. + When both interceptors are used, this `post_create_private_connection_with_metadata` interceptor runs after the + `post_create_private_connection` interceptor. The (possibly modified) response returned by + `post_create_private_connection` will be passed to + `post_create_private_connection_with_metadata`. + """ + return response, metadata + def pre_create_route( self, request: datastream.CreateRouteRequest, @@ -355,12 +401,35 @@ def post_create_route( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_route - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_route_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_create_route` interceptor runs + before the `post_create_route_with_metadata` interceptor. """ return response + def post_create_route_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_route + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_create_route_with_metadata` + interceptor in new development instead of the `post_create_route` interceptor. + When both interceptors are used, this `post_create_route_with_metadata` interceptor runs after the + `post_create_route` interceptor. The (possibly modified) response returned by + `post_create_route` will be passed to + `post_create_route_with_metadata`. + """ + return response, metadata + def pre_create_stream( self, request: datastream.CreateStreamRequest, @@ -378,12 +447,35 @@ def post_create_stream( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_stream - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_stream_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_create_stream` interceptor runs + before the `post_create_stream_with_metadata` interceptor. """ return response + def post_create_stream_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_stream + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_create_stream_with_metadata` + interceptor in new development instead of the `post_create_stream` interceptor. + When both interceptors are used, this `post_create_stream_with_metadata` interceptor runs after the + `post_create_stream` interceptor. The (possibly modified) response returned by + `post_create_stream` will be passed to + `post_create_stream_with_metadata`. + """ + return response, metadata + def pre_delete_connection_profile( self, request: datastream.DeleteConnectionProfileRequest, @@ -404,12 +496,35 @@ def post_delete_connection_profile( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_delete_connection_profile` interceptor runs + before the `post_delete_connection_profile_with_metadata` interceptor. """ return response + def post_delete_connection_profile_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_delete_connection_profile_with_metadata` + interceptor in new development instead of the `post_delete_connection_profile` interceptor. + When both interceptors are used, this `post_delete_connection_profile_with_metadata` interceptor runs after the + `post_delete_connection_profile` interceptor. The (possibly modified) response returned by + `post_delete_connection_profile` will be passed to + `post_delete_connection_profile_with_metadata`. + """ + return response, metadata + def pre_delete_private_connection( self, request: datastream.DeletePrivateConnectionRequest, @@ -430,12 +545,35 @@ def post_delete_private_connection( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_private_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_private_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_delete_private_connection` interceptor runs + before the `post_delete_private_connection_with_metadata` interceptor. """ return response + def post_delete_private_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_private_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_delete_private_connection_with_metadata` + interceptor in new development instead of the `post_delete_private_connection` interceptor. + When both interceptors are used, this `post_delete_private_connection_with_metadata` interceptor runs after the + `post_delete_private_connection` interceptor. The (possibly modified) response returned by + `post_delete_private_connection` will be passed to + `post_delete_private_connection_with_metadata`. + """ + return response, metadata + def pre_delete_route( self, request: datastream.DeleteRouteRequest, @@ -453,12 +591,35 @@ def post_delete_route( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_route - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_route_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_delete_route` interceptor runs + before the `post_delete_route_with_metadata` interceptor. """ return response + def post_delete_route_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_route + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_delete_route_with_metadata` + interceptor in new development instead of the `post_delete_route` interceptor. + When both interceptors are used, this `post_delete_route_with_metadata` interceptor runs after the + `post_delete_route` interceptor. The (possibly modified) response returned by + `post_delete_route` will be passed to + `post_delete_route_with_metadata`. + """ + return response, metadata + def pre_delete_stream( self, request: datastream.DeleteStreamRequest, @@ -476,12 +637,35 @@ def post_delete_stream( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_stream - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_stream_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_delete_stream` interceptor runs + before the `post_delete_stream_with_metadata` interceptor. """ return response + def post_delete_stream_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_stream + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_delete_stream_with_metadata` + interceptor in new development instead of the `post_delete_stream` interceptor. + When both interceptors are used, this `post_delete_stream_with_metadata` interceptor runs after the + `post_delete_stream` interceptor. The (possibly modified) response returned by + `post_delete_stream` will be passed to + `post_delete_stream_with_metadata`. + """ + return response, metadata + def pre_discover_connection_profile( self, request: datastream.DiscoverConnectionProfileRequest, @@ -502,12 +686,38 @@ def post_discover_connection_profile( ) -> datastream.DiscoverConnectionProfileResponse: """Post-rpc interceptor for discover_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_discover_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_discover_connection_profile` interceptor runs + before the `post_discover_connection_profile_with_metadata` interceptor. """ return response + def post_discover_connection_profile_with_metadata( + self, + response: datastream.DiscoverConnectionProfileResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.DiscoverConnectionProfileResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for discover_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_discover_connection_profile_with_metadata` + interceptor in new development instead of the `post_discover_connection_profile` interceptor. + When both interceptors are used, this `post_discover_connection_profile_with_metadata` interceptor runs after the + `post_discover_connection_profile` interceptor. The (possibly modified) response returned by + `post_discover_connection_profile` will be passed to + `post_discover_connection_profile_with_metadata`. + """ + return response, metadata + def pre_fetch_static_ips( self, request: datastream.FetchStaticIpsRequest, @@ -527,12 +737,37 @@ def post_fetch_static_ips( ) -> datastream.FetchStaticIpsResponse: """Post-rpc interceptor for fetch_static_ips - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_static_ips_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_fetch_static_ips` interceptor runs + before the `post_fetch_static_ips_with_metadata` interceptor. """ return response + def post_fetch_static_ips_with_metadata( + self, + response: datastream.FetchStaticIpsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.FetchStaticIpsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for fetch_static_ips + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_fetch_static_ips_with_metadata` + interceptor in new development instead of the `post_fetch_static_ips` interceptor. + When both interceptors are used, this `post_fetch_static_ips_with_metadata` interceptor runs after the + `post_fetch_static_ips` interceptor. The (possibly modified) response returned by + `post_fetch_static_ips` will be passed to + `post_fetch_static_ips_with_metadata`. + """ + return response, metadata + def pre_get_connection_profile( self, request: datastream.GetConnectionProfileRequest, @@ -552,12 +787,37 @@ def post_get_connection_profile( ) -> datastream_resources.ConnectionProfile: """Post-rpc interceptor for get_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_get_connection_profile` interceptor runs + before the `post_get_connection_profile_with_metadata` interceptor. """ return response + def post_get_connection_profile_with_metadata( + self, + response: datastream_resources.ConnectionProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream_resources.ConnectionProfile, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_get_connection_profile_with_metadata` + interceptor in new development instead of the `post_get_connection_profile` interceptor. + When both interceptors are used, this `post_get_connection_profile_with_metadata` interceptor runs after the + `post_get_connection_profile` interceptor. The (possibly modified) response returned by + `post_get_connection_profile` will be passed to + `post_get_connection_profile_with_metadata`. + """ + return response, metadata + def pre_get_private_connection( self, request: datastream.GetPrivateConnectionRequest, @@ -577,12 +837,37 @@ def post_get_private_connection( ) -> datastream_resources.PrivateConnection: """Post-rpc interceptor for get_private_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_private_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_get_private_connection` interceptor runs + before the `post_get_private_connection_with_metadata` interceptor. """ return response + def post_get_private_connection_with_metadata( + self, + response: datastream_resources.PrivateConnection, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream_resources.PrivateConnection, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_private_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_get_private_connection_with_metadata` + interceptor in new development instead of the `post_get_private_connection` interceptor. + When both interceptors are used, this `post_get_private_connection_with_metadata` interceptor runs after the + `post_get_private_connection` interceptor. The (possibly modified) response returned by + `post_get_private_connection` will be passed to + `post_get_private_connection_with_metadata`. + """ + return response, metadata + def pre_get_route( self, request: datastream.GetRouteRequest, @@ -600,12 +885,35 @@ def post_get_route( ) -> datastream_resources.Route: """Post-rpc interceptor for get_route - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_route_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_get_route` interceptor runs + before the `post_get_route_with_metadata` interceptor. """ return response + def post_get_route_with_metadata( + self, + response: datastream_resources.Route, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[datastream_resources.Route, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_route + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_get_route_with_metadata` + interceptor in new development instead of the `post_get_route` interceptor. + When both interceptors are used, this `post_get_route_with_metadata` interceptor runs after the + `post_get_route` interceptor. The (possibly modified) response returned by + `post_get_route` will be passed to + `post_get_route_with_metadata`. + """ + return response, metadata + def pre_get_stream( self, request: datastream.GetStreamRequest, @@ -623,12 +931,35 @@ def post_get_stream( ) -> datastream_resources.Stream: """Post-rpc interceptor for get_stream - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_stream_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_get_stream` interceptor runs + before the `post_get_stream_with_metadata` interceptor. """ return response + def post_get_stream_with_metadata( + self, + response: datastream_resources.Stream, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[datastream_resources.Stream, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_stream + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_get_stream_with_metadata` + interceptor in new development instead of the `post_get_stream` interceptor. + When both interceptors are used, this `post_get_stream_with_metadata` interceptor runs after the + `post_get_stream` interceptor. The (possibly modified) response returned by + `post_get_stream` will be passed to + `post_get_stream_with_metadata`. + """ + return response, metadata + def pre_get_stream_object( self, request: datastream.GetStreamObjectRequest, @@ -648,12 +979,37 @@ def post_get_stream_object( ) -> datastream_resources.StreamObject: """Post-rpc interceptor for get_stream_object - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_stream_object_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_get_stream_object` interceptor runs + before the `post_get_stream_object_with_metadata` interceptor. """ return response + def post_get_stream_object_with_metadata( + self, + response: datastream_resources.StreamObject, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream_resources.StreamObject, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_stream_object + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_get_stream_object_with_metadata` + interceptor in new development instead of the `post_get_stream_object` interceptor. + When both interceptors are used, this `post_get_stream_object_with_metadata` interceptor runs after the + `post_get_stream_object` interceptor. The (possibly modified) response returned by + `post_get_stream_object` will be passed to + `post_get_stream_object_with_metadata`. + """ + return response, metadata + def pre_list_connection_profiles( self, request: datastream.ListConnectionProfilesRequest, @@ -674,12 +1030,38 @@ def post_list_connection_profiles( ) -> datastream.ListConnectionProfilesResponse: """Post-rpc interceptor for list_connection_profiles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_connection_profiles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_list_connection_profiles` interceptor runs + before the `post_list_connection_profiles_with_metadata` interceptor. """ return response + def post_list_connection_profiles_with_metadata( + self, + response: datastream.ListConnectionProfilesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.ListConnectionProfilesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_connection_profiles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_list_connection_profiles_with_metadata` + interceptor in new development instead of the `post_list_connection_profiles` interceptor. + When both interceptors are used, this `post_list_connection_profiles_with_metadata` interceptor runs after the + `post_list_connection_profiles` interceptor. The (possibly modified) response returned by + `post_list_connection_profiles` will be passed to + `post_list_connection_profiles_with_metadata`. + """ + return response, metadata + def pre_list_private_connections( self, request: datastream.ListPrivateConnectionsRequest, @@ -700,12 +1082,38 @@ def post_list_private_connections( ) -> datastream.ListPrivateConnectionsResponse: """Post-rpc interceptor for list_private_connections - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_private_connections_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_list_private_connections` interceptor runs + before the `post_list_private_connections_with_metadata` interceptor. """ return response + def post_list_private_connections_with_metadata( + self, + response: datastream.ListPrivateConnectionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.ListPrivateConnectionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_private_connections + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_list_private_connections_with_metadata` + interceptor in new development instead of the `post_list_private_connections` interceptor. + When both interceptors are used, this `post_list_private_connections_with_metadata` interceptor runs after the + `post_list_private_connections` interceptor. The (possibly modified) response returned by + `post_list_private_connections` will be passed to + `post_list_private_connections_with_metadata`. + """ + return response, metadata + def pre_list_routes( self, request: datastream.ListRoutesRequest, @@ -723,12 +1131,35 @@ def post_list_routes( ) -> datastream.ListRoutesResponse: """Post-rpc interceptor for list_routes - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_routes_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_list_routes` interceptor runs + before the `post_list_routes_with_metadata` interceptor. """ return response + def post_list_routes_with_metadata( + self, + response: datastream.ListRoutesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[datastream.ListRoutesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_routes + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_list_routes_with_metadata` + interceptor in new development instead of the `post_list_routes` interceptor. + When both interceptors are used, this `post_list_routes_with_metadata` interceptor runs after the + `post_list_routes` interceptor. The (possibly modified) response returned by + `post_list_routes` will be passed to + `post_list_routes_with_metadata`. + """ + return response, metadata + def pre_list_stream_objects( self, request: datastream.ListStreamObjectsRequest, @@ -748,12 +1179,37 @@ def post_list_stream_objects( ) -> datastream.ListStreamObjectsResponse: """Post-rpc interceptor for list_stream_objects - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_stream_objects_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_list_stream_objects` interceptor runs + before the `post_list_stream_objects_with_metadata` interceptor. """ return response + def post_list_stream_objects_with_metadata( + self, + response: datastream.ListStreamObjectsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.ListStreamObjectsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_stream_objects + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_list_stream_objects_with_metadata` + interceptor in new development instead of the `post_list_stream_objects` interceptor. + When both interceptors are used, this `post_list_stream_objects_with_metadata` interceptor runs after the + `post_list_stream_objects` interceptor. The (possibly modified) response returned by + `post_list_stream_objects` will be passed to + `post_list_stream_objects_with_metadata`. + """ + return response, metadata + def pre_list_streams( self, request: datastream.ListStreamsRequest, @@ -771,12 +1227,35 @@ def post_list_streams( ) -> datastream.ListStreamsResponse: """Post-rpc interceptor for list_streams - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_streams_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_list_streams` interceptor runs + before the `post_list_streams_with_metadata` interceptor. """ return response + def post_list_streams_with_metadata( + self, + response: datastream.ListStreamsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[datastream.ListStreamsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_streams + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_list_streams_with_metadata` + interceptor in new development instead of the `post_list_streams` interceptor. + When both interceptors are used, this `post_list_streams_with_metadata` interceptor runs after the + `post_list_streams` interceptor. The (possibly modified) response returned by + `post_list_streams` will be passed to + `post_list_streams_with_metadata`. + """ + return response, metadata + def pre_lookup_stream_object( self, request: datastream.LookupStreamObjectRequest, @@ -796,12 +1275,37 @@ def post_lookup_stream_object( ) -> datastream_resources.StreamObject: """Post-rpc interceptor for lookup_stream_object - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_lookup_stream_object_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_lookup_stream_object` interceptor runs + before the `post_lookup_stream_object_with_metadata` interceptor. """ return response + def post_lookup_stream_object_with_metadata( + self, + response: datastream_resources.StreamObject, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream_resources.StreamObject, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for lookup_stream_object + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_lookup_stream_object_with_metadata` + interceptor in new development instead of the `post_lookup_stream_object` interceptor. + When both interceptors are used, this `post_lookup_stream_object_with_metadata` interceptor runs after the + `post_lookup_stream_object` interceptor. The (possibly modified) response returned by + `post_lookup_stream_object` will be passed to + `post_lookup_stream_object_with_metadata`. + """ + return response, metadata + def pre_run_stream( self, request: datastream.RunStreamRequest, @@ -819,12 +1323,35 @@ def post_run_stream( ) -> operations_pb2.Operation: """Post-rpc interceptor for run_stream - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_run_stream_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_run_stream` interceptor runs + before the `post_run_stream_with_metadata` interceptor. """ return response + def post_run_stream_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for run_stream + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_run_stream_with_metadata` + interceptor in new development instead of the `post_run_stream` interceptor. + When both interceptors are used, this `post_run_stream_with_metadata` interceptor runs after the + `post_run_stream` interceptor. The (possibly modified) response returned by + `post_run_stream` will be passed to + `post_run_stream_with_metadata`. + """ + return response, metadata + def pre_start_backfill_job( self, request: datastream.StartBackfillJobRequest, @@ -844,12 +1371,37 @@ def post_start_backfill_job( ) -> datastream.StartBackfillJobResponse: """Post-rpc interceptor for start_backfill_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_start_backfill_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_start_backfill_job` interceptor runs + before the `post_start_backfill_job_with_metadata` interceptor. """ return response + def post_start_backfill_job_with_metadata( + self, + response: datastream.StartBackfillJobResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.StartBackfillJobResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for start_backfill_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_start_backfill_job_with_metadata` + interceptor in new development instead of the `post_start_backfill_job` interceptor. + When both interceptors are used, this `post_start_backfill_job_with_metadata` interceptor runs after the + `post_start_backfill_job` interceptor. The (possibly modified) response returned by + `post_start_backfill_job` will be passed to + `post_start_backfill_job_with_metadata`. + """ + return response, metadata + def pre_stop_backfill_job( self, request: datastream.StopBackfillJobRequest, @@ -869,12 +1421,37 @@ def post_stop_backfill_job( ) -> datastream.StopBackfillJobResponse: """Post-rpc interceptor for stop_backfill_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_stop_backfill_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_stop_backfill_job` interceptor runs + before the `post_stop_backfill_job_with_metadata` interceptor. """ return response + def post_stop_backfill_job_with_metadata( + self, + response: datastream.StopBackfillJobResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.StopBackfillJobResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for stop_backfill_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_stop_backfill_job_with_metadata` + interceptor in new development instead of the `post_stop_backfill_job` interceptor. + When both interceptors are used, this `post_stop_backfill_job_with_metadata` interceptor runs after the + `post_stop_backfill_job` interceptor. The (possibly modified) response returned by + `post_stop_backfill_job` will be passed to + `post_stop_backfill_job_with_metadata`. + """ + return response, metadata + def pre_update_connection_profile( self, request: datastream.UpdateConnectionProfileRequest, @@ -895,12 +1472,35 @@ def post_update_connection_profile( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_update_connection_profile` interceptor runs + before the `post_update_connection_profile_with_metadata` interceptor. """ return response + def post_update_connection_profile_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_update_connection_profile_with_metadata` + interceptor in new development instead of the `post_update_connection_profile` interceptor. + When both interceptors are used, this `post_update_connection_profile_with_metadata` interceptor runs after the + `post_update_connection_profile` interceptor. The (possibly modified) response returned by + `post_update_connection_profile` will be passed to + `post_update_connection_profile_with_metadata`. + """ + return response, metadata + def pre_update_stream( self, request: datastream.UpdateStreamRequest, @@ -918,12 +1518,35 @@ def post_update_stream( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_stream - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_stream_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_update_stream` interceptor runs + before the `post_update_stream_with_metadata` interceptor. """ return response + def post_update_stream_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_stream + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_update_stream_with_metadata` + interceptor in new development instead of the `post_update_stream` interceptor. + When both interceptors are used, this `post_update_stream_with_metadata` interceptor runs after the + `post_update_stream` interceptor. The (possibly modified) response returned by + `post_update_stream` will be passed to + `post_update_stream_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -1338,6 +1961,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1488,6 +2115,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_private_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_private_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1639,6 +2270,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_route(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_route_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1793,6 +2428,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_stream(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_stream_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1937,6 +2576,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2081,6 +2724,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_private_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_private_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2226,6 +2873,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_route(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_route_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2372,6 +3023,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_stream(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_stream_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2522,6 +3177,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_discover_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_discover_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2671,6 +3330,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_static_ips(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_static_ips_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2819,6 +3482,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2968,6 +3635,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_private_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_private_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3116,6 +3787,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_route(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_route_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3260,6 +3935,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_stream(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_stream_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3405,6 +4084,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_stream_object(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_stream_object_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3552,6 +4235,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_connection_profiles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_connection_profiles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3699,6 +4386,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_private_connections(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_private_connections_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3843,6 +4534,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_routes(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_routes_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3988,6 +4683,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_stream_objects(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_stream_objects_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4134,6 +4833,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_streams(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_streams_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4286,6 +4989,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_lookup_stream_object(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_lookup_stream_object_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4437,6 +5144,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_run_stream(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_run_stream_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4590,6 +5301,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_start_backfill_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_start_backfill_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4744,6 +5459,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_stop_backfill_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_stop_backfill_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4895,6 +5614,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5049,6 +5772,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_stream(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_stream_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/gapic_version.py b/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/gapic_version.py index 739fdfae141c..558c8aab67c5 100644 --- a/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/gapic_version.py +++ b/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.12.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/services/datastream/client.py b/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/services/datastream/client.py index 9d2869f6c71b..ef7a1ebcdaa5 100644 --- a/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/services/datastream/client.py +++ b/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/services/datastream/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -556,6 +558,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/services/datastream/transports/rest.py b/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/services/datastream/transports/rest.py index 3283a75bf745..ffd3b2f2279a 100644 --- a/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/services/datastream/transports/rest.py +++ b/packages/google-cloud-datastream/google/cloud/datastream_v1alpha1/services/datastream/transports/rest.py @@ -263,12 +263,35 @@ def post_create_connection_profile( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_create_connection_profile` interceptor runs + before the `post_create_connection_profile_with_metadata` interceptor. """ return response + def post_create_connection_profile_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_create_connection_profile_with_metadata` + interceptor in new development instead of the `post_create_connection_profile` interceptor. + When both interceptors are used, this `post_create_connection_profile_with_metadata` interceptor runs after the + `post_create_connection_profile` interceptor. The (possibly modified) response returned by + `post_create_connection_profile` will be passed to + `post_create_connection_profile_with_metadata`. + """ + return response, metadata + def pre_create_private_connection( self, request: datastream.CreatePrivateConnectionRequest, @@ -289,12 +312,35 @@ def post_create_private_connection( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_private_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_private_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_create_private_connection` interceptor runs + before the `post_create_private_connection_with_metadata` interceptor. """ return response + def post_create_private_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_private_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_create_private_connection_with_metadata` + interceptor in new development instead of the `post_create_private_connection` interceptor. + When both interceptors are used, this `post_create_private_connection_with_metadata` interceptor runs after the + `post_create_private_connection` interceptor. The (possibly modified) response returned by + `post_create_private_connection` will be passed to + `post_create_private_connection_with_metadata`. + """ + return response, metadata + def pre_create_route( self, request: datastream.CreateRouteRequest, @@ -312,12 +358,35 @@ def post_create_route( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_route - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_route_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_create_route` interceptor runs + before the `post_create_route_with_metadata` interceptor. """ return response + def post_create_route_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_route + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_create_route_with_metadata` + interceptor in new development instead of the `post_create_route` interceptor. + When both interceptors are used, this `post_create_route_with_metadata` interceptor runs after the + `post_create_route` interceptor. The (possibly modified) response returned by + `post_create_route` will be passed to + `post_create_route_with_metadata`. + """ + return response, metadata + def pre_create_stream( self, request: datastream.CreateStreamRequest, @@ -335,12 +404,35 @@ def post_create_stream( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_stream - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_stream_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_create_stream` interceptor runs + before the `post_create_stream_with_metadata` interceptor. """ return response + def post_create_stream_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_stream + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_create_stream_with_metadata` + interceptor in new development instead of the `post_create_stream` interceptor. + When both interceptors are used, this `post_create_stream_with_metadata` interceptor runs after the + `post_create_stream` interceptor. The (possibly modified) response returned by + `post_create_stream` will be passed to + `post_create_stream_with_metadata`. + """ + return response, metadata + def pre_delete_connection_profile( self, request: datastream.DeleteConnectionProfileRequest, @@ -361,12 +453,35 @@ def post_delete_connection_profile( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_delete_connection_profile` interceptor runs + before the `post_delete_connection_profile_with_metadata` interceptor. """ return response + def post_delete_connection_profile_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_delete_connection_profile_with_metadata` + interceptor in new development instead of the `post_delete_connection_profile` interceptor. + When both interceptors are used, this `post_delete_connection_profile_with_metadata` interceptor runs after the + `post_delete_connection_profile` interceptor. The (possibly modified) response returned by + `post_delete_connection_profile` will be passed to + `post_delete_connection_profile_with_metadata`. + """ + return response, metadata + def pre_delete_private_connection( self, request: datastream.DeletePrivateConnectionRequest, @@ -387,12 +502,35 @@ def post_delete_private_connection( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_private_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_private_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_delete_private_connection` interceptor runs + before the `post_delete_private_connection_with_metadata` interceptor. """ return response + def post_delete_private_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_private_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_delete_private_connection_with_metadata` + interceptor in new development instead of the `post_delete_private_connection` interceptor. + When both interceptors are used, this `post_delete_private_connection_with_metadata` interceptor runs after the + `post_delete_private_connection` interceptor. The (possibly modified) response returned by + `post_delete_private_connection` will be passed to + `post_delete_private_connection_with_metadata`. + """ + return response, metadata + def pre_delete_route( self, request: datastream.DeleteRouteRequest, @@ -410,12 +548,35 @@ def post_delete_route( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_route - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_route_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_delete_route` interceptor runs + before the `post_delete_route_with_metadata` interceptor. """ return response + def post_delete_route_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_route + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_delete_route_with_metadata` + interceptor in new development instead of the `post_delete_route` interceptor. + When both interceptors are used, this `post_delete_route_with_metadata` interceptor runs after the + `post_delete_route` interceptor. The (possibly modified) response returned by + `post_delete_route` will be passed to + `post_delete_route_with_metadata`. + """ + return response, metadata + def pre_delete_stream( self, request: datastream.DeleteStreamRequest, @@ -433,12 +594,35 @@ def post_delete_stream( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_stream - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_stream_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_delete_stream` interceptor runs + before the `post_delete_stream_with_metadata` interceptor. """ return response + def post_delete_stream_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_stream + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_delete_stream_with_metadata` + interceptor in new development instead of the `post_delete_stream` interceptor. + When both interceptors are used, this `post_delete_stream_with_metadata` interceptor runs after the + `post_delete_stream` interceptor. The (possibly modified) response returned by + `post_delete_stream` will be passed to + `post_delete_stream_with_metadata`. + """ + return response, metadata + def pre_discover_connection_profile( self, request: datastream.DiscoverConnectionProfileRequest, @@ -459,12 +643,38 @@ def post_discover_connection_profile( ) -> datastream.DiscoverConnectionProfileResponse: """Post-rpc interceptor for discover_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_discover_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_discover_connection_profile` interceptor runs + before the `post_discover_connection_profile_with_metadata` interceptor. """ return response + def post_discover_connection_profile_with_metadata( + self, + response: datastream.DiscoverConnectionProfileResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.DiscoverConnectionProfileResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for discover_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_discover_connection_profile_with_metadata` + interceptor in new development instead of the `post_discover_connection_profile` interceptor. + When both interceptors are used, this `post_discover_connection_profile_with_metadata` interceptor runs after the + `post_discover_connection_profile` interceptor. The (possibly modified) response returned by + `post_discover_connection_profile` will be passed to + `post_discover_connection_profile_with_metadata`. + """ + return response, metadata + def pre_fetch_errors( self, request: datastream.FetchErrorsRequest, @@ -482,12 +692,35 @@ def post_fetch_errors( ) -> operations_pb2.Operation: """Post-rpc interceptor for fetch_errors - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_errors_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_fetch_errors` interceptor runs + before the `post_fetch_errors_with_metadata` interceptor. """ return response + def post_fetch_errors_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for fetch_errors + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_fetch_errors_with_metadata` + interceptor in new development instead of the `post_fetch_errors` interceptor. + When both interceptors are used, this `post_fetch_errors_with_metadata` interceptor runs after the + `post_fetch_errors` interceptor. The (possibly modified) response returned by + `post_fetch_errors` will be passed to + `post_fetch_errors_with_metadata`. + """ + return response, metadata + def pre_fetch_static_ips( self, request: datastream.FetchStaticIpsRequest, @@ -507,12 +740,37 @@ def post_fetch_static_ips( ) -> datastream.FetchStaticIpsResponse: """Post-rpc interceptor for fetch_static_ips - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_static_ips_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_fetch_static_ips` interceptor runs + before the `post_fetch_static_ips_with_metadata` interceptor. """ return response + def post_fetch_static_ips_with_metadata( + self, + response: datastream.FetchStaticIpsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.FetchStaticIpsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for fetch_static_ips + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_fetch_static_ips_with_metadata` + interceptor in new development instead of the `post_fetch_static_ips` interceptor. + When both interceptors are used, this `post_fetch_static_ips_with_metadata` interceptor runs after the + `post_fetch_static_ips` interceptor. The (possibly modified) response returned by + `post_fetch_static_ips` will be passed to + `post_fetch_static_ips_with_metadata`. + """ + return response, metadata + def pre_get_connection_profile( self, request: datastream.GetConnectionProfileRequest, @@ -532,12 +790,37 @@ def post_get_connection_profile( ) -> datastream_resources.ConnectionProfile: """Post-rpc interceptor for get_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_get_connection_profile` interceptor runs + before the `post_get_connection_profile_with_metadata` interceptor. """ return response + def post_get_connection_profile_with_metadata( + self, + response: datastream_resources.ConnectionProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream_resources.ConnectionProfile, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_get_connection_profile_with_metadata` + interceptor in new development instead of the `post_get_connection_profile` interceptor. + When both interceptors are used, this `post_get_connection_profile_with_metadata` interceptor runs after the + `post_get_connection_profile` interceptor. The (possibly modified) response returned by + `post_get_connection_profile` will be passed to + `post_get_connection_profile_with_metadata`. + """ + return response, metadata + def pre_get_private_connection( self, request: datastream.GetPrivateConnectionRequest, @@ -557,12 +840,37 @@ def post_get_private_connection( ) -> datastream_resources.PrivateConnection: """Post-rpc interceptor for get_private_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_private_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_get_private_connection` interceptor runs + before the `post_get_private_connection_with_metadata` interceptor. """ return response + def post_get_private_connection_with_metadata( + self, + response: datastream_resources.PrivateConnection, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream_resources.PrivateConnection, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_private_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_get_private_connection_with_metadata` + interceptor in new development instead of the `post_get_private_connection` interceptor. + When both interceptors are used, this `post_get_private_connection_with_metadata` interceptor runs after the + `post_get_private_connection` interceptor. The (possibly modified) response returned by + `post_get_private_connection` will be passed to + `post_get_private_connection_with_metadata`. + """ + return response, metadata + def pre_get_route( self, request: datastream.GetRouteRequest, @@ -580,12 +888,35 @@ def post_get_route( ) -> datastream_resources.Route: """Post-rpc interceptor for get_route - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_route_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_get_route` interceptor runs + before the `post_get_route_with_metadata` interceptor. """ return response + def post_get_route_with_metadata( + self, + response: datastream_resources.Route, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[datastream_resources.Route, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_route + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_get_route_with_metadata` + interceptor in new development instead of the `post_get_route` interceptor. + When both interceptors are used, this `post_get_route_with_metadata` interceptor runs after the + `post_get_route` interceptor. The (possibly modified) response returned by + `post_get_route` will be passed to + `post_get_route_with_metadata`. + """ + return response, metadata + def pre_get_stream( self, request: datastream.GetStreamRequest, @@ -603,12 +934,35 @@ def post_get_stream( ) -> datastream_resources.Stream: """Post-rpc interceptor for get_stream - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_stream_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_get_stream` interceptor runs + before the `post_get_stream_with_metadata` interceptor. """ return response + def post_get_stream_with_metadata( + self, + response: datastream_resources.Stream, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[datastream_resources.Stream, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_stream + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_get_stream_with_metadata` + interceptor in new development instead of the `post_get_stream` interceptor. + When both interceptors are used, this `post_get_stream_with_metadata` interceptor runs after the + `post_get_stream` interceptor. The (possibly modified) response returned by + `post_get_stream` will be passed to + `post_get_stream_with_metadata`. + """ + return response, metadata + def pre_list_connection_profiles( self, request: datastream.ListConnectionProfilesRequest, @@ -629,12 +983,38 @@ def post_list_connection_profiles( ) -> datastream.ListConnectionProfilesResponse: """Post-rpc interceptor for list_connection_profiles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_connection_profiles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_list_connection_profiles` interceptor runs + before the `post_list_connection_profiles_with_metadata` interceptor. """ return response + def post_list_connection_profiles_with_metadata( + self, + response: datastream.ListConnectionProfilesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.ListConnectionProfilesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_connection_profiles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_list_connection_profiles_with_metadata` + interceptor in new development instead of the `post_list_connection_profiles` interceptor. + When both interceptors are used, this `post_list_connection_profiles_with_metadata` interceptor runs after the + `post_list_connection_profiles` interceptor. The (possibly modified) response returned by + `post_list_connection_profiles` will be passed to + `post_list_connection_profiles_with_metadata`. + """ + return response, metadata + def pre_list_private_connections( self, request: datastream.ListPrivateConnectionsRequest, @@ -655,12 +1035,38 @@ def post_list_private_connections( ) -> datastream.ListPrivateConnectionsResponse: """Post-rpc interceptor for list_private_connections - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_private_connections_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_list_private_connections` interceptor runs + before the `post_list_private_connections_with_metadata` interceptor. """ return response + def post_list_private_connections_with_metadata( + self, + response: datastream.ListPrivateConnectionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + datastream.ListPrivateConnectionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_private_connections + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_list_private_connections_with_metadata` + interceptor in new development instead of the `post_list_private_connections` interceptor. + When both interceptors are used, this `post_list_private_connections_with_metadata` interceptor runs after the + `post_list_private_connections` interceptor. The (possibly modified) response returned by + `post_list_private_connections` will be passed to + `post_list_private_connections_with_metadata`. + """ + return response, metadata + def pre_list_routes( self, request: datastream.ListRoutesRequest, @@ -678,12 +1084,35 @@ def post_list_routes( ) -> datastream.ListRoutesResponse: """Post-rpc interceptor for list_routes - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_routes_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_list_routes` interceptor runs + before the `post_list_routes_with_metadata` interceptor. """ return response + def post_list_routes_with_metadata( + self, + response: datastream.ListRoutesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[datastream.ListRoutesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_routes + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_list_routes_with_metadata` + interceptor in new development instead of the `post_list_routes` interceptor. + When both interceptors are used, this `post_list_routes_with_metadata` interceptor runs after the + `post_list_routes` interceptor. The (possibly modified) response returned by + `post_list_routes` will be passed to + `post_list_routes_with_metadata`. + """ + return response, metadata + def pre_list_streams( self, request: datastream.ListStreamsRequest, @@ -701,12 +1130,35 @@ def post_list_streams( ) -> datastream.ListStreamsResponse: """Post-rpc interceptor for list_streams - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_streams_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_list_streams` interceptor runs + before the `post_list_streams_with_metadata` interceptor. """ return response + def post_list_streams_with_metadata( + self, + response: datastream.ListStreamsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[datastream.ListStreamsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_streams + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_list_streams_with_metadata` + interceptor in new development instead of the `post_list_streams` interceptor. + When both interceptors are used, this `post_list_streams_with_metadata` interceptor runs after the + `post_list_streams` interceptor. The (possibly modified) response returned by + `post_list_streams` will be passed to + `post_list_streams_with_metadata`. + """ + return response, metadata + def pre_update_connection_profile( self, request: datastream.UpdateConnectionProfileRequest, @@ -727,12 +1179,35 @@ def post_update_connection_profile( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_connection_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_connection_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_update_connection_profile` interceptor runs + before the `post_update_connection_profile_with_metadata` interceptor. """ return response + def post_update_connection_profile_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_connection_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_update_connection_profile_with_metadata` + interceptor in new development instead of the `post_update_connection_profile` interceptor. + When both interceptors are used, this `post_update_connection_profile_with_metadata` interceptor runs after the + `post_update_connection_profile` interceptor. The (possibly modified) response returned by + `post_update_connection_profile` will be passed to + `post_update_connection_profile_with_metadata`. + """ + return response, metadata + def pre_update_stream( self, request: datastream.UpdateStreamRequest, @@ -750,12 +1225,35 @@ def post_update_stream( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_stream - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_stream_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Datastream server but before - it is returned to user code. + it is returned to user code. This `post_update_stream` interceptor runs + before the `post_update_stream_with_metadata` interceptor. """ return response + def post_update_stream_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_stream + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Datastream server but before it is returned to user code. + + We recommend only using this `post_update_stream_with_metadata` + interceptor in new development instead of the `post_update_stream` interceptor. + When both interceptors are used, this `post_update_stream_with_metadata` interceptor runs after the + `post_update_stream` interceptor. The (possibly modified) response returned by + `post_update_stream` will be passed to + `post_update_stream_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class DatastreamRestStub: @@ -1023,6 +1521,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1172,6 +1674,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_private_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_private_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1323,6 +1829,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_route(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_route_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1476,6 +1986,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_stream(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_stream_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1619,6 +2133,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1762,6 +2280,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_private_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_private_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1907,6 +2429,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_route(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_route_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2052,6 +2578,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_stream(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_stream_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2202,6 +2732,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_discover_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_discover_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2356,6 +2890,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_errors(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_errors_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2503,6 +3041,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_static_ips(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_static_ips_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2647,6 +3189,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2795,6 +3341,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_private_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_private_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2943,6 +3493,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_route(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_route_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3085,6 +3639,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_stream(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_stream_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3227,6 +3785,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_connection_profiles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_connection_profiles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3371,6 +3933,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_private_connections(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_private_connections_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3515,6 +4081,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_routes(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_routes_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3659,6 +4229,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_streams(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_streams_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3808,6 +4382,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_connection_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_connection_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3961,6 +4539,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_stream(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_stream_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-datastream/samples/generated_samples/snippet_metadata_google.cloud.datastream.v1.json b/packages/google-cloud-datastream/samples/generated_samples/snippet_metadata_google.cloud.datastream.v1.json index 9c6908ff8170..c35515ccf4ca 100644 --- a/packages/google-cloud-datastream/samples/generated_samples/snippet_metadata_google.cloud.datastream.v1.json +++ b/packages/google-cloud-datastream/samples/generated_samples/snippet_metadata_google.cloud.datastream.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-datastream", - "version": "1.12.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-datastream/samples/generated_samples/snippet_metadata_google.cloud.datastream.v1alpha1.json b/packages/google-cloud-datastream/samples/generated_samples/snippet_metadata_google.cloud.datastream.v1alpha1.json index e1f0ea38cc54..8ecc74dc7276 100644 --- a/packages/google-cloud-datastream/samples/generated_samples/snippet_metadata_google.cloud.datastream.v1alpha1.json +++ b/packages/google-cloud-datastream/samples/generated_samples/snippet_metadata_google.cloud.datastream.v1alpha1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-datastream", - "version": "1.12.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-datastream/tests/unit/gapic/datastream_v1/test_datastream.py b/packages/google-cloud-datastream/tests/unit/gapic/datastream_v1/test_datastream.py index fc6b148e807f..da7287be8739 100644 --- a/packages/google-cloud-datastream/tests/unit/gapic/datastream_v1/test_datastream.py +++ b/packages/google-cloud-datastream/tests/unit/gapic/datastream_v1/test_datastream.py @@ -78,6 +78,13 @@ ) from google.cloud.datastream_v1.types import datastream, datastream_resources +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -313,6 +320,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DatastreamClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DatastreamClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -17705,10 +17755,14 @@ def test_list_connection_profiles_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_list_connection_profiles" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_list_connection_profiles_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_list_connection_profiles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.ListConnectionProfilesRequest.pb( datastream.ListConnectionProfilesRequest() ) @@ -17734,6 +17788,10 @@ def test_list_connection_profiles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.ListConnectionProfilesResponse() + post_with_metadata.return_value = ( + datastream.ListConnectionProfilesResponse(), + metadata, + ) client.list_connection_profiles( request, @@ -17745,6 +17803,7 @@ def test_list_connection_profiles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_connection_profile_rest_bad_request( @@ -17835,10 +17894,14 @@ def test_get_connection_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_get_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_get_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_get_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.GetConnectionProfileRequest.pb( datastream.GetConnectionProfileRequest() ) @@ -17864,6 +17927,10 @@ def test_get_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.ConnectionProfile() + post_with_metadata.return_value = ( + datastream_resources.ConnectionProfile(), + metadata, + ) client.get_connection_profile( request, @@ -17875,6 +17942,7 @@ def test_get_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_connection_profile_rest_bad_request( @@ -18100,10 +18168,14 @@ def test_create_connection_profile_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_create_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_create_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_create_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.CreateConnectionProfileRequest.pb( datastream.CreateConnectionProfileRequest() ) @@ -18127,6 +18199,7 @@ def test_create_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_connection_profile( request, @@ -18138,6 +18211,7 @@ def test_create_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_connection_profile_rest_bad_request( @@ -18371,10 +18445,14 @@ def test_update_connection_profile_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_update_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_update_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_update_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.UpdateConnectionProfileRequest.pb( datastream.UpdateConnectionProfileRequest() ) @@ -18398,6 +18476,7 @@ def test_update_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_connection_profile( request, @@ -18409,6 +18488,7 @@ def test_update_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_connection_profile_rest_bad_request( @@ -18493,10 +18573,14 @@ def test_delete_connection_profile_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_delete_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_delete_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_delete_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DeleteConnectionProfileRequest.pb( datastream.DeleteConnectionProfileRequest() ) @@ -18520,6 +18604,7 @@ def test_delete_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_connection_profile( request, @@ -18531,6 +18616,7 @@ def test_delete_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_discover_connection_profile_rest_bad_request( @@ -18612,10 +18698,14 @@ def test_discover_connection_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_discover_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_discover_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_discover_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DiscoverConnectionProfileRequest.pb( datastream.DiscoverConnectionProfileRequest() ) @@ -18641,6 +18731,10 @@ def test_discover_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.DiscoverConnectionProfileResponse() + post_with_metadata.return_value = ( + datastream.DiscoverConnectionProfileResponse(), + metadata, + ) client.discover_connection_profile( request, @@ -18652,6 +18746,7 @@ def test_discover_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_streams_rest_bad_request(request_type=datastream.ListStreamsRequest): @@ -18736,10 +18831,13 @@ def test_list_streams_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_list_streams" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_list_streams_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_list_streams" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.ListStreamsRequest.pb(datastream.ListStreamsRequest()) transcode.return_value = { "method": "post", @@ -18763,6 +18861,7 @@ def test_list_streams_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.ListStreamsResponse() + post_with_metadata.return_value = datastream.ListStreamsResponse(), metadata client.list_streams( request, @@ -18774,6 +18873,7 @@ def test_list_streams_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_stream_rest_bad_request(request_type=datastream.GetStreamRequest): @@ -18865,10 +18965,13 @@ def test_get_stream_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_get_stream" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_get_stream_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_get_stream" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.GetStreamRequest.pb(datastream.GetStreamRequest()) transcode.return_value = { "method": "post", @@ -18892,6 +18995,7 @@ def test_get_stream_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.Stream() + post_with_metadata.return_value = datastream_resources.Stream(), metadata client.get_stream( request, @@ -18903,6 +19007,7 @@ def test_get_stream_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_stream_rest_bad_request(request_type=datastream.CreateStreamRequest): @@ -19233,10 +19338,13 @@ def test_create_stream_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_create_stream" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_create_stream_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_create_stream" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.CreateStreamRequest.pb(datastream.CreateStreamRequest()) transcode.return_value = { "method": "post", @@ -19258,6 +19366,7 @@ def test_create_stream_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_stream( request, @@ -19269,6 +19378,7 @@ def test_create_stream_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_stream_rest_bad_request(request_type=datastream.UpdateStreamRequest): @@ -19603,10 +19713,13 @@ def test_update_stream_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_update_stream" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_update_stream_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_update_stream" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.UpdateStreamRequest.pb(datastream.UpdateStreamRequest()) transcode.return_value = { "method": "post", @@ -19628,6 +19741,7 @@ def test_update_stream_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_stream( request, @@ -19639,6 +19753,7 @@ def test_update_stream_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_stream_rest_bad_request(request_type=datastream.DeleteStreamRequest): @@ -19717,10 +19832,13 @@ def test_delete_stream_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_delete_stream" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_delete_stream_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_delete_stream" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DeleteStreamRequest.pb(datastream.DeleteStreamRequest()) transcode.return_value = { "method": "post", @@ -19742,6 +19860,7 @@ def test_delete_stream_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_stream( request, @@ -19753,6 +19872,7 @@ def test_delete_stream_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_run_stream_rest_bad_request(request_type=datastream.RunStreamRequest): @@ -19831,10 +19951,13 @@ def test_run_stream_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_run_stream" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_run_stream_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_run_stream" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.RunStreamRequest.pb(datastream.RunStreamRequest()) transcode.return_value = { "method": "post", @@ -19856,6 +19979,7 @@ def test_run_stream_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.run_stream( request, @@ -19867,6 +19991,7 @@ def test_run_stream_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_stream_object_rest_bad_request( @@ -19957,10 +20082,13 @@ def test_get_stream_object_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_get_stream_object" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_get_stream_object_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_get_stream_object" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.GetStreamObjectRequest.pb( datastream.GetStreamObjectRequest() ) @@ -19986,6 +20114,7 @@ def test_get_stream_object_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.StreamObject() + post_with_metadata.return_value = datastream_resources.StreamObject(), metadata client.get_stream_object( request, @@ -19997,6 +20126,7 @@ def test_get_stream_object_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_lookup_stream_object_rest_bad_request( @@ -20083,10 +20213,13 @@ def test_lookup_stream_object_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_lookup_stream_object" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_lookup_stream_object_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_lookup_stream_object" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.LookupStreamObjectRequest.pb( datastream.LookupStreamObjectRequest() ) @@ -20112,6 +20245,7 @@ def test_lookup_stream_object_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.StreamObject() + post_with_metadata.return_value = datastream_resources.StreamObject(), metadata client.lookup_stream_object( request, @@ -20123,6 +20257,7 @@ def test_lookup_stream_object_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_stream_objects_rest_bad_request( @@ -20207,10 +20342,13 @@ def test_list_stream_objects_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_list_stream_objects" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_list_stream_objects_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_list_stream_objects" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.ListStreamObjectsRequest.pb( datastream.ListStreamObjectsRequest() ) @@ -20236,6 +20374,10 @@ def test_list_stream_objects_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.ListStreamObjectsResponse() + post_with_metadata.return_value = ( + datastream.ListStreamObjectsResponse(), + metadata, + ) client.list_stream_objects( request, @@ -20247,6 +20389,7 @@ def test_list_stream_objects_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_start_backfill_job_rest_bad_request( @@ -20332,10 +20475,13 @@ def test_start_backfill_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_start_backfill_job" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_start_backfill_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_start_backfill_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.StartBackfillJobRequest.pb( datastream.StartBackfillJobRequest() ) @@ -20361,6 +20507,10 @@ def test_start_backfill_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.StartBackfillJobResponse() + post_with_metadata.return_value = ( + datastream.StartBackfillJobResponse(), + metadata, + ) client.start_backfill_job( request, @@ -20372,6 +20522,7 @@ def test_start_backfill_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_stop_backfill_job_rest_bad_request( @@ -20457,10 +20608,13 @@ def test_stop_backfill_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_stop_backfill_job" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_stop_backfill_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_stop_backfill_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.StopBackfillJobRequest.pb( datastream.StopBackfillJobRequest() ) @@ -20486,6 +20640,7 @@ def test_stop_backfill_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.StopBackfillJobResponse() + post_with_metadata.return_value = datastream.StopBackfillJobResponse(), metadata client.stop_backfill_job( request, @@ -20497,6 +20652,7 @@ def test_stop_backfill_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_static_ips_rest_bad_request( @@ -20583,10 +20739,13 @@ def test_fetch_static_ips_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_fetch_static_ips" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_fetch_static_ips_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_fetch_static_ips" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.FetchStaticIpsRequest.pb( datastream.FetchStaticIpsRequest() ) @@ -20612,6 +20771,7 @@ def test_fetch_static_ips_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.FetchStaticIpsResponse() + post_with_metadata.return_value = datastream.FetchStaticIpsResponse(), metadata client.fetch_static_ips( request, @@ -20623,6 +20783,7 @@ def test_fetch_static_ips_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_private_connection_rest_bad_request( @@ -20788,10 +20949,14 @@ def test_create_private_connection_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_create_private_connection" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_create_private_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_create_private_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.CreatePrivateConnectionRequest.pb( datastream.CreatePrivateConnectionRequest() ) @@ -20815,6 +20980,7 @@ def test_create_private_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_private_connection( request, @@ -20826,6 +20992,7 @@ def test_create_private_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_private_connection_rest_bad_request( @@ -20918,10 +21085,14 @@ def test_get_private_connection_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_get_private_connection" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_get_private_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_get_private_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.GetPrivateConnectionRequest.pb( datastream.GetPrivateConnectionRequest() ) @@ -20947,6 +21118,10 @@ def test_get_private_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.PrivateConnection() + post_with_metadata.return_value = ( + datastream_resources.PrivateConnection(), + metadata, + ) client.get_private_connection( request, @@ -20958,6 +21133,7 @@ def test_get_private_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_private_connections_rest_bad_request( @@ -21044,10 +21220,14 @@ def test_list_private_connections_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_list_private_connections" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_list_private_connections_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_list_private_connections" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.ListPrivateConnectionsRequest.pb( datastream.ListPrivateConnectionsRequest() ) @@ -21073,6 +21253,10 @@ def test_list_private_connections_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.ListPrivateConnectionsResponse() + post_with_metadata.return_value = ( + datastream.ListPrivateConnectionsResponse(), + metadata, + ) client.list_private_connections( request, @@ -21084,6 +21268,7 @@ def test_list_private_connections_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_private_connection_rest_bad_request( @@ -21168,10 +21353,14 @@ def test_delete_private_connection_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_delete_private_connection" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_delete_private_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_delete_private_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DeletePrivateConnectionRequest.pb( datastream.DeletePrivateConnectionRequest() ) @@ -21195,6 +21384,7 @@ def test_delete_private_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_private_connection( request, @@ -21206,6 +21396,7 @@ def test_delete_private_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_route_rest_bad_request(request_type=datastream.CreateRouteRequest): @@ -21364,10 +21555,13 @@ def test_create_route_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_create_route" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_create_route_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_create_route" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.CreateRouteRequest.pb(datastream.CreateRouteRequest()) transcode.return_value = { "method": "post", @@ -21389,6 +21583,7 @@ def test_create_route_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_route( request, @@ -21400,6 +21595,7 @@ def test_create_route_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_route_rest_bad_request(request_type=datastream.GetRouteRequest): @@ -21492,10 +21688,13 @@ def test_get_route_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_get_route" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_get_route_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_get_route" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.GetRouteRequest.pb(datastream.GetRouteRequest()) transcode.return_value = { "method": "post", @@ -21517,6 +21716,7 @@ def test_get_route_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.Route() + post_with_metadata.return_value = datastream_resources.Route(), metadata client.get_route( request, @@ -21528,6 +21728,7 @@ def test_get_route_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_routes_rest_bad_request(request_type=datastream.ListRoutesRequest): @@ -21616,10 +21817,13 @@ def test_list_routes_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_list_routes" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_list_routes_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_list_routes" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.ListRoutesRequest.pb(datastream.ListRoutesRequest()) transcode.return_value = { "method": "post", @@ -21643,6 +21847,7 @@ def test_list_routes_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.ListRoutesResponse() + post_with_metadata.return_value = datastream.ListRoutesResponse(), metadata client.list_routes( request, @@ -21654,6 +21859,7 @@ def test_list_routes_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_route_rest_bad_request(request_type=datastream.DeleteRouteRequest): @@ -21736,10 +21942,13 @@ def test_delete_route_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_delete_route" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_delete_route_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_delete_route" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DeleteRouteRequest.pb(datastream.DeleteRouteRequest()) transcode.return_value = { "method": "post", @@ -21761,6 +21970,7 @@ def test_delete_route_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_route( request, @@ -21772,6 +21982,7 @@ def test_delete_route_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-datastream/tests/unit/gapic/datastream_v1alpha1/test_datastream.py b/packages/google-cloud-datastream/tests/unit/gapic/datastream_v1alpha1/test_datastream.py index f6abd17ce818..2ef2dbd8762b 100644 --- a/packages/google-cloud-datastream/tests/unit/gapic/datastream_v1alpha1/test_datastream.py +++ b/packages/google-cloud-datastream/tests/unit/gapic/datastream_v1alpha1/test_datastream.py @@ -74,6 +74,13 @@ ) from google.cloud.datastream_v1alpha1.types import datastream, datastream_resources +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -309,6 +316,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DatastreamClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DatastreamClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -14586,10 +14636,14 @@ def test_list_connection_profiles_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_list_connection_profiles" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_list_connection_profiles_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_list_connection_profiles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.ListConnectionProfilesRequest.pb( datastream.ListConnectionProfilesRequest() ) @@ -14615,6 +14669,10 @@ def test_list_connection_profiles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.ListConnectionProfilesResponse() + post_with_metadata.return_value = ( + datastream.ListConnectionProfilesResponse(), + metadata, + ) client.list_connection_profiles( request, @@ -14626,6 +14684,7 @@ def test_list_connection_profiles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_connection_profile_rest_bad_request( @@ -14716,10 +14775,14 @@ def test_get_connection_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_get_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_get_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_get_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.GetConnectionProfileRequest.pb( datastream.GetConnectionProfileRequest() ) @@ -14745,6 +14808,10 @@ def test_get_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.ConnectionProfile() + post_with_metadata.return_value = ( + datastream_resources.ConnectionProfile(), + metadata, + ) client.get_connection_profile( request, @@ -14756,6 +14823,7 @@ def test_get_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_connection_profile_rest_bad_request( @@ -14950,10 +15018,14 @@ def test_create_connection_profile_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_create_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_create_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_create_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.CreateConnectionProfileRequest.pb( datastream.CreateConnectionProfileRequest() ) @@ -14977,6 +15049,7 @@ def test_create_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_connection_profile( request, @@ -14988,6 +15061,7 @@ def test_create_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_connection_profile_rest_bad_request( @@ -15190,10 +15264,14 @@ def test_update_connection_profile_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_update_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_update_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_update_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.UpdateConnectionProfileRequest.pb( datastream.UpdateConnectionProfileRequest() ) @@ -15217,6 +15295,7 @@ def test_update_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_connection_profile( request, @@ -15228,6 +15307,7 @@ def test_update_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_connection_profile_rest_bad_request( @@ -15312,10 +15392,14 @@ def test_delete_connection_profile_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_delete_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_delete_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_delete_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DeleteConnectionProfileRequest.pb( datastream.DeleteConnectionProfileRequest() ) @@ -15339,6 +15423,7 @@ def test_delete_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_connection_profile( request, @@ -15350,6 +15435,7 @@ def test_delete_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_discover_connection_profile_rest_bad_request( @@ -15431,10 +15517,14 @@ def test_discover_connection_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_discover_connection_profile" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_discover_connection_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_discover_connection_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DiscoverConnectionProfileRequest.pb( datastream.DiscoverConnectionProfileRequest() ) @@ -15460,6 +15550,10 @@ def test_discover_connection_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.DiscoverConnectionProfileResponse() + post_with_metadata.return_value = ( + datastream.DiscoverConnectionProfileResponse(), + metadata, + ) client.discover_connection_profile( request, @@ -15471,6 +15565,7 @@ def test_discover_connection_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_streams_rest_bad_request(request_type=datastream.ListStreamsRequest): @@ -15555,10 +15650,13 @@ def test_list_streams_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_list_streams" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_list_streams_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_list_streams" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.ListStreamsRequest.pb(datastream.ListStreamsRequest()) transcode.return_value = { "method": "post", @@ -15582,6 +15680,7 @@ def test_list_streams_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.ListStreamsResponse() + post_with_metadata.return_value = datastream.ListStreamsResponse(), metadata client.list_streams( request, @@ -15593,6 +15692,7 @@ def test_list_streams_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_stream_rest_bad_request(request_type=datastream.GetStreamRequest): @@ -15679,10 +15779,13 @@ def test_get_stream_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_get_stream" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_get_stream_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_get_stream" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.GetStreamRequest.pb(datastream.GetStreamRequest()) transcode.return_value = { "method": "post", @@ -15706,6 +15809,7 @@ def test_get_stream_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.Stream() + post_with_metadata.return_value = datastream_resources.Stream(), metadata client.get_stream( request, @@ -15717,6 +15821,7 @@ def test_get_stream_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_stream_rest_bad_request(request_type=datastream.CreateStreamRequest): @@ -15949,10 +16054,13 @@ def test_create_stream_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_create_stream" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_create_stream_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_create_stream" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.CreateStreamRequest.pb(datastream.CreateStreamRequest()) transcode.return_value = { "method": "post", @@ -15974,6 +16082,7 @@ def test_create_stream_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_stream( request, @@ -15985,6 +16094,7 @@ def test_create_stream_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_stream_rest_bad_request(request_type=datastream.UpdateStreamRequest): @@ -16221,10 +16331,13 @@ def test_update_stream_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_update_stream" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_update_stream_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_update_stream" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.UpdateStreamRequest.pb(datastream.UpdateStreamRequest()) transcode.return_value = { "method": "post", @@ -16246,6 +16359,7 @@ def test_update_stream_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_stream( request, @@ -16257,6 +16371,7 @@ def test_update_stream_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_stream_rest_bad_request(request_type=datastream.DeleteStreamRequest): @@ -16335,10 +16450,13 @@ def test_delete_stream_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_delete_stream" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_delete_stream_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_delete_stream" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DeleteStreamRequest.pb(datastream.DeleteStreamRequest()) transcode.return_value = { "method": "post", @@ -16360,6 +16478,7 @@ def test_delete_stream_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_stream( request, @@ -16371,6 +16490,7 @@ def test_delete_stream_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_errors_rest_bad_request(request_type=datastream.FetchErrorsRequest): @@ -16449,10 +16569,13 @@ def test_fetch_errors_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_fetch_errors" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_fetch_errors_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_fetch_errors" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.FetchErrorsRequest.pb(datastream.FetchErrorsRequest()) transcode.return_value = { "method": "post", @@ -16474,6 +16597,7 @@ def test_fetch_errors_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.fetch_errors( request, @@ -16485,6 +16609,7 @@ def test_fetch_errors_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_static_ips_rest_bad_request( @@ -16571,10 +16696,13 @@ def test_fetch_static_ips_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_fetch_static_ips" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_fetch_static_ips_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_fetch_static_ips" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.FetchStaticIpsRequest.pb( datastream.FetchStaticIpsRequest() ) @@ -16600,6 +16728,7 @@ def test_fetch_static_ips_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.FetchStaticIpsResponse() + post_with_metadata.return_value = datastream.FetchStaticIpsResponse(), metadata client.fetch_static_ips( request, @@ -16611,6 +16740,7 @@ def test_fetch_static_ips_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_private_connection_rest_bad_request( @@ -16776,10 +16906,14 @@ def test_create_private_connection_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_create_private_connection" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_create_private_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_create_private_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.CreatePrivateConnectionRequest.pb( datastream.CreatePrivateConnectionRequest() ) @@ -16803,6 +16937,7 @@ def test_create_private_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_private_connection( request, @@ -16814,6 +16949,7 @@ def test_create_private_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_private_connection_rest_bad_request( @@ -16906,10 +17042,14 @@ def test_get_private_connection_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_get_private_connection" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_get_private_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_get_private_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.GetPrivateConnectionRequest.pb( datastream.GetPrivateConnectionRequest() ) @@ -16935,6 +17075,10 @@ def test_get_private_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.PrivateConnection() + post_with_metadata.return_value = ( + datastream_resources.PrivateConnection(), + metadata, + ) client.get_private_connection( request, @@ -16946,6 +17090,7 @@ def test_get_private_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_private_connections_rest_bad_request( @@ -17032,10 +17177,14 @@ def test_list_private_connections_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_list_private_connections" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_list_private_connections_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_list_private_connections" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.ListPrivateConnectionsRequest.pb( datastream.ListPrivateConnectionsRequest() ) @@ -17061,6 +17210,10 @@ def test_list_private_connections_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.ListPrivateConnectionsResponse() + post_with_metadata.return_value = ( + datastream.ListPrivateConnectionsResponse(), + metadata, + ) client.list_private_connections( request, @@ -17072,6 +17225,7 @@ def test_list_private_connections_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_private_connection_rest_bad_request( @@ -17156,10 +17310,14 @@ def test_delete_private_connection_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_delete_private_connection" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, + "post_delete_private_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_delete_private_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DeletePrivateConnectionRequest.pb( datastream.DeletePrivateConnectionRequest() ) @@ -17183,6 +17341,7 @@ def test_delete_private_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_private_connection( request, @@ -17194,6 +17353,7 @@ def test_delete_private_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_route_rest_bad_request(request_type=datastream.CreateRouteRequest): @@ -17352,10 +17512,13 @@ def test_create_route_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_create_route" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_create_route_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_create_route" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.CreateRouteRequest.pb(datastream.CreateRouteRequest()) transcode.return_value = { "method": "post", @@ -17377,6 +17540,7 @@ def test_create_route_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_route( request, @@ -17388,6 +17552,7 @@ def test_create_route_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_route_rest_bad_request(request_type=datastream.GetRouteRequest): @@ -17480,10 +17645,13 @@ def test_get_route_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_get_route" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_get_route_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_get_route" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.GetRouteRequest.pb(datastream.GetRouteRequest()) transcode.return_value = { "method": "post", @@ -17505,6 +17673,7 @@ def test_get_route_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream_resources.Route() + post_with_metadata.return_value = datastream_resources.Route(), metadata client.get_route( request, @@ -17516,6 +17685,7 @@ def test_get_route_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_routes_rest_bad_request(request_type=datastream.ListRoutesRequest): @@ -17604,10 +17774,13 @@ def test_list_routes_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DatastreamRestInterceptor, "post_list_routes" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_list_routes_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_list_routes" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.ListRoutesRequest.pb(datastream.ListRoutesRequest()) transcode.return_value = { "method": "post", @@ -17631,6 +17804,7 @@ def test_list_routes_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = datastream.ListRoutesResponse() + post_with_metadata.return_value = datastream.ListRoutesResponse(), metadata client.list_routes( request, @@ -17642,6 +17816,7 @@ def test_list_routes_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_route_rest_bad_request(request_type=datastream.DeleteRouteRequest): @@ -17724,10 +17899,13 @@ def test_delete_route_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DatastreamRestInterceptor, "post_delete_route" ) as post, mock.patch.object( + transports.DatastreamRestInterceptor, "post_delete_route_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DatastreamRestInterceptor, "pre_delete_route" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = datastream.DeleteRouteRequest.pb(datastream.DeleteRouteRequest()) transcode.return_value = { "method": "post", @@ -17749,6 +17927,7 @@ def test_delete_route_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_route( request, @@ -17760,6 +17939,7 @@ def test_delete_route_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-deploy/deploy-v1-py.tar.gz b/packages/google-cloud-deploy/deploy-v1-py.tar.gz new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-deploy/google/cloud/deploy/gapic_version.py b/packages/google-cloud-deploy/google/cloud/deploy/gapic_version.py index 21f7deacf8df..558c8aab67c5 100644 --- a/packages/google-cloud-deploy/google/cloud/deploy/gapic_version.py +++ b/packages/google-cloud-deploy/google/cloud/deploy/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.5.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-deploy/google/cloud/deploy_v1/gapic_version.py b/packages/google-cloud-deploy/google/cloud/deploy_v1/gapic_version.py index 21f7deacf8df..558c8aab67c5 100644 --- a/packages/google-cloud-deploy/google/cloud/deploy_v1/gapic_version.py +++ b/packages/google-cloud-deploy/google/cloud/deploy_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.5.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-deploy/google/cloud/deploy_v1/services/cloud_deploy/client.py b/packages/google-cloud-deploy/google/cloud/deploy_v1/services/cloud_deploy/client.py index a074a3469f0a..9e0a1ce77f2f 100644 --- a/packages/google-cloud-deploy/google/cloud/deploy_v1/services/cloud_deploy/client.py +++ b/packages/google-cloud-deploy/google/cloud/deploy_v1/services/cloud_deploy/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -866,6 +868,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -6618,16 +6647,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -6673,16 +6706,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -6905,16 +6942,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -7027,16 +7068,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -7087,16 +7132,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_location( self, @@ -7142,16 +7191,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -7197,16 +7250,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-deploy/google/cloud/deploy_v1/services/cloud_deploy/transports/rest.py b/packages/google-cloud-deploy/google/cloud/deploy_v1/services/cloud_deploy/transports/rest.py index c17ab4438f70..cbca0c6a4167 100644 --- a/packages/google-cloud-deploy/google/cloud/deploy_v1/services/cloud_deploy/transports/rest.py +++ b/packages/google-cloud-deploy/google/cloud/deploy_v1/services/cloud_deploy/transports/rest.py @@ -457,12 +457,37 @@ def post_abandon_release( ) -> cloud_deploy.AbandonReleaseResponse: """Post-rpc interceptor for abandon_release - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_abandon_release_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_abandon_release` interceptor runs + before the `post_abandon_release_with_metadata` interceptor. """ return response + def post_abandon_release_with_metadata( + self, + response: cloud_deploy.AbandonReleaseResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.AbandonReleaseResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for abandon_release + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_abandon_release_with_metadata` + interceptor in new development instead of the `post_abandon_release` interceptor. + When both interceptors are used, this `post_abandon_release_with_metadata` interceptor runs after the + `post_abandon_release` interceptor. The (possibly modified) response returned by + `post_abandon_release` will be passed to + `post_abandon_release_with_metadata`. + """ + return response, metadata + def pre_advance_rollout( self, request: cloud_deploy.AdvanceRolloutRequest, @@ -482,12 +507,37 @@ def post_advance_rollout( ) -> cloud_deploy.AdvanceRolloutResponse: """Post-rpc interceptor for advance_rollout - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_advance_rollout_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_advance_rollout` interceptor runs + before the `post_advance_rollout_with_metadata` interceptor. """ return response + def post_advance_rollout_with_metadata( + self, + response: cloud_deploy.AdvanceRolloutResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.AdvanceRolloutResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for advance_rollout + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_advance_rollout_with_metadata` + interceptor in new development instead of the `post_advance_rollout` interceptor. + When both interceptors are used, this `post_advance_rollout_with_metadata` interceptor runs after the + `post_advance_rollout` interceptor. The (possibly modified) response returned by + `post_advance_rollout` will be passed to + `post_advance_rollout_with_metadata`. + """ + return response, metadata + def pre_approve_rollout( self, request: cloud_deploy.ApproveRolloutRequest, @@ -507,12 +557,37 @@ def post_approve_rollout( ) -> cloud_deploy.ApproveRolloutResponse: """Post-rpc interceptor for approve_rollout - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_approve_rollout_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_approve_rollout` interceptor runs + before the `post_approve_rollout_with_metadata` interceptor. """ return response + def post_approve_rollout_with_metadata( + self, + response: cloud_deploy.ApproveRolloutResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ApproveRolloutResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for approve_rollout + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_approve_rollout_with_metadata` + interceptor in new development instead of the `post_approve_rollout` interceptor. + When both interceptors are used, this `post_approve_rollout_with_metadata` interceptor runs after the + `post_approve_rollout` interceptor. The (possibly modified) response returned by + `post_approve_rollout` will be passed to + `post_approve_rollout_with_metadata`. + """ + return response, metadata + def pre_cancel_automation_run( self, request: cloud_deploy.CancelAutomationRunRequest, @@ -532,12 +607,38 @@ def post_cancel_automation_run( ) -> cloud_deploy.CancelAutomationRunResponse: """Post-rpc interceptor for cancel_automation_run - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_cancel_automation_run_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_cancel_automation_run` interceptor runs + before the `post_cancel_automation_run_with_metadata` interceptor. """ return response + def post_cancel_automation_run_with_metadata( + self, + response: cloud_deploy.CancelAutomationRunResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.CancelAutomationRunResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for cancel_automation_run + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_cancel_automation_run_with_metadata` + interceptor in new development instead of the `post_cancel_automation_run` interceptor. + When both interceptors are used, this `post_cancel_automation_run_with_metadata` interceptor runs after the + `post_cancel_automation_run` interceptor. The (possibly modified) response returned by + `post_cancel_automation_run` will be passed to + `post_cancel_automation_run_with_metadata`. + """ + return response, metadata + def pre_cancel_rollout( self, request: cloud_deploy.CancelRolloutRequest, @@ -557,12 +658,37 @@ def post_cancel_rollout( ) -> cloud_deploy.CancelRolloutResponse: """Post-rpc interceptor for cancel_rollout - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_cancel_rollout_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_cancel_rollout` interceptor runs + before the `post_cancel_rollout_with_metadata` interceptor. """ return response + def post_cancel_rollout_with_metadata( + self, + response: cloud_deploy.CancelRolloutResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.CancelRolloutResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for cancel_rollout + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_cancel_rollout_with_metadata` + interceptor in new development instead of the `post_cancel_rollout` interceptor. + When both interceptors are used, this `post_cancel_rollout_with_metadata` interceptor runs after the + `post_cancel_rollout` interceptor. The (possibly modified) response returned by + `post_cancel_rollout` will be passed to + `post_cancel_rollout_with_metadata`. + """ + return response, metadata + def pre_create_automation( self, request: cloud_deploy.CreateAutomationRequest, @@ -582,12 +708,35 @@ def post_create_automation( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_automation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_automation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_create_automation` interceptor runs + before the `post_create_automation_with_metadata` interceptor. """ return response + def post_create_automation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_automation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_create_automation_with_metadata` + interceptor in new development instead of the `post_create_automation` interceptor. + When both interceptors are used, this `post_create_automation_with_metadata` interceptor runs after the + `post_create_automation` interceptor. The (possibly modified) response returned by + `post_create_automation` will be passed to + `post_create_automation_with_metadata`. + """ + return response, metadata + def pre_create_custom_target_type( self, request: cloud_deploy.CreateCustomTargetTypeRequest, @@ -608,12 +757,35 @@ def post_create_custom_target_type( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_custom_target_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_custom_target_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_create_custom_target_type` interceptor runs + before the `post_create_custom_target_type_with_metadata` interceptor. """ return response + def post_create_custom_target_type_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_custom_target_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_create_custom_target_type_with_metadata` + interceptor in new development instead of the `post_create_custom_target_type` interceptor. + When both interceptors are used, this `post_create_custom_target_type_with_metadata` interceptor runs after the + `post_create_custom_target_type` interceptor. The (possibly modified) response returned by + `post_create_custom_target_type` will be passed to + `post_create_custom_target_type_with_metadata`. + """ + return response, metadata + def pre_create_delivery_pipeline( self, request: cloud_deploy.CreateDeliveryPipelineRequest, @@ -634,12 +806,35 @@ def post_create_delivery_pipeline( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_delivery_pipeline - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_delivery_pipeline_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_create_delivery_pipeline` interceptor runs + before the `post_create_delivery_pipeline_with_metadata` interceptor. """ return response + def post_create_delivery_pipeline_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_delivery_pipeline + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_create_delivery_pipeline_with_metadata` + interceptor in new development instead of the `post_create_delivery_pipeline` interceptor. + When both interceptors are used, this `post_create_delivery_pipeline_with_metadata` interceptor runs after the + `post_create_delivery_pipeline` interceptor. The (possibly modified) response returned by + `post_create_delivery_pipeline` will be passed to + `post_create_delivery_pipeline_with_metadata`. + """ + return response, metadata + def pre_create_deploy_policy( self, request: cloud_deploy.CreateDeployPolicyRequest, @@ -659,12 +854,35 @@ def post_create_deploy_policy( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_deploy_policy - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_deploy_policy_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_create_deploy_policy` interceptor runs + before the `post_create_deploy_policy_with_metadata` interceptor. """ return response + def post_create_deploy_policy_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_deploy_policy + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_create_deploy_policy_with_metadata` + interceptor in new development instead of the `post_create_deploy_policy` interceptor. + When both interceptors are used, this `post_create_deploy_policy_with_metadata` interceptor runs after the + `post_create_deploy_policy` interceptor. The (possibly modified) response returned by + `post_create_deploy_policy` will be passed to + `post_create_deploy_policy_with_metadata`. + """ + return response, metadata + def pre_create_release( self, request: cloud_deploy.CreateReleaseRequest, @@ -684,12 +902,35 @@ def post_create_release( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_release - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_release_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_create_release` interceptor runs + before the `post_create_release_with_metadata` interceptor. """ return response + def post_create_release_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_release + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_create_release_with_metadata` + interceptor in new development instead of the `post_create_release` interceptor. + When both interceptors are used, this `post_create_release_with_metadata` interceptor runs after the + `post_create_release` interceptor. The (possibly modified) response returned by + `post_create_release` will be passed to + `post_create_release_with_metadata`. + """ + return response, metadata + def pre_create_rollout( self, request: cloud_deploy.CreateRolloutRequest, @@ -709,12 +950,35 @@ def post_create_rollout( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_rollout - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_rollout_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_create_rollout` interceptor runs + before the `post_create_rollout_with_metadata` interceptor. """ return response + def post_create_rollout_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_rollout + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_create_rollout_with_metadata` + interceptor in new development instead of the `post_create_rollout` interceptor. + When both interceptors are used, this `post_create_rollout_with_metadata` interceptor runs after the + `post_create_rollout` interceptor. The (possibly modified) response returned by + `post_create_rollout` will be passed to + `post_create_rollout_with_metadata`. + """ + return response, metadata + def pre_create_target( self, request: cloud_deploy.CreateTargetRequest, @@ -734,12 +998,35 @@ def post_create_target( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_target - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_target_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_create_target` interceptor runs + before the `post_create_target_with_metadata` interceptor. """ return response + def post_create_target_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_target + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_create_target_with_metadata` + interceptor in new development instead of the `post_create_target` interceptor. + When both interceptors are used, this `post_create_target_with_metadata` interceptor runs after the + `post_create_target` interceptor. The (possibly modified) response returned by + `post_create_target` will be passed to + `post_create_target_with_metadata`. + """ + return response, metadata + def pre_delete_automation( self, request: cloud_deploy.DeleteAutomationRequest, @@ -759,12 +1046,35 @@ def post_delete_automation( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_automation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_automation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_delete_automation` interceptor runs + before the `post_delete_automation_with_metadata` interceptor. """ return response + def post_delete_automation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_automation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_delete_automation_with_metadata` + interceptor in new development instead of the `post_delete_automation` interceptor. + When both interceptors are used, this `post_delete_automation_with_metadata` interceptor runs after the + `post_delete_automation` interceptor. The (possibly modified) response returned by + `post_delete_automation` will be passed to + `post_delete_automation_with_metadata`. + """ + return response, metadata + def pre_delete_custom_target_type( self, request: cloud_deploy.DeleteCustomTargetTypeRequest, @@ -785,12 +1095,35 @@ def post_delete_custom_target_type( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_custom_target_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_custom_target_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_delete_custom_target_type` interceptor runs + before the `post_delete_custom_target_type_with_metadata` interceptor. """ return response + def post_delete_custom_target_type_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_custom_target_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_delete_custom_target_type_with_metadata` + interceptor in new development instead of the `post_delete_custom_target_type` interceptor. + When both interceptors are used, this `post_delete_custom_target_type_with_metadata` interceptor runs after the + `post_delete_custom_target_type` interceptor. The (possibly modified) response returned by + `post_delete_custom_target_type` will be passed to + `post_delete_custom_target_type_with_metadata`. + """ + return response, metadata + def pre_delete_delivery_pipeline( self, request: cloud_deploy.DeleteDeliveryPipelineRequest, @@ -811,12 +1144,35 @@ def post_delete_delivery_pipeline( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_delivery_pipeline - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_delivery_pipeline_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_delete_delivery_pipeline` interceptor runs + before the `post_delete_delivery_pipeline_with_metadata` interceptor. """ return response + def post_delete_delivery_pipeline_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_delivery_pipeline + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_delete_delivery_pipeline_with_metadata` + interceptor in new development instead of the `post_delete_delivery_pipeline` interceptor. + When both interceptors are used, this `post_delete_delivery_pipeline_with_metadata` interceptor runs after the + `post_delete_delivery_pipeline` interceptor. The (possibly modified) response returned by + `post_delete_delivery_pipeline` will be passed to + `post_delete_delivery_pipeline_with_metadata`. + """ + return response, metadata + def pre_delete_deploy_policy( self, request: cloud_deploy.DeleteDeployPolicyRequest, @@ -836,12 +1192,35 @@ def post_delete_deploy_policy( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_deploy_policy - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_deploy_policy_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_delete_deploy_policy` interceptor runs + before the `post_delete_deploy_policy_with_metadata` interceptor. """ return response + def post_delete_deploy_policy_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_deploy_policy + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_delete_deploy_policy_with_metadata` + interceptor in new development instead of the `post_delete_deploy_policy` interceptor. + When both interceptors are used, this `post_delete_deploy_policy_with_metadata` interceptor runs after the + `post_delete_deploy_policy` interceptor. The (possibly modified) response returned by + `post_delete_deploy_policy` will be passed to + `post_delete_deploy_policy_with_metadata`. + """ + return response, metadata + def pre_delete_target( self, request: cloud_deploy.DeleteTargetRequest, @@ -861,12 +1240,35 @@ def post_delete_target( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_target - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_target_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_delete_target` interceptor runs + before the `post_delete_target_with_metadata` interceptor. """ return response + def post_delete_target_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_target + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_delete_target_with_metadata` + interceptor in new development instead of the `post_delete_target` interceptor. + When both interceptors are used, this `post_delete_target_with_metadata` interceptor runs after the + `post_delete_target` interceptor. The (possibly modified) response returned by + `post_delete_target` will be passed to + `post_delete_target_with_metadata`. + """ + return response, metadata + def pre_get_automation( self, request: cloud_deploy.GetAutomationRequest, @@ -886,12 +1288,35 @@ def post_get_automation( ) -> cloud_deploy.Automation: """Post-rpc interceptor for get_automation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_automation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_get_automation` interceptor runs + before the `post_get_automation_with_metadata` interceptor. """ return response + def post_get_automation_with_metadata( + self, + response: cloud_deploy.Automation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.Automation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_automation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_automation_with_metadata` + interceptor in new development instead of the `post_get_automation` interceptor. + When both interceptors are used, this `post_get_automation_with_metadata` interceptor runs after the + `post_get_automation` interceptor. The (possibly modified) response returned by + `post_get_automation` will be passed to + `post_get_automation_with_metadata`. + """ + return response, metadata + def pre_get_automation_run( self, request: cloud_deploy.GetAutomationRunRequest, @@ -911,12 +1336,35 @@ def post_get_automation_run( ) -> cloud_deploy.AutomationRun: """Post-rpc interceptor for get_automation_run - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_automation_run_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_get_automation_run` interceptor runs + before the `post_get_automation_run_with_metadata` interceptor. """ return response + def post_get_automation_run_with_metadata( + self, + response: cloud_deploy.AutomationRun, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.AutomationRun, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_automation_run + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_automation_run_with_metadata` + interceptor in new development instead of the `post_get_automation_run` interceptor. + When both interceptors are used, this `post_get_automation_run_with_metadata` interceptor runs after the + `post_get_automation_run` interceptor. The (possibly modified) response returned by + `post_get_automation_run` will be passed to + `post_get_automation_run_with_metadata`. + """ + return response, metadata + def pre_get_config( self, request: cloud_deploy.GetConfigRequest, @@ -932,12 +1380,35 @@ def pre_get_config( def post_get_config(self, response: cloud_deploy.Config) -> cloud_deploy.Config: """Post-rpc interceptor for get_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_get_config` interceptor runs + before the `post_get_config_with_metadata` interceptor. """ return response + def post_get_config_with_metadata( + self, + response: cloud_deploy.Config, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.Config, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_config_with_metadata` + interceptor in new development instead of the `post_get_config` interceptor. + When both interceptors are used, this `post_get_config_with_metadata` interceptor runs after the + `post_get_config` interceptor. The (possibly modified) response returned by + `post_get_config` will be passed to + `post_get_config_with_metadata`. + """ + return response, metadata + def pre_get_custom_target_type( self, request: cloud_deploy.GetCustomTargetTypeRequest, @@ -957,12 +1428,35 @@ def post_get_custom_target_type( ) -> cloud_deploy.CustomTargetType: """Post-rpc interceptor for get_custom_target_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_custom_target_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_get_custom_target_type` interceptor runs + before the `post_get_custom_target_type_with_metadata` interceptor. """ return response + def post_get_custom_target_type_with_metadata( + self, + response: cloud_deploy.CustomTargetType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.CustomTargetType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_custom_target_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_custom_target_type_with_metadata` + interceptor in new development instead of the `post_get_custom_target_type` interceptor. + When both interceptors are used, this `post_get_custom_target_type_with_metadata` interceptor runs after the + `post_get_custom_target_type` interceptor. The (possibly modified) response returned by + `post_get_custom_target_type` will be passed to + `post_get_custom_target_type_with_metadata`. + """ + return response, metadata + def pre_get_delivery_pipeline( self, request: cloud_deploy.GetDeliveryPipelineRequest, @@ -982,12 +1476,35 @@ def post_get_delivery_pipeline( ) -> cloud_deploy.DeliveryPipeline: """Post-rpc interceptor for get_delivery_pipeline - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_delivery_pipeline_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_get_delivery_pipeline` interceptor runs + before the `post_get_delivery_pipeline_with_metadata` interceptor. """ return response + def post_get_delivery_pipeline_with_metadata( + self, + response: cloud_deploy.DeliveryPipeline, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.DeliveryPipeline, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_delivery_pipeline + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_delivery_pipeline_with_metadata` + interceptor in new development instead of the `post_get_delivery_pipeline` interceptor. + When both interceptors are used, this `post_get_delivery_pipeline_with_metadata` interceptor runs after the + `post_get_delivery_pipeline` interceptor. The (possibly modified) response returned by + `post_get_delivery_pipeline` will be passed to + `post_get_delivery_pipeline_with_metadata`. + """ + return response, metadata + def pre_get_deploy_policy( self, request: cloud_deploy.GetDeployPolicyRequest, @@ -1007,12 +1524,35 @@ def post_get_deploy_policy( ) -> cloud_deploy.DeployPolicy: """Post-rpc interceptor for get_deploy_policy - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_deploy_policy_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_get_deploy_policy` interceptor runs + before the `post_get_deploy_policy_with_metadata` interceptor. """ return response + def post_get_deploy_policy_with_metadata( + self, + response: cloud_deploy.DeployPolicy, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.DeployPolicy, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_deploy_policy + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_deploy_policy_with_metadata` + interceptor in new development instead of the `post_get_deploy_policy` interceptor. + When both interceptors are used, this `post_get_deploy_policy_with_metadata` interceptor runs after the + `post_get_deploy_policy` interceptor. The (possibly modified) response returned by + `post_get_deploy_policy` will be passed to + `post_get_deploy_policy_with_metadata`. + """ + return response, metadata + def pre_get_job_run( self, request: cloud_deploy.GetJobRunRequest, @@ -1028,12 +1568,35 @@ def pre_get_job_run( def post_get_job_run(self, response: cloud_deploy.JobRun) -> cloud_deploy.JobRun: """Post-rpc interceptor for get_job_run - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_job_run_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_get_job_run` interceptor runs + before the `post_get_job_run_with_metadata` interceptor. """ return response + def post_get_job_run_with_metadata( + self, + response: cloud_deploy.JobRun, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.JobRun, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_job_run + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_job_run_with_metadata` + interceptor in new development instead of the `post_get_job_run` interceptor. + When both interceptors are used, this `post_get_job_run_with_metadata` interceptor runs after the + `post_get_job_run` interceptor. The (possibly modified) response returned by + `post_get_job_run` will be passed to + `post_get_job_run_with_metadata`. + """ + return response, metadata + def pre_get_release( self, request: cloud_deploy.GetReleaseRequest, @@ -1049,12 +1612,35 @@ def pre_get_release( def post_get_release(self, response: cloud_deploy.Release) -> cloud_deploy.Release: """Post-rpc interceptor for get_release - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_release_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_get_release` interceptor runs + before the `post_get_release_with_metadata` interceptor. """ return response + def post_get_release_with_metadata( + self, + response: cloud_deploy.Release, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.Release, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_release + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_release_with_metadata` + interceptor in new development instead of the `post_get_release` interceptor. + When both interceptors are used, this `post_get_release_with_metadata` interceptor runs after the + `post_get_release` interceptor. The (possibly modified) response returned by + `post_get_release` will be passed to + `post_get_release_with_metadata`. + """ + return response, metadata + def pre_get_rollout( self, request: cloud_deploy.GetRolloutRequest, @@ -1070,12 +1656,35 @@ def pre_get_rollout( def post_get_rollout(self, response: cloud_deploy.Rollout) -> cloud_deploy.Rollout: """Post-rpc interceptor for get_rollout - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_rollout_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_get_rollout` interceptor runs + before the `post_get_rollout_with_metadata` interceptor. """ return response + def post_get_rollout_with_metadata( + self, + response: cloud_deploy.Rollout, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.Rollout, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_rollout + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_rollout_with_metadata` + interceptor in new development instead of the `post_get_rollout` interceptor. + When both interceptors are used, this `post_get_rollout_with_metadata` interceptor runs after the + `post_get_rollout` interceptor. The (possibly modified) response returned by + `post_get_rollout` will be passed to + `post_get_rollout_with_metadata`. + """ + return response, metadata + def pre_get_target( self, request: cloud_deploy.GetTargetRequest, @@ -1091,11 +1700,34 @@ def pre_get_target( def post_get_target(self, response: cloud_deploy.Target) -> cloud_deploy.Target: """Post-rpc interceptor for get_target - Override in a subclass to manipulate the response - after it is returned by the CloudDeploy server but before - it is returned to user code. + DEPRECATED. Please use the `post_get_target_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response + after it is returned by the CloudDeploy server but before + it is returned to user code. This `post_get_target` interceptor runs + before the `post_get_target_with_metadata` interceptor. + """ + return response + + def post_get_target_with_metadata( + self, + response: cloud_deploy.Target, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.Target, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_target + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_get_target_with_metadata` + interceptor in new development instead of the `post_get_target` interceptor. + When both interceptors are used, this `post_get_target_with_metadata` interceptor runs after the + `post_get_target` interceptor. The (possibly modified) response returned by + `post_get_target` will be passed to + `post_get_target_with_metadata`. """ - return response + return response, metadata def pre_ignore_job( self, @@ -1114,12 +1746,35 @@ def post_ignore_job( ) -> cloud_deploy.IgnoreJobResponse: """Post-rpc interceptor for ignore_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_ignore_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_ignore_job` interceptor runs + before the `post_ignore_job_with_metadata` interceptor. """ return response + def post_ignore_job_with_metadata( + self, + response: cloud_deploy.IgnoreJobResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.IgnoreJobResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for ignore_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_ignore_job_with_metadata` + interceptor in new development instead of the `post_ignore_job` interceptor. + When both interceptors are used, this `post_ignore_job_with_metadata` interceptor runs after the + `post_ignore_job` interceptor. The (possibly modified) response returned by + `post_ignore_job` will be passed to + `post_ignore_job_with_metadata`. + """ + return response, metadata + def pre_list_automation_runs( self, request: cloud_deploy.ListAutomationRunsRequest, @@ -1139,12 +1794,37 @@ def post_list_automation_runs( ) -> cloud_deploy.ListAutomationRunsResponse: """Post-rpc interceptor for list_automation_runs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_automation_runs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_list_automation_runs` interceptor runs + before the `post_list_automation_runs_with_metadata` interceptor. """ return response + def post_list_automation_runs_with_metadata( + self, + response: cloud_deploy.ListAutomationRunsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ListAutomationRunsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_automation_runs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_list_automation_runs_with_metadata` + interceptor in new development instead of the `post_list_automation_runs` interceptor. + When both interceptors are used, this `post_list_automation_runs_with_metadata` interceptor runs after the + `post_list_automation_runs` interceptor. The (possibly modified) response returned by + `post_list_automation_runs` will be passed to + `post_list_automation_runs_with_metadata`. + """ + return response, metadata + def pre_list_automations( self, request: cloud_deploy.ListAutomationsRequest, @@ -1164,12 +1844,37 @@ def post_list_automations( ) -> cloud_deploy.ListAutomationsResponse: """Post-rpc interceptor for list_automations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_automations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_list_automations` interceptor runs + before the `post_list_automations_with_metadata` interceptor. """ return response + def post_list_automations_with_metadata( + self, + response: cloud_deploy.ListAutomationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ListAutomationsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_automations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_list_automations_with_metadata` + interceptor in new development instead of the `post_list_automations` interceptor. + When both interceptors are used, this `post_list_automations_with_metadata` interceptor runs after the + `post_list_automations` interceptor. The (possibly modified) response returned by + `post_list_automations` will be passed to + `post_list_automations_with_metadata`. + """ + return response, metadata + def pre_list_custom_target_types( self, request: cloud_deploy.ListCustomTargetTypesRequest, @@ -1190,12 +1895,38 @@ def post_list_custom_target_types( ) -> cloud_deploy.ListCustomTargetTypesResponse: """Post-rpc interceptor for list_custom_target_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_custom_target_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_list_custom_target_types` interceptor runs + before the `post_list_custom_target_types_with_metadata` interceptor. """ return response + def post_list_custom_target_types_with_metadata( + self, + response: cloud_deploy.ListCustomTargetTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ListCustomTargetTypesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_custom_target_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_list_custom_target_types_with_metadata` + interceptor in new development instead of the `post_list_custom_target_types` interceptor. + When both interceptors are used, this `post_list_custom_target_types_with_metadata` interceptor runs after the + `post_list_custom_target_types` interceptor. The (possibly modified) response returned by + `post_list_custom_target_types` will be passed to + `post_list_custom_target_types_with_metadata`. + """ + return response, metadata + def pre_list_delivery_pipelines( self, request: cloud_deploy.ListDeliveryPipelinesRequest, @@ -1216,12 +1947,38 @@ def post_list_delivery_pipelines( ) -> cloud_deploy.ListDeliveryPipelinesResponse: """Post-rpc interceptor for list_delivery_pipelines - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_delivery_pipelines_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_list_delivery_pipelines` interceptor runs + before the `post_list_delivery_pipelines_with_metadata` interceptor. """ return response + def post_list_delivery_pipelines_with_metadata( + self, + response: cloud_deploy.ListDeliveryPipelinesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ListDeliveryPipelinesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_delivery_pipelines + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_list_delivery_pipelines_with_metadata` + interceptor in new development instead of the `post_list_delivery_pipelines` interceptor. + When both interceptors are used, this `post_list_delivery_pipelines_with_metadata` interceptor runs after the + `post_list_delivery_pipelines` interceptor. The (possibly modified) response returned by + `post_list_delivery_pipelines` will be passed to + `post_list_delivery_pipelines_with_metadata`. + """ + return response, metadata + def pre_list_deploy_policies( self, request: cloud_deploy.ListDeployPoliciesRequest, @@ -1241,12 +1998,37 @@ def post_list_deploy_policies( ) -> cloud_deploy.ListDeployPoliciesResponse: """Post-rpc interceptor for list_deploy_policies - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_deploy_policies_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_list_deploy_policies` interceptor runs + before the `post_list_deploy_policies_with_metadata` interceptor. """ return response + def post_list_deploy_policies_with_metadata( + self, + response: cloud_deploy.ListDeployPoliciesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ListDeployPoliciesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_deploy_policies + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_list_deploy_policies_with_metadata` + interceptor in new development instead of the `post_list_deploy_policies` interceptor. + When both interceptors are used, this `post_list_deploy_policies_with_metadata` interceptor runs after the + `post_list_deploy_policies` interceptor. The (possibly modified) response returned by + `post_list_deploy_policies` will be passed to + `post_list_deploy_policies_with_metadata`. + """ + return response, metadata + def pre_list_job_runs( self, request: cloud_deploy.ListJobRunsRequest, @@ -1266,12 +2048,37 @@ def post_list_job_runs( ) -> cloud_deploy.ListJobRunsResponse: """Post-rpc interceptor for list_job_runs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_job_runs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_list_job_runs` interceptor runs + before the `post_list_job_runs_with_metadata` interceptor. """ return response + def post_list_job_runs_with_metadata( + self, + response: cloud_deploy.ListJobRunsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ListJobRunsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_job_runs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_list_job_runs_with_metadata` + interceptor in new development instead of the `post_list_job_runs` interceptor. + When both interceptors are used, this `post_list_job_runs_with_metadata` interceptor runs after the + `post_list_job_runs` interceptor. The (possibly modified) response returned by + `post_list_job_runs` will be passed to + `post_list_job_runs_with_metadata`. + """ + return response, metadata + def pre_list_releases( self, request: cloud_deploy.ListReleasesRequest, @@ -1291,12 +2098,37 @@ def post_list_releases( ) -> cloud_deploy.ListReleasesResponse: """Post-rpc interceptor for list_releases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_releases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_list_releases` interceptor runs + before the `post_list_releases_with_metadata` interceptor. """ return response + def post_list_releases_with_metadata( + self, + response: cloud_deploy.ListReleasesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ListReleasesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_releases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_list_releases_with_metadata` + interceptor in new development instead of the `post_list_releases` interceptor. + When both interceptors are used, this `post_list_releases_with_metadata` interceptor runs after the + `post_list_releases` interceptor. The (possibly modified) response returned by + `post_list_releases` will be passed to + `post_list_releases_with_metadata`. + """ + return response, metadata + def pre_list_rollouts( self, request: cloud_deploy.ListRolloutsRequest, @@ -1316,12 +2148,37 @@ def post_list_rollouts( ) -> cloud_deploy.ListRolloutsResponse: """Post-rpc interceptor for list_rollouts - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_rollouts_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_list_rollouts` interceptor runs + before the `post_list_rollouts_with_metadata` interceptor. """ return response + def post_list_rollouts_with_metadata( + self, + response: cloud_deploy.ListRolloutsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ListRolloutsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_rollouts + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_list_rollouts_with_metadata` + interceptor in new development instead of the `post_list_rollouts` interceptor. + When both interceptors are used, this `post_list_rollouts_with_metadata` interceptor runs after the + `post_list_rollouts` interceptor. The (possibly modified) response returned by + `post_list_rollouts` will be passed to + `post_list_rollouts_with_metadata`. + """ + return response, metadata + def pre_list_targets( self, request: cloud_deploy.ListTargetsRequest, @@ -1341,12 +2198,37 @@ def post_list_targets( ) -> cloud_deploy.ListTargetsResponse: """Post-rpc interceptor for list_targets - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_targets_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_list_targets` interceptor runs + before the `post_list_targets_with_metadata` interceptor. """ return response + def post_list_targets_with_metadata( + self, + response: cloud_deploy.ListTargetsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.ListTargetsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_targets + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_list_targets_with_metadata` + interceptor in new development instead of the `post_list_targets` interceptor. + When both interceptors are used, this `post_list_targets_with_metadata` interceptor runs after the + `post_list_targets` interceptor. The (possibly modified) response returned by + `post_list_targets` will be passed to + `post_list_targets_with_metadata`. + """ + return response, metadata + def pre_retry_job( self, request: cloud_deploy.RetryJobRequest, @@ -1364,12 +2246,35 @@ def post_retry_job( ) -> cloud_deploy.RetryJobResponse: """Post-rpc interceptor for retry_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_retry_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_retry_job` interceptor runs + before the `post_retry_job_with_metadata` interceptor. """ return response + def post_retry_job_with_metadata( + self, + response: cloud_deploy.RetryJobResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[cloud_deploy.RetryJobResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for retry_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_retry_job_with_metadata` + interceptor in new development instead of the `post_retry_job` interceptor. + When both interceptors are used, this `post_retry_job_with_metadata` interceptor runs after the + `post_retry_job` interceptor. The (possibly modified) response returned by + `post_retry_job` will be passed to + `post_retry_job_with_metadata`. + """ + return response, metadata + def pre_rollback_target( self, request: cloud_deploy.RollbackTargetRequest, @@ -1389,12 +2294,37 @@ def post_rollback_target( ) -> cloud_deploy.RollbackTargetResponse: """Post-rpc interceptor for rollback_target - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_rollback_target_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_rollback_target` interceptor runs + before the `post_rollback_target_with_metadata` interceptor. """ return response + def post_rollback_target_with_metadata( + self, + response: cloud_deploy.RollbackTargetResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.RollbackTargetResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for rollback_target + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_rollback_target_with_metadata` + interceptor in new development instead of the `post_rollback_target` interceptor. + When both interceptors are used, this `post_rollback_target_with_metadata` interceptor runs after the + `post_rollback_target` interceptor. The (possibly modified) response returned by + `post_rollback_target` will be passed to + `post_rollback_target_with_metadata`. + """ + return response, metadata + def pre_terminate_job_run( self, request: cloud_deploy.TerminateJobRunRequest, @@ -1414,12 +2344,37 @@ def post_terminate_job_run( ) -> cloud_deploy.TerminateJobRunResponse: """Post-rpc interceptor for terminate_job_run - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_terminate_job_run_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_terminate_job_run` interceptor runs + before the `post_terminate_job_run_with_metadata` interceptor. """ return response + def post_terminate_job_run_with_metadata( + self, + response: cloud_deploy.TerminateJobRunResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + cloud_deploy.TerminateJobRunResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for terminate_job_run + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_terminate_job_run_with_metadata` + interceptor in new development instead of the `post_terminate_job_run` interceptor. + When both interceptors are used, this `post_terminate_job_run_with_metadata` interceptor runs after the + `post_terminate_job_run` interceptor. The (possibly modified) response returned by + `post_terminate_job_run` will be passed to + `post_terminate_job_run_with_metadata`. + """ + return response, metadata + def pre_update_automation( self, request: cloud_deploy.UpdateAutomationRequest, @@ -1439,12 +2394,35 @@ def post_update_automation( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_automation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_automation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_update_automation` interceptor runs + before the `post_update_automation_with_metadata` interceptor. """ return response + def post_update_automation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_automation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_update_automation_with_metadata` + interceptor in new development instead of the `post_update_automation` interceptor. + When both interceptors are used, this `post_update_automation_with_metadata` interceptor runs after the + `post_update_automation` interceptor. The (possibly modified) response returned by + `post_update_automation` will be passed to + `post_update_automation_with_metadata`. + """ + return response, metadata + def pre_update_custom_target_type( self, request: cloud_deploy.UpdateCustomTargetTypeRequest, @@ -1465,12 +2443,35 @@ def post_update_custom_target_type( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_custom_target_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_custom_target_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_update_custom_target_type` interceptor runs + before the `post_update_custom_target_type_with_metadata` interceptor. """ return response + def post_update_custom_target_type_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_custom_target_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_update_custom_target_type_with_metadata` + interceptor in new development instead of the `post_update_custom_target_type` interceptor. + When both interceptors are used, this `post_update_custom_target_type_with_metadata` interceptor runs after the + `post_update_custom_target_type` interceptor. The (possibly modified) response returned by + `post_update_custom_target_type` will be passed to + `post_update_custom_target_type_with_metadata`. + """ + return response, metadata + def pre_update_delivery_pipeline( self, request: cloud_deploy.UpdateDeliveryPipelineRequest, @@ -1491,12 +2492,35 @@ def post_update_delivery_pipeline( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_delivery_pipeline - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_delivery_pipeline_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_update_delivery_pipeline` interceptor runs + before the `post_update_delivery_pipeline_with_metadata` interceptor. """ return response + def post_update_delivery_pipeline_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_delivery_pipeline + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_update_delivery_pipeline_with_metadata` + interceptor in new development instead of the `post_update_delivery_pipeline` interceptor. + When both interceptors are used, this `post_update_delivery_pipeline_with_metadata` interceptor runs after the + `post_update_delivery_pipeline` interceptor. The (possibly modified) response returned by + `post_update_delivery_pipeline` will be passed to + `post_update_delivery_pipeline_with_metadata`. + """ + return response, metadata + def pre_update_deploy_policy( self, request: cloud_deploy.UpdateDeployPolicyRequest, @@ -1516,12 +2540,35 @@ def post_update_deploy_policy( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_deploy_policy - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_deploy_policy_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_update_deploy_policy` interceptor runs + before the `post_update_deploy_policy_with_metadata` interceptor. """ return response + def post_update_deploy_policy_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_deploy_policy + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_update_deploy_policy_with_metadata` + interceptor in new development instead of the `post_update_deploy_policy` interceptor. + When both interceptors are used, this `post_update_deploy_policy_with_metadata` interceptor runs after the + `post_update_deploy_policy` interceptor. The (possibly modified) response returned by + `post_update_deploy_policy` will be passed to + `post_update_deploy_policy_with_metadata`. + """ + return response, metadata + def pre_update_target( self, request: cloud_deploy.UpdateTargetRequest, @@ -1541,12 +2588,35 @@ def post_update_target( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_target - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_target_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CloudDeploy server but before - it is returned to user code. + it is returned to user code. This `post_update_target` interceptor runs + before the `post_update_target_with_metadata` interceptor. """ return response + def post_update_target_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_target + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CloudDeploy server but before it is returned to user code. + + We recommend only using this `post_update_target_with_metadata` + interceptor in new development instead of the `post_update_target` interceptor. + When both interceptors are used, this `post_update_target_with_metadata` interceptor runs after the + `post_update_target` interceptor. The (possibly modified) response returned by + `post_update_target` will be passed to + `post_update_target_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -2031,6 +3101,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_abandon_release(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_abandon_release_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2179,6 +3253,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_advance_rollout(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_advance_rollout_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2327,6 +3405,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_approve_rollout(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_approve_rollout_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2477,6 +3559,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_cancel_automation_run(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_cancel_automation_run_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2629,6 +3715,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_cancel_rollout(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_cancel_rollout_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2780,6 +3870,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_automation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_automation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2929,6 +4023,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_custom_target_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_custom_target_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3078,6 +4176,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_delivery_pipeline(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_delivery_pipeline_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3227,6 +4329,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_deploy_policy(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_deploy_policy_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3378,6 +4484,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_release(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_release_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3530,6 +4640,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_rollout(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_rollout_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3683,6 +4797,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_target(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_target_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3826,6 +4944,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_automation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_automation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3969,6 +5091,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_custom_target_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_custom_target_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4112,6 +5238,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_delivery_pipeline(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_delivery_pipeline_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4255,6 +5385,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_deploy_policy(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_deploy_policy_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4400,6 +5534,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_target(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_target_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4550,6 +5688,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_automation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_automation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4696,6 +5838,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_automation_run(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_automation_run_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4838,6 +5984,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4986,6 +6136,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_custom_target_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_custom_target_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5132,6 +6286,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_delivery_pipeline(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_delivery_pipeline_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5278,6 +6436,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_deploy_policy(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_deploy_policy_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5425,6 +6587,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_job_run(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_job_run_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5573,6 +6739,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_release(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_release_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5722,6 +6892,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_rollout(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_rollout_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5868,6 +7042,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_target(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_target_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6016,6 +7194,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_ignore_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_ignore_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6158,6 +7340,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_automation_runs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_automation_runs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6302,6 +7488,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_automations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_automations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6446,6 +7636,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_custom_target_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_custom_target_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6590,6 +7784,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_delivery_pipelines(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_delivery_pipelines_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6734,6 +7932,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_deploy_policies(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_deploy_policies_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6883,6 +8085,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_job_runs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_job_runs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7029,6 +8235,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_releases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_releases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7178,6 +8388,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_rollouts(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_rollouts_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7324,6 +8538,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_targets(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_targets_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7475,6 +8693,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_retry_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_retry_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7621,6 +8843,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_rollback_target(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_rollback_target_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7771,6 +8997,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_terminate_job_run(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_terminate_job_run_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7922,6 +9152,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_automation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_automation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8071,6 +9305,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_custom_target_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_custom_target_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8220,6 +9458,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_delivery_pipeline(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_delivery_pipeline_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8369,6 +9611,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_deploy_policy(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_deploy_policy_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8522,6 +9768,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_target(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_target_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-deploy/samples/generated_samples/snippet_metadata_google.cloud.deploy.v1.json b/packages/google-cloud-deploy/samples/generated_samples/snippet_metadata_google.cloud.deploy.v1.json index 8899f8655d94..c29c8f123304 100644 --- a/packages/google-cloud-deploy/samples/generated_samples/snippet_metadata_google.cloud.deploy.v1.json +++ b/packages/google-cloud-deploy/samples/generated_samples/snippet_metadata_google.cloud.deploy.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-deploy", - "version": "2.5.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-deploy/tests/unit/gapic/deploy_v1/test_cloud_deploy.py b/packages/google-cloud-deploy/tests/unit/gapic/deploy_v1/test_cloud_deploy.py index e7c517531ce9..b27b763897ec 100644 --- a/packages/google-cloud-deploy/tests/unit/gapic/deploy_v1/test_cloud_deploy.py +++ b/packages/google-cloud-deploy/tests/unit/gapic/deploy_v1/test_cloud_deploy.py @@ -81,6 +81,13 @@ ) from google.cloud.deploy_v1.types import cloud_deploy +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -320,6 +327,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = CloudDeployClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = CloudDeployClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -30366,10 +30416,14 @@ def test_list_delivery_pipelines_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_list_delivery_pipelines" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_list_delivery_pipelines_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_list_delivery_pipelines" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ListDeliveryPipelinesRequest.pb( cloud_deploy.ListDeliveryPipelinesRequest() ) @@ -30395,6 +30449,10 @@ def test_list_delivery_pipelines_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ListDeliveryPipelinesResponse() + post_with_metadata.return_value = ( + cloud_deploy.ListDeliveryPipelinesResponse(), + metadata, + ) client.list_delivery_pipelines( request, @@ -30406,6 +30464,7 @@ def test_list_delivery_pipelines_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_delivery_pipeline_rest_bad_request( @@ -30502,10 +30561,14 @@ def test_get_delivery_pipeline_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_delivery_pipeline" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_get_delivery_pipeline_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_delivery_pipeline" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetDeliveryPipelineRequest.pb( cloud_deploy.GetDeliveryPipelineRequest() ) @@ -30531,6 +30594,7 @@ def test_get_delivery_pipeline_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.DeliveryPipeline() + post_with_metadata.return_value = cloud_deploy.DeliveryPipeline(), metadata client.get_delivery_pipeline( request, @@ -30542,6 +30606,7 @@ def test_get_delivery_pipeline_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_delivery_pipeline_rest_bad_request( @@ -30800,10 +30865,14 @@ def test_create_delivery_pipeline_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_create_delivery_pipeline" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_create_delivery_pipeline_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_create_delivery_pipeline" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.CreateDeliveryPipelineRequest.pb( cloud_deploy.CreateDeliveryPipelineRequest() ) @@ -30827,6 +30896,7 @@ def test_create_delivery_pipeline_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_delivery_pipeline( request, @@ -30838,6 +30908,7 @@ def test_create_delivery_pipeline_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_delivery_pipeline_rest_bad_request( @@ -31104,10 +31175,14 @@ def test_update_delivery_pipeline_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_update_delivery_pipeline" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_update_delivery_pipeline_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_update_delivery_pipeline" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.UpdateDeliveryPipelineRequest.pb( cloud_deploy.UpdateDeliveryPipelineRequest() ) @@ -31131,6 +31206,7 @@ def test_update_delivery_pipeline_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_delivery_pipeline( request, @@ -31142,6 +31218,7 @@ def test_update_delivery_pipeline_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_delivery_pipeline_rest_bad_request( @@ -31226,10 +31303,14 @@ def test_delete_delivery_pipeline_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_delete_delivery_pipeline" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_delete_delivery_pipeline_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_delete_delivery_pipeline" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.DeleteDeliveryPipelineRequest.pb( cloud_deploy.DeleteDeliveryPipelineRequest() ) @@ -31253,6 +31334,7 @@ def test_delete_delivery_pipeline_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_delivery_pipeline( request, @@ -31264,6 +31346,7 @@ def test_delete_delivery_pipeline_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_targets_rest_bad_request(request_type=cloud_deploy.ListTargetsRequest): @@ -31348,10 +31431,13 @@ def test_list_targets_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_list_targets" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_list_targets_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_list_targets" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ListTargetsRequest.pb( cloud_deploy.ListTargetsRequest() ) @@ -31377,6 +31463,7 @@ def test_list_targets_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ListTargetsResponse() + post_with_metadata.return_value = cloud_deploy.ListTargetsResponse(), metadata client.list_targets( request, @@ -31388,6 +31475,7 @@ def test_list_targets_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_rollback_target_rest_bad_request( @@ -31473,10 +31561,13 @@ def test_rollback_target_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_rollback_target" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_rollback_target_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_rollback_target" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.RollbackTargetRequest.pb( cloud_deploy.RollbackTargetRequest() ) @@ -31502,6 +31593,10 @@ def test_rollback_target_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.RollbackTargetResponse() + post_with_metadata.return_value = ( + cloud_deploy.RollbackTargetResponse(), + metadata, + ) client.rollback_target( request, @@ -31513,6 +31608,7 @@ def test_rollback_target_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_target_rest_bad_request(request_type=cloud_deploy.GetTargetRequest): @@ -31605,10 +31701,13 @@ def test_get_target_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_target" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_get_target_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_target" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetTargetRequest.pb(cloud_deploy.GetTargetRequest()) transcode.return_value = { "method": "post", @@ -31630,6 +31729,7 @@ def test_get_target_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.Target() + post_with_metadata.return_value = cloud_deploy.Target(), metadata client.get_target( request, @@ -31641,6 +31741,7 @@ def test_get_target_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_target_rest_bad_request(request_type=cloud_deploy.CreateTargetRequest): @@ -31829,10 +31930,13 @@ def test_create_target_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_create_target" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_create_target_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_create_target" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.CreateTargetRequest.pb( cloud_deploy.CreateTargetRequest() ) @@ -31856,6 +31960,7 @@ def test_create_target_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_target( request, @@ -31867,6 +31972,7 @@ def test_create_target_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_target_rest_bad_request(request_type=cloud_deploy.UpdateTargetRequest): @@ -32059,10 +32165,13 @@ def test_update_target_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_update_target" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_update_target_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_update_target" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.UpdateTargetRequest.pb( cloud_deploy.UpdateTargetRequest() ) @@ -32086,6 +32195,7 @@ def test_update_target_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_target( request, @@ -32097,6 +32207,7 @@ def test_update_target_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_target_rest_bad_request(request_type=cloud_deploy.DeleteTargetRequest): @@ -32175,10 +32286,13 @@ def test_delete_target_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_delete_target" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_delete_target_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_delete_target" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.DeleteTargetRequest.pb( cloud_deploy.DeleteTargetRequest() ) @@ -32202,6 +32316,7 @@ def test_delete_target_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_target( request, @@ -32213,6 +32328,7 @@ def test_delete_target_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_custom_target_types_rest_bad_request( @@ -32299,10 +32415,14 @@ def test_list_custom_target_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_list_custom_target_types" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_list_custom_target_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_list_custom_target_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ListCustomTargetTypesRequest.pb( cloud_deploy.ListCustomTargetTypesRequest() ) @@ -32328,6 +32448,10 @@ def test_list_custom_target_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ListCustomTargetTypesResponse() + post_with_metadata.return_value = ( + cloud_deploy.ListCustomTargetTypesResponse(), + metadata, + ) client.list_custom_target_types( request, @@ -32339,6 +32463,7 @@ def test_list_custom_target_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_custom_target_type_rest_bad_request( @@ -32435,10 +32560,14 @@ def test_get_custom_target_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_custom_target_type" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_get_custom_target_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_custom_target_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetCustomTargetTypeRequest.pb( cloud_deploy.GetCustomTargetTypeRequest() ) @@ -32464,6 +32593,7 @@ def test_get_custom_target_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.CustomTargetType() + post_with_metadata.return_value = cloud_deploy.CustomTargetType(), metadata client.get_custom_target_type( request, @@ -32475,6 +32605,7 @@ def test_get_custom_target_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_custom_target_type_rest_bad_request( @@ -32658,10 +32789,14 @@ def test_create_custom_target_type_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_create_custom_target_type" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_create_custom_target_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_create_custom_target_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.CreateCustomTargetTypeRequest.pb( cloud_deploy.CreateCustomTargetTypeRequest() ) @@ -32685,6 +32820,7 @@ def test_create_custom_target_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_custom_target_type( request, @@ -32696,6 +32832,7 @@ def test_create_custom_target_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_custom_target_type_rest_bad_request( @@ -32887,10 +33024,14 @@ def test_update_custom_target_type_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_update_custom_target_type" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_update_custom_target_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_update_custom_target_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.UpdateCustomTargetTypeRequest.pb( cloud_deploy.UpdateCustomTargetTypeRequest() ) @@ -32914,6 +33055,7 @@ def test_update_custom_target_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_custom_target_type( request, @@ -32925,6 +33067,7 @@ def test_update_custom_target_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_custom_target_type_rest_bad_request( @@ -33009,10 +33152,14 @@ def test_delete_custom_target_type_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_delete_custom_target_type" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_delete_custom_target_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_delete_custom_target_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.DeleteCustomTargetTypeRequest.pb( cloud_deploy.DeleteCustomTargetTypeRequest() ) @@ -33036,6 +33183,7 @@ def test_delete_custom_target_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_custom_target_type( request, @@ -33047,6 +33195,7 @@ def test_delete_custom_target_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_releases_rest_bad_request(request_type=cloud_deploy.ListReleasesRequest): @@ -33135,10 +33284,13 @@ def test_list_releases_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_list_releases" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_list_releases_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_list_releases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ListReleasesRequest.pb( cloud_deploy.ListReleasesRequest() ) @@ -33164,6 +33316,7 @@ def test_list_releases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ListReleasesResponse() + post_with_metadata.return_value = cloud_deploy.ListReleasesResponse(), metadata client.list_releases( request, @@ -33175,6 +33328,7 @@ def test_list_releases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_release_rest_bad_request(request_type=cloud_deploy.GetReleaseRequest): @@ -33277,10 +33431,13 @@ def test_get_release_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_release" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_get_release_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_release" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetReleaseRequest.pb(cloud_deploy.GetReleaseRequest()) transcode.return_value = { "method": "post", @@ -33302,6 +33459,7 @@ def test_get_release_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.Release() + post_with_metadata.return_value = cloud_deploy.Release(), metadata client.get_release( request, @@ -33313,6 +33471,7 @@ def test_get_release_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_release_rest_bad_request( @@ -33690,10 +33849,13 @@ def test_create_release_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_create_release" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_create_release_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_create_release" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.CreateReleaseRequest.pb( cloud_deploy.CreateReleaseRequest() ) @@ -33717,6 +33879,7 @@ def test_create_release_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_release( request, @@ -33728,6 +33891,7 @@ def test_create_release_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_abandon_release_rest_bad_request( @@ -33813,10 +33977,13 @@ def test_abandon_release_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_abandon_release" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_abandon_release_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_abandon_release" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.AbandonReleaseRequest.pb( cloud_deploy.AbandonReleaseRequest() ) @@ -33842,6 +34009,10 @@ def test_abandon_release_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.AbandonReleaseResponse() + post_with_metadata.return_value = ( + cloud_deploy.AbandonReleaseResponse(), + metadata, + ) client.abandon_release( request, @@ -33853,6 +34024,7 @@ def test_abandon_release_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_deploy_policy_rest_bad_request( @@ -34045,10 +34217,13 @@ def test_create_deploy_policy_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_create_deploy_policy" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_create_deploy_policy_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_create_deploy_policy" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.CreateDeployPolicyRequest.pb( cloud_deploy.CreateDeployPolicyRequest() ) @@ -34072,6 +34247,7 @@ def test_create_deploy_policy_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_deploy_policy( request, @@ -34083,6 +34259,7 @@ def test_create_deploy_policy_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_deploy_policy_rest_bad_request( @@ -34283,10 +34460,13 @@ def test_update_deploy_policy_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_update_deploy_policy" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_update_deploy_policy_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_update_deploy_policy" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.UpdateDeployPolicyRequest.pb( cloud_deploy.UpdateDeployPolicyRequest() ) @@ -34310,6 +34490,7 @@ def test_update_deploy_policy_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_deploy_policy( request, @@ -34321,6 +34502,7 @@ def test_update_deploy_policy_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_deploy_policy_rest_bad_request( @@ -34401,10 +34583,13 @@ def test_delete_deploy_policy_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_delete_deploy_policy" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_delete_deploy_policy_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_delete_deploy_policy" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.DeleteDeployPolicyRequest.pb( cloud_deploy.DeleteDeployPolicyRequest() ) @@ -34428,6 +34613,7 @@ def test_delete_deploy_policy_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_deploy_policy( request, @@ -34439,6 +34625,7 @@ def test_delete_deploy_policy_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_deploy_policies_rest_bad_request( @@ -34525,10 +34712,13 @@ def test_list_deploy_policies_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_list_deploy_policies" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_list_deploy_policies_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_list_deploy_policies" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ListDeployPoliciesRequest.pb( cloud_deploy.ListDeployPoliciesRequest() ) @@ -34554,6 +34744,10 @@ def test_list_deploy_policies_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ListDeployPoliciesResponse() + post_with_metadata.return_value = ( + cloud_deploy.ListDeployPoliciesResponse(), + metadata, + ) client.list_deploy_policies( request, @@ -34565,6 +34759,7 @@ def test_list_deploy_policies_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_deploy_policy_rest_bad_request( @@ -34657,10 +34852,13 @@ def test_get_deploy_policy_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_deploy_policy" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_get_deploy_policy_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_deploy_policy" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetDeployPolicyRequest.pb( cloud_deploy.GetDeployPolicyRequest() ) @@ -34684,6 +34882,7 @@ def test_get_deploy_policy_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.DeployPolicy() + post_with_metadata.return_value = cloud_deploy.DeployPolicy(), metadata client.get_deploy_policy( request, @@ -34695,6 +34894,7 @@ def test_get_deploy_policy_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_approve_rollout_rest_bad_request( @@ -34780,10 +34980,13 @@ def test_approve_rollout_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_approve_rollout" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_approve_rollout_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_approve_rollout" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ApproveRolloutRequest.pb( cloud_deploy.ApproveRolloutRequest() ) @@ -34809,6 +35012,10 @@ def test_approve_rollout_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ApproveRolloutResponse() + post_with_metadata.return_value = ( + cloud_deploy.ApproveRolloutResponse(), + metadata, + ) client.approve_rollout( request, @@ -34820,6 +35027,7 @@ def test_approve_rollout_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_advance_rollout_rest_bad_request( @@ -34905,10 +35113,13 @@ def test_advance_rollout_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_advance_rollout" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_advance_rollout_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_advance_rollout" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.AdvanceRolloutRequest.pb( cloud_deploy.AdvanceRolloutRequest() ) @@ -34934,6 +35145,10 @@ def test_advance_rollout_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.AdvanceRolloutResponse() + post_with_metadata.return_value = ( + cloud_deploy.AdvanceRolloutResponse(), + metadata, + ) client.advance_rollout( request, @@ -34945,6 +35160,7 @@ def test_advance_rollout_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_rollout_rest_bad_request( @@ -35030,10 +35246,13 @@ def test_cancel_rollout_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_cancel_rollout" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_cancel_rollout_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_cancel_rollout" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.CancelRolloutRequest.pb( cloud_deploy.CancelRolloutRequest() ) @@ -35059,6 +35278,7 @@ def test_cancel_rollout_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.CancelRolloutResponse() + post_with_metadata.return_value = cloud_deploy.CancelRolloutResponse(), metadata client.cancel_rollout( request, @@ -35070,6 +35290,7 @@ def test_cancel_rollout_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_rollouts_rest_bad_request(request_type=cloud_deploy.ListRolloutsRequest): @@ -35158,10 +35379,13 @@ def test_list_rollouts_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_list_rollouts" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_list_rollouts_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_list_rollouts" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ListRolloutsRequest.pb( cloud_deploy.ListRolloutsRequest() ) @@ -35187,6 +35411,7 @@ def test_list_rollouts_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ListRolloutsResponse() + post_with_metadata.return_value = cloud_deploy.ListRolloutsResponse(), metadata client.list_rollouts( request, @@ -35198,6 +35423,7 @@ def test_list_rollouts_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_rollout_rest_bad_request(request_type=cloud_deploy.GetRolloutRequest): @@ -35313,10 +35539,13 @@ def test_get_rollout_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_rollout" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_get_rollout_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_rollout" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetRolloutRequest.pb(cloud_deploy.GetRolloutRequest()) transcode.return_value = { "method": "post", @@ -35338,6 +35567,7 @@ def test_get_rollout_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.Rollout() + post_with_metadata.return_value = cloud_deploy.Rollout(), metadata client.get_rollout( request, @@ -35349,6 +35579,7 @@ def test_get_rollout_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_rollout_rest_bad_request( @@ -35578,10 +35809,13 @@ def test_create_rollout_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_create_rollout" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_create_rollout_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_create_rollout" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.CreateRolloutRequest.pb( cloud_deploy.CreateRolloutRequest() ) @@ -35605,6 +35839,7 @@ def test_create_rollout_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_rollout( request, @@ -35616,6 +35851,7 @@ def test_create_rollout_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_ignore_job_rest_bad_request(request_type=cloud_deploy.IgnoreJobRequest): @@ -35699,10 +35935,13 @@ def test_ignore_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_ignore_job" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_ignore_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_ignore_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.IgnoreJobRequest.pb(cloud_deploy.IgnoreJobRequest()) transcode.return_value = { "method": "post", @@ -35726,6 +35965,7 @@ def test_ignore_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.IgnoreJobResponse() + post_with_metadata.return_value = cloud_deploy.IgnoreJobResponse(), metadata client.ignore_job( request, @@ -35737,6 +35977,7 @@ def test_ignore_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_retry_job_rest_bad_request(request_type=cloud_deploy.RetryJobRequest): @@ -35820,10 +36061,13 @@ def test_retry_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_retry_job" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_retry_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_retry_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.RetryJobRequest.pb(cloud_deploy.RetryJobRequest()) transcode.return_value = { "method": "post", @@ -35847,6 +36091,7 @@ def test_retry_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.RetryJobResponse() + post_with_metadata.return_value = cloud_deploy.RetryJobResponse(), metadata client.retry_job( request, @@ -35858,6 +36103,7 @@ def test_retry_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_job_runs_rest_bad_request(request_type=cloud_deploy.ListJobRunsRequest): @@ -35946,10 +36192,13 @@ def test_list_job_runs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_list_job_runs" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_list_job_runs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_list_job_runs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ListJobRunsRequest.pb( cloud_deploy.ListJobRunsRequest() ) @@ -35975,6 +36224,7 @@ def test_list_job_runs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ListJobRunsResponse() + post_with_metadata.return_value = cloud_deploy.ListJobRunsResponse(), metadata client.list_job_runs( request, @@ -35986,6 +36236,7 @@ def test_list_job_runs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_job_run_rest_bad_request(request_type=cloud_deploy.GetJobRunRequest): @@ -36082,10 +36333,13 @@ def test_get_job_run_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_job_run" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_get_job_run_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_job_run" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetJobRunRequest.pb(cloud_deploy.GetJobRunRequest()) transcode.return_value = { "method": "post", @@ -36107,6 +36361,7 @@ def test_get_job_run_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.JobRun() + post_with_metadata.return_value = cloud_deploy.JobRun(), metadata client.get_job_run( request, @@ -36118,6 +36373,7 @@ def test_get_job_run_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_terminate_job_run_rest_bad_request( @@ -36203,10 +36459,13 @@ def test_terminate_job_run_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_terminate_job_run" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_terminate_job_run_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_terminate_job_run" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.TerminateJobRunRequest.pb( cloud_deploy.TerminateJobRunRequest() ) @@ -36232,6 +36491,10 @@ def test_terminate_job_run_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.TerminateJobRunResponse() + post_with_metadata.return_value = ( + cloud_deploy.TerminateJobRunResponse(), + metadata, + ) client.terminate_job_run( request, @@ -36243,6 +36506,7 @@ def test_terminate_job_run_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_config_rest_bad_request(request_type=cloud_deploy.GetConfigRequest): @@ -36327,10 +36591,13 @@ def test_get_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_config" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_get_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetConfigRequest.pb(cloud_deploy.GetConfigRequest()) transcode.return_value = { "method": "post", @@ -36352,6 +36619,7 @@ def test_get_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.Config() + post_with_metadata.return_value = cloud_deploy.Config(), metadata client.get_config( request, @@ -36363,6 +36631,7 @@ def test_get_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_automation_rest_bad_request( @@ -36585,10 +36854,13 @@ def test_create_automation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_create_automation" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_create_automation_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_create_automation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.CreateAutomationRequest.pb( cloud_deploy.CreateAutomationRequest() ) @@ -36612,6 +36884,7 @@ def test_create_automation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_automation( request, @@ -36623,6 +36896,7 @@ def test_create_automation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_automation_rest_bad_request( @@ -36849,10 +37123,13 @@ def test_update_automation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_update_automation" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_update_automation_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_update_automation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.UpdateAutomationRequest.pb( cloud_deploy.UpdateAutomationRequest() ) @@ -36876,6 +37153,7 @@ def test_update_automation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_automation( request, @@ -36887,6 +37165,7 @@ def test_update_automation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_automation_rest_bad_request( @@ -36971,10 +37250,13 @@ def test_delete_automation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CloudDeployRestInterceptor, "post_delete_automation" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_delete_automation_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_delete_automation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.DeleteAutomationRequest.pb( cloud_deploy.DeleteAutomationRequest() ) @@ -36998,6 +37280,7 @@ def test_delete_automation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_automation( request, @@ -37009,6 +37292,7 @@ def test_delete_automation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_automation_rest_bad_request( @@ -37107,10 +37391,13 @@ def test_get_automation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_automation" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_get_automation_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_automation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetAutomationRequest.pb( cloud_deploy.GetAutomationRequest() ) @@ -37134,6 +37421,7 @@ def test_get_automation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.Automation() + post_with_metadata.return_value = cloud_deploy.Automation(), metadata client.get_automation( request, @@ -37145,6 +37433,7 @@ def test_get_automation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_automations_rest_bad_request( @@ -37235,10 +37524,13 @@ def test_list_automations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_list_automations" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_list_automations_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_list_automations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ListAutomationsRequest.pb( cloud_deploy.ListAutomationsRequest() ) @@ -37264,6 +37556,10 @@ def test_list_automations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ListAutomationsResponse() + post_with_metadata.return_value = ( + cloud_deploy.ListAutomationsResponse(), + metadata, + ) client.list_automations( request, @@ -37275,6 +37571,7 @@ def test_list_automations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_automation_run_rest_bad_request( @@ -37377,10 +37674,13 @@ def test_get_automation_run_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_get_automation_run" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_get_automation_run_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_get_automation_run" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.GetAutomationRunRequest.pb( cloud_deploy.GetAutomationRunRequest() ) @@ -37404,6 +37704,7 @@ def test_get_automation_run_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.AutomationRun() + post_with_metadata.return_value = cloud_deploy.AutomationRun(), metadata client.get_automation_run( request, @@ -37415,6 +37716,7 @@ def test_get_automation_run_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_automation_runs_rest_bad_request( @@ -37505,10 +37807,13 @@ def test_list_automation_runs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_list_automation_runs" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, "post_list_automation_runs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_list_automation_runs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.ListAutomationRunsRequest.pb( cloud_deploy.ListAutomationRunsRequest() ) @@ -37534,6 +37839,10 @@ def test_list_automation_runs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.ListAutomationRunsResponse() + post_with_metadata.return_value = ( + cloud_deploy.ListAutomationRunsResponse(), + metadata, + ) client.list_automation_runs( request, @@ -37545,6 +37854,7 @@ def test_list_automation_runs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_automation_run_rest_bad_request( @@ -37630,10 +37940,14 @@ def test_cancel_automation_run_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CloudDeployRestInterceptor, "post_cancel_automation_run" ) as post, mock.patch.object( + transports.CloudDeployRestInterceptor, + "post_cancel_automation_run_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CloudDeployRestInterceptor, "pre_cancel_automation_run" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = cloud_deploy.CancelAutomationRunRequest.pb( cloud_deploy.CancelAutomationRunRequest() ) @@ -37659,6 +37973,10 @@ def test_cancel_automation_run_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = cloud_deploy.CancelAutomationRunResponse() + post_with_metadata.return_value = ( + cloud_deploy.CancelAutomationRunResponse(), + metadata, + ) client.cancel_automation_run( request, @@ -37670,6 +37988,7 @@ def test_cancel_automation_run_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-developerconnect/google/cloud/developerconnect/gapic_version.py b/packages/google-cloud-developerconnect/google/cloud/developerconnect/gapic_version.py index 51d2795b9d6b..558c8aab67c5 100644 --- a/packages/google-cloud-developerconnect/google/cloud/developerconnect/gapic_version.py +++ b/packages/google-cloud-developerconnect/google/cloud/developerconnect/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.6" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/gapic_version.py b/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/gapic_version.py index 51d2795b9d6b..558c8aab67c5 100644 --- a/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/gapic_version.py +++ b/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.6" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/services/developer_connect/client.py b/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/services/developer_connect/client.py index 134b9ac4e341..0cab9cbed5db 100644 --- a/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/services/developer_connect/client.py +++ b/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/services/developer_connect/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -588,6 +590,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2580,16 +2609,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2635,16 +2668,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -2801,16 +2838,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2856,16 +2897,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/services/developer_connect/transports/rest.py b/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/services/developer_connect/transports/rest.py index 4dec0bdacd8c..b632621bb8d5 100644 --- a/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/services/developer_connect/transports/rest.py +++ b/packages/google-cloud-developerconnect/google/cloud/developerconnect_v1/services/developer_connect/transports/rest.py @@ -208,12 +208,35 @@ def post_create_connection( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_create_connection` interceptor runs + before the `post_create_connection_with_metadata` interceptor. """ return response + def post_create_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_create_connection_with_metadata` + interceptor in new development instead of the `post_create_connection` interceptor. + When both interceptors are used, this `post_create_connection_with_metadata` interceptor runs after the + `post_create_connection` interceptor. The (possibly modified) response returned by + `post_create_connection` will be passed to + `post_create_connection_with_metadata`. + """ + return response, metadata + def pre_create_git_repository_link( self, request: developer_connect.CreateGitRepositoryLinkRequest, @@ -234,12 +257,35 @@ def post_create_git_repository_link( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_git_repository_link - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_git_repository_link_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_create_git_repository_link` interceptor runs + before the `post_create_git_repository_link_with_metadata` interceptor. """ return response + def post_create_git_repository_link_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_git_repository_link + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_create_git_repository_link_with_metadata` + interceptor in new development instead of the `post_create_git_repository_link` interceptor. + When both interceptors are used, this `post_create_git_repository_link_with_metadata` interceptor runs after the + `post_create_git_repository_link` interceptor. The (possibly modified) response returned by + `post_create_git_repository_link` will be passed to + `post_create_git_repository_link_with_metadata`. + """ + return response, metadata + def pre_delete_connection( self, request: developer_connect.DeleteConnectionRequest, @@ -260,12 +306,35 @@ def post_delete_connection( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_delete_connection` interceptor runs + before the `post_delete_connection_with_metadata` interceptor. """ return response + def post_delete_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_delete_connection_with_metadata` + interceptor in new development instead of the `post_delete_connection` interceptor. + When both interceptors are used, this `post_delete_connection_with_metadata` interceptor runs after the + `post_delete_connection` interceptor. The (possibly modified) response returned by + `post_delete_connection` will be passed to + `post_delete_connection_with_metadata`. + """ + return response, metadata + def pre_delete_git_repository_link( self, request: developer_connect.DeleteGitRepositoryLinkRequest, @@ -286,12 +355,35 @@ def post_delete_git_repository_link( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_git_repository_link - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_git_repository_link_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_delete_git_repository_link` interceptor runs + before the `post_delete_git_repository_link_with_metadata` interceptor. """ return response + def post_delete_git_repository_link_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_git_repository_link + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_delete_git_repository_link_with_metadata` + interceptor in new development instead of the `post_delete_git_repository_link` interceptor. + When both interceptors are used, this `post_delete_git_repository_link_with_metadata` interceptor runs after the + `post_delete_git_repository_link` interceptor. The (possibly modified) response returned by + `post_delete_git_repository_link` will be passed to + `post_delete_git_repository_link_with_metadata`. + """ + return response, metadata + def pre_fetch_git_hub_installations( self, request: developer_connect.FetchGitHubInstallationsRequest, @@ -312,12 +404,38 @@ def post_fetch_git_hub_installations( ) -> developer_connect.FetchGitHubInstallationsResponse: """Post-rpc interceptor for fetch_git_hub_installations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_git_hub_installations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_fetch_git_hub_installations` interceptor runs + before the `post_fetch_git_hub_installations_with_metadata` interceptor. """ return response + def post_fetch_git_hub_installations_with_metadata( + self, + response: developer_connect.FetchGitHubInstallationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developer_connect.FetchGitHubInstallationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for fetch_git_hub_installations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_fetch_git_hub_installations_with_metadata` + interceptor in new development instead of the `post_fetch_git_hub_installations` interceptor. + When both interceptors are used, this `post_fetch_git_hub_installations_with_metadata` interceptor runs after the + `post_fetch_git_hub_installations` interceptor. The (possibly modified) response returned by + `post_fetch_git_hub_installations` will be passed to + `post_fetch_git_hub_installations_with_metadata`. + """ + return response, metadata + def pre_fetch_git_refs( self, request: developer_connect.FetchGitRefsRequest, @@ -337,12 +455,37 @@ def post_fetch_git_refs( ) -> developer_connect.FetchGitRefsResponse: """Post-rpc interceptor for fetch_git_refs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_git_refs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_fetch_git_refs` interceptor runs + before the `post_fetch_git_refs_with_metadata` interceptor. """ return response + def post_fetch_git_refs_with_metadata( + self, + response: developer_connect.FetchGitRefsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developer_connect.FetchGitRefsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for fetch_git_refs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_fetch_git_refs_with_metadata` + interceptor in new development instead of the `post_fetch_git_refs` interceptor. + When both interceptors are used, this `post_fetch_git_refs_with_metadata` interceptor runs after the + `post_fetch_git_refs` interceptor. The (possibly modified) response returned by + `post_fetch_git_refs` will be passed to + `post_fetch_git_refs_with_metadata`. + """ + return response, metadata + def pre_fetch_linkable_git_repositories( self, request: developer_connect.FetchLinkableGitRepositoriesRequest, @@ -363,12 +506,38 @@ def post_fetch_linkable_git_repositories( ) -> developer_connect.FetchLinkableGitRepositoriesResponse: """Post-rpc interceptor for fetch_linkable_git_repositories - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_linkable_git_repositories_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_fetch_linkable_git_repositories` interceptor runs + before the `post_fetch_linkable_git_repositories_with_metadata` interceptor. """ return response + def post_fetch_linkable_git_repositories_with_metadata( + self, + response: developer_connect.FetchLinkableGitRepositoriesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developer_connect.FetchLinkableGitRepositoriesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for fetch_linkable_git_repositories + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_fetch_linkable_git_repositories_with_metadata` + interceptor in new development instead of the `post_fetch_linkable_git_repositories` interceptor. + When both interceptors are used, this `post_fetch_linkable_git_repositories_with_metadata` interceptor runs after the + `post_fetch_linkable_git_repositories` interceptor. The (possibly modified) response returned by + `post_fetch_linkable_git_repositories` will be passed to + `post_fetch_linkable_git_repositories_with_metadata`. + """ + return response, metadata + def pre_fetch_read_token( self, request: developer_connect.FetchReadTokenRequest, @@ -388,12 +557,38 @@ def post_fetch_read_token( ) -> developer_connect.FetchReadTokenResponse: """Post-rpc interceptor for fetch_read_token - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_read_token_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_fetch_read_token` interceptor runs + before the `post_fetch_read_token_with_metadata` interceptor. """ return response + def post_fetch_read_token_with_metadata( + self, + response: developer_connect.FetchReadTokenResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developer_connect.FetchReadTokenResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for fetch_read_token + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_fetch_read_token_with_metadata` + interceptor in new development instead of the `post_fetch_read_token` interceptor. + When both interceptors are used, this `post_fetch_read_token_with_metadata` interceptor runs after the + `post_fetch_read_token` interceptor. The (possibly modified) response returned by + `post_fetch_read_token` will be passed to + `post_fetch_read_token_with_metadata`. + """ + return response, metadata + def pre_fetch_read_write_token( self, request: developer_connect.FetchReadWriteTokenRequest, @@ -414,12 +609,38 @@ def post_fetch_read_write_token( ) -> developer_connect.FetchReadWriteTokenResponse: """Post-rpc interceptor for fetch_read_write_token - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_read_write_token_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_fetch_read_write_token` interceptor runs + before the `post_fetch_read_write_token_with_metadata` interceptor. """ return response + def post_fetch_read_write_token_with_metadata( + self, + response: developer_connect.FetchReadWriteTokenResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developer_connect.FetchReadWriteTokenResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for fetch_read_write_token + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_fetch_read_write_token_with_metadata` + interceptor in new development instead of the `post_fetch_read_write_token` interceptor. + When both interceptors are used, this `post_fetch_read_write_token_with_metadata` interceptor runs after the + `post_fetch_read_write_token` interceptor. The (possibly modified) response returned by + `post_fetch_read_write_token` will be passed to + `post_fetch_read_write_token_with_metadata`. + """ + return response, metadata + def pre_get_connection( self, request: developer_connect.GetConnectionRequest, @@ -439,12 +660,35 @@ def post_get_connection( ) -> developer_connect.Connection: """Post-rpc interceptor for get_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_get_connection` interceptor runs + before the `post_get_connection_with_metadata` interceptor. """ return response + def post_get_connection_with_metadata( + self, + response: developer_connect.Connection, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[developer_connect.Connection, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_get_connection_with_metadata` + interceptor in new development instead of the `post_get_connection` interceptor. + When both interceptors are used, this `post_get_connection_with_metadata` interceptor runs after the + `post_get_connection` interceptor. The (possibly modified) response returned by + `post_get_connection` will be passed to + `post_get_connection_with_metadata`. + """ + return response, metadata + def pre_get_git_repository_link( self, request: developer_connect.GetGitRepositoryLinkRequest, @@ -465,12 +709,37 @@ def post_get_git_repository_link( ) -> developer_connect.GitRepositoryLink: """Post-rpc interceptor for get_git_repository_link - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_git_repository_link_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_get_git_repository_link` interceptor runs + before the `post_get_git_repository_link_with_metadata` interceptor. """ return response + def post_get_git_repository_link_with_metadata( + self, + response: developer_connect.GitRepositoryLink, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developer_connect.GitRepositoryLink, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_git_repository_link + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_get_git_repository_link_with_metadata` + interceptor in new development instead of the `post_get_git_repository_link` interceptor. + When both interceptors are used, this `post_get_git_repository_link_with_metadata` interceptor runs after the + `post_get_git_repository_link` interceptor. The (possibly modified) response returned by + `post_get_git_repository_link` will be passed to + `post_get_git_repository_link_with_metadata`. + """ + return response, metadata + def pre_list_connections( self, request: developer_connect.ListConnectionsRequest, @@ -491,12 +760,38 @@ def post_list_connections( ) -> developer_connect.ListConnectionsResponse: """Post-rpc interceptor for list_connections - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_connections_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_list_connections` interceptor runs + before the `post_list_connections_with_metadata` interceptor. """ return response + def post_list_connections_with_metadata( + self, + response: developer_connect.ListConnectionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developer_connect.ListConnectionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_connections + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_list_connections_with_metadata` + interceptor in new development instead of the `post_list_connections` interceptor. + When both interceptors are used, this `post_list_connections_with_metadata` interceptor runs after the + `post_list_connections` interceptor. The (possibly modified) response returned by + `post_list_connections` will be passed to + `post_list_connections_with_metadata`. + """ + return response, metadata + def pre_list_git_repository_links( self, request: developer_connect.ListGitRepositoryLinksRequest, @@ -517,12 +812,38 @@ def post_list_git_repository_links( ) -> developer_connect.ListGitRepositoryLinksResponse: """Post-rpc interceptor for list_git_repository_links - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_git_repository_links_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_list_git_repository_links` interceptor runs + before the `post_list_git_repository_links_with_metadata` interceptor. """ return response + def post_list_git_repository_links_with_metadata( + self, + response: developer_connect.ListGitRepositoryLinksResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + developer_connect.ListGitRepositoryLinksResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_git_repository_links + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_list_git_repository_links_with_metadata` + interceptor in new development instead of the `post_list_git_repository_links` interceptor. + When both interceptors are used, this `post_list_git_repository_links_with_metadata` interceptor runs after the + `post_list_git_repository_links` interceptor. The (possibly modified) response returned by + `post_list_git_repository_links` will be passed to + `post_list_git_repository_links_with_metadata`. + """ + return response, metadata + def pre_update_connection( self, request: developer_connect.UpdateConnectionRequest, @@ -543,12 +864,35 @@ def post_update_connection( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DeveloperConnect server but before - it is returned to user code. + it is returned to user code. This `post_update_connection` interceptor runs + before the `post_update_connection_with_metadata` interceptor. """ return response + def post_update_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DeveloperConnect server but before it is returned to user code. + + We recommend only using this `post_update_connection_with_metadata` + interceptor in new development instead of the `post_update_connection` interceptor. + When both interceptors are used, this `post_update_connection_with_metadata` interceptor runs after the + `post_update_connection` interceptor. The (possibly modified) response returned by + `post_update_connection` will be passed to + `post_update_connection_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -963,6 +1307,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1117,6 +1465,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_git_repository_link(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_git_repository_link_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1261,6 +1613,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1409,6 +1765,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_git_repository_link(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_git_repository_link_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1558,6 +1918,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_git_hub_installations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_git_hub_installations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1702,6 +2066,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_git_refs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_git_refs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1851,6 +2219,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_linkable_git_repositories(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_fetch_linkable_git_repositories_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2005,6 +2380,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_read_token(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_read_token_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2159,6 +2538,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_read_write_token(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_read_write_token_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2301,6 +2684,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2449,6 +2836,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_git_repository_link(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_git_repository_link_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2597,6 +2988,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_connections(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_connections_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2747,6 +3142,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_git_repository_links(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_git_repository_links_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2901,6 +3300,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-developerconnect/samples/generated_samples/snippet_metadata_google.cloud.developerconnect.v1.json b/packages/google-cloud-developerconnect/samples/generated_samples/snippet_metadata_google.cloud.developerconnect.v1.json index ad7feba7c0ba..f01375bb231f 100644 --- a/packages/google-cloud-developerconnect/samples/generated_samples/snippet_metadata_google.cloud.developerconnect.v1.json +++ b/packages/google-cloud-developerconnect/samples/generated_samples/snippet_metadata_google.cloud.developerconnect.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-developerconnect", - "version": "0.1.6" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-developerconnect/tests/unit/gapic/developerconnect_v1/test_developer_connect.py b/packages/google-cloud-developerconnect/tests/unit/gapic/developerconnect_v1/test_developer_connect.py index 1421dbac69c1..2802719629a9 100644 --- a/packages/google-cloud-developerconnect/tests/unit/gapic/developerconnect_v1/test_developer_connect.py +++ b/packages/google-cloud-developerconnect/tests/unit/gapic/developerconnect_v1/test_developer_connect.py @@ -74,6 +74,13 @@ ) from google.cloud.developerconnect_v1.types import developer_connect +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -333,6 +340,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DeveloperConnectClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DeveloperConnectClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -10820,10 +10870,14 @@ def test_list_connections_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_list_connections" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_list_connections_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_list_connections" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.ListConnectionsRequest.pb( developer_connect.ListConnectionsRequest() ) @@ -10849,6 +10903,10 @@ def test_list_connections_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = developer_connect.ListConnectionsResponse() + post_with_metadata.return_value = ( + developer_connect.ListConnectionsResponse(), + metadata, + ) client.list_connections( request, @@ -10860,6 +10918,7 @@ def test_list_connections_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_connection_rest_bad_request( @@ -10952,10 +11011,13 @@ def test_get_connection_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_get_connection" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, "post_get_connection_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_get_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.GetConnectionRequest.pb( developer_connect.GetConnectionRequest() ) @@ -10981,6 +11043,7 @@ def test_get_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = developer_connect.Connection() + post_with_metadata.return_value = developer_connect.Connection(), metadata client.get_connection( request, @@ -10992,6 +11055,7 @@ def test_get_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_connection_rest_bad_request( @@ -11195,10 +11259,14 @@ def test_create_connection_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_create_connection" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_create_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_create_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.CreateConnectionRequest.pb( developer_connect.CreateConnectionRequest() ) @@ -11222,6 +11290,7 @@ def test_create_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_connection( request, @@ -11233,6 +11302,7 @@ def test_create_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_connection_rest_bad_request( @@ -11440,10 +11510,14 @@ def test_update_connection_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_update_connection" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_update_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_update_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.UpdateConnectionRequest.pb( developer_connect.UpdateConnectionRequest() ) @@ -11467,6 +11541,7 @@ def test_update_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_connection( request, @@ -11478,6 +11553,7 @@ def test_update_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_connection_rest_bad_request( @@ -11558,10 +11634,14 @@ def test_delete_connection_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_delete_connection" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_delete_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_delete_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.DeleteConnectionRequest.pb( developer_connect.DeleteConnectionRequest() ) @@ -11585,6 +11665,7 @@ def test_delete_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_connection( request, @@ -11596,6 +11677,7 @@ def test_delete_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_git_repository_link_rest_bad_request( @@ -11758,10 +11840,14 @@ def test_create_git_repository_link_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_create_git_repository_link" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_create_git_repository_link_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_create_git_repository_link" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.CreateGitRepositoryLinkRequest.pb( developer_connect.CreateGitRepositoryLinkRequest() ) @@ -11785,6 +11871,7 @@ def test_create_git_repository_link_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_git_repository_link( request, @@ -11796,6 +11883,7 @@ def test_create_git_repository_link_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_git_repository_link_rest_bad_request( @@ -11880,10 +11968,14 @@ def test_delete_git_repository_link_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_delete_git_repository_link" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_delete_git_repository_link_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_delete_git_repository_link" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.DeleteGitRepositoryLinkRequest.pb( developer_connect.DeleteGitRepositoryLinkRequest() ) @@ -11907,6 +11999,7 @@ def test_delete_git_repository_link_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_git_repository_link( request, @@ -11918,6 +12011,7 @@ def test_delete_git_repository_link_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_git_repository_links_rest_bad_request( @@ -12004,10 +12098,14 @@ def test_list_git_repository_links_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_list_git_repository_links" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_list_git_repository_links_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_list_git_repository_links" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.ListGitRepositoryLinksRequest.pb( developer_connect.ListGitRepositoryLinksRequest() ) @@ -12033,6 +12131,10 @@ def test_list_git_repository_links_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = developer_connect.ListGitRepositoryLinksResponse() + post_with_metadata.return_value = ( + developer_connect.ListGitRepositoryLinksResponse(), + metadata, + ) client.list_git_repository_links( request, @@ -12044,6 +12146,7 @@ def test_list_git_repository_links_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_git_repository_link_rest_bad_request( @@ -12142,10 +12245,14 @@ def test_get_git_repository_link_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_get_git_repository_link" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_get_git_repository_link_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_get_git_repository_link" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.GetGitRepositoryLinkRequest.pb( developer_connect.GetGitRepositoryLinkRequest() ) @@ -12171,6 +12278,10 @@ def test_get_git_repository_link_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = developer_connect.GitRepositoryLink() + post_with_metadata.return_value = ( + developer_connect.GitRepositoryLink(), + metadata, + ) client.get_git_repository_link( request, @@ -12182,6 +12293,7 @@ def test_get_git_repository_link_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_read_write_token_rest_bad_request( @@ -12272,10 +12384,14 @@ def test_fetch_read_write_token_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_fetch_read_write_token" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_fetch_read_write_token_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_fetch_read_write_token" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.FetchReadWriteTokenRequest.pb( developer_connect.FetchReadWriteTokenRequest() ) @@ -12301,6 +12417,10 @@ def test_fetch_read_write_token_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = developer_connect.FetchReadWriteTokenResponse() + post_with_metadata.return_value = ( + developer_connect.FetchReadWriteTokenResponse(), + metadata, + ) client.fetch_read_write_token( request, @@ -12312,6 +12432,7 @@ def test_fetch_read_write_token_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_read_token_rest_bad_request( @@ -12402,10 +12523,14 @@ def test_fetch_read_token_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_fetch_read_token" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_fetch_read_token_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_fetch_read_token" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.FetchReadTokenRequest.pb( developer_connect.FetchReadTokenRequest() ) @@ -12431,6 +12556,10 @@ def test_fetch_read_token_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = developer_connect.FetchReadTokenResponse() + post_with_metadata.return_value = ( + developer_connect.FetchReadTokenResponse(), + metadata, + ) client.fetch_read_token( request, @@ -12442,6 +12571,7 @@ def test_fetch_read_token_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_linkable_git_repositories_rest_bad_request( @@ -12533,11 +12663,15 @@ def test_fetch_linkable_git_repositories_rest_interceptors(null_interceptor): transports.DeveloperConnectRestInterceptor, "post_fetch_linkable_git_repositories", ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_fetch_linkable_git_repositories_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_fetch_linkable_git_repositories", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.FetchLinkableGitRepositoriesRequest.pb( developer_connect.FetchLinkableGitRepositoriesRequest() ) @@ -12563,6 +12697,10 @@ def test_fetch_linkable_git_repositories_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = developer_connect.FetchLinkableGitRepositoriesResponse() + post_with_metadata.return_value = ( + developer_connect.FetchLinkableGitRepositoriesResponse(), + metadata, + ) client.fetch_linkable_git_repositories( request, @@ -12574,6 +12712,7 @@ def test_fetch_linkable_git_repositories_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_git_hub_installations_rest_bad_request( @@ -12661,10 +12800,14 @@ def test_fetch_git_hub_installations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_fetch_git_hub_installations" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, + "post_fetch_git_hub_installations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_fetch_git_hub_installations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.FetchGitHubInstallationsRequest.pb( developer_connect.FetchGitHubInstallationsRequest() ) @@ -12690,6 +12833,10 @@ def test_fetch_git_hub_installations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = developer_connect.FetchGitHubInstallationsResponse() + post_with_metadata.return_value = ( + developer_connect.FetchGitHubInstallationsResponse(), + metadata, + ) client.fetch_git_hub_installations( request, @@ -12701,6 +12848,7 @@ def test_fetch_git_hub_installations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_git_refs_rest_bad_request( @@ -12791,10 +12939,13 @@ def test_fetch_git_refs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeveloperConnectRestInterceptor, "post_fetch_git_refs" ) as post, mock.patch.object( + transports.DeveloperConnectRestInterceptor, "post_fetch_git_refs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DeveloperConnectRestInterceptor, "pre_fetch_git_refs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = developer_connect.FetchGitRefsRequest.pb( developer_connect.FetchGitRefsRequest() ) @@ -12820,6 +12971,10 @@ def test_fetch_git_refs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = developer_connect.FetchGitRefsResponse() + post_with_metadata.return_value = ( + developer_connect.FetchGitRefsResponse(), + metadata, + ) client.fetch_git_refs( request, @@ -12831,6 +12986,7 @@ def test_fetch_git_refs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): 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 e553ae451f41..558c8aab67c5 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.38.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} 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 e553ae451f41..558c8aab67c5 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.38.0" # {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/agents/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/agents/client.py index 737832a1035c..c8f4c0984e15 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/agents/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/agents/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -658,6 +660,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2177,16 +2206,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2232,16 +2265,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2342,16 +2379,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2397,16 +2438,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/agents/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/agents/transports/rest.py index eb8e6052d972..c09dcb6e6432 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/agents/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/agents/transports/rest.py @@ -181,12 +181,35 @@ def pre_create_agent( def post_create_agent(self, response: gcdc_agent.Agent) -> gcdc_agent.Agent: """Post-rpc interceptor for create_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_create_agent` interceptor runs + before the `post_create_agent_with_metadata` interceptor. """ return response + def post_create_agent_with_metadata( + self, + response: gcdc_agent.Agent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_create_agent_with_metadata` + interceptor in new development instead of the `post_create_agent` interceptor. + When both interceptors are used, this `post_create_agent_with_metadata` interceptor runs after the + `post_create_agent` interceptor. The (possibly modified) response returned by + `post_create_agent` will be passed to + `post_create_agent_with_metadata`. + """ + return response, metadata + def pre_delete_agent( self, request: agent.DeleteAgentRequest, @@ -216,12 +239,35 @@ def post_export_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_export_agent` interceptor runs + before the `post_export_agent_with_metadata` interceptor. """ return response + def post_export_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_export_agent_with_metadata` + interceptor in new development instead of the `post_export_agent` interceptor. + When both interceptors are used, this `post_export_agent_with_metadata` interceptor runs after the + `post_export_agent` interceptor. The (possibly modified) response returned by + `post_export_agent` will be passed to + `post_export_agent_with_metadata`. + """ + return response, metadata + def pre_get_agent( self, request: agent.GetAgentRequest, @@ -237,12 +283,33 @@ def pre_get_agent( def post_get_agent(self, response: agent.Agent) -> agent.Agent: """Post-rpc interceptor for get_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_agent` interceptor runs + before the `post_get_agent_with_metadata` interceptor. """ return response + def post_get_agent_with_metadata( + self, response: agent.Agent, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_agent_with_metadata` + interceptor in new development instead of the `post_get_agent` interceptor. + When both interceptors are used, this `post_get_agent_with_metadata` interceptor runs after the + `post_get_agent` interceptor. The (possibly modified) response returned by + `post_get_agent` will be passed to + `post_get_agent_with_metadata`. + """ + return response, metadata + def pre_get_agent_validation_result( self, request: agent.GetAgentValidationResultRequest, @@ -262,12 +329,35 @@ def post_get_agent_validation_result( ) -> agent.AgentValidationResult: """Post-rpc interceptor for get_agent_validation_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_agent_validation_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_agent_validation_result` interceptor runs + before the `post_get_agent_validation_result_with_metadata` interceptor. """ return response + def post_get_agent_validation_result_with_metadata( + self, + response: agent.AgentValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[agent.AgentValidationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_agent_validation_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_agent_validation_result_with_metadata` + interceptor in new development instead of the `post_get_agent_validation_result` interceptor. + When both interceptors are used, this `post_get_agent_validation_result_with_metadata` interceptor runs after the + `post_get_agent_validation_result` interceptor. The (possibly modified) response returned by + `post_get_agent_validation_result` will be passed to + `post_get_agent_validation_result_with_metadata`. + """ + return response, metadata + def pre_get_generative_settings( self, request: agent.GetGenerativeSettingsRequest, @@ -287,12 +377,37 @@ def post_get_generative_settings( ) -> generative_settings.GenerativeSettings: """Post-rpc interceptor for get_generative_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_generative_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_generative_settings` interceptor runs + before the `post_get_generative_settings_with_metadata` interceptor. """ return response + def post_get_generative_settings_with_metadata( + self, + response: generative_settings.GenerativeSettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generative_settings.GenerativeSettings, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_generative_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_generative_settings_with_metadata` + interceptor in new development instead of the `post_get_generative_settings` interceptor. + When both interceptors are used, this `post_get_generative_settings_with_metadata` interceptor runs after the + `post_get_generative_settings` interceptor. The (possibly modified) response returned by + `post_get_generative_settings` will be passed to + `post_get_generative_settings_with_metadata`. + """ + return response, metadata + def pre_list_agents( self, request: agent.ListAgentsRequest, @@ -310,12 +425,35 @@ def post_list_agents( ) -> agent.ListAgentsResponse: """Post-rpc interceptor for list_agents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_agents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_list_agents` interceptor runs + before the `post_list_agents_with_metadata` interceptor. """ return response + def post_list_agents_with_metadata( + self, + response: agent.ListAgentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[agent.ListAgentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_agents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_list_agents_with_metadata` + interceptor in new development instead of the `post_list_agents` interceptor. + When both interceptors are used, this `post_list_agents_with_metadata` interceptor runs after the + `post_list_agents` interceptor. The (possibly modified) response returned by + `post_list_agents` will be passed to + `post_list_agents_with_metadata`. + """ + return response, metadata + def pre_restore_agent( self, request: agent.RestoreAgentRequest, @@ -333,12 +471,35 @@ def post_restore_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for restore_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_restore_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_restore_agent` interceptor runs + before the `post_restore_agent_with_metadata` interceptor. """ return response + def post_restore_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for restore_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_restore_agent_with_metadata` + interceptor in new development instead of the `post_restore_agent` interceptor. + When both interceptors are used, this `post_restore_agent_with_metadata` interceptor runs after the + `post_restore_agent` interceptor. The (possibly modified) response returned by + `post_restore_agent` will be passed to + `post_restore_agent_with_metadata`. + """ + return response, metadata + def pre_update_agent( self, request: gcdc_agent.UpdateAgentRequest, @@ -354,12 +515,35 @@ def pre_update_agent( def post_update_agent(self, response: gcdc_agent.Agent) -> gcdc_agent.Agent: """Post-rpc interceptor for update_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_update_agent` interceptor runs + before the `post_update_agent_with_metadata` interceptor. """ return response + def post_update_agent_with_metadata( + self, + response: gcdc_agent.Agent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_update_agent_with_metadata` + interceptor in new development instead of the `post_update_agent` interceptor. + When both interceptors are used, this `post_update_agent_with_metadata` interceptor runs after the + `post_update_agent` interceptor. The (possibly modified) response returned by + `post_update_agent` will be passed to + `post_update_agent_with_metadata`. + """ + return response, metadata + def pre_update_generative_settings( self, request: agent.UpdateGenerativeSettingsRequest, @@ -379,12 +563,38 @@ def post_update_generative_settings( ) -> gcdc_generative_settings.GenerativeSettings: """Post-rpc interceptor for update_generative_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_generative_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_update_generative_settings` interceptor runs + before the `post_update_generative_settings_with_metadata` interceptor. """ return response + def post_update_generative_settings_with_metadata( + self, + response: gcdc_generative_settings.GenerativeSettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_generative_settings.GenerativeSettings, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_generative_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_update_generative_settings_with_metadata` + interceptor in new development instead of the `post_update_generative_settings` interceptor. + When both interceptors are used, this `post_update_generative_settings_with_metadata` interceptor runs after the + `post_update_generative_settings` interceptor. The (possibly modified) response returned by + `post_update_generative_settings` will be passed to + `post_update_generative_settings_with_metadata`. + """ + return response, metadata + def pre_validate_agent( self, request: agent.ValidateAgentRequest, @@ -402,12 +612,35 @@ def post_validate_agent( ) -> agent.AgentValidationResult: """Post-rpc interceptor for validate_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_validate_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_validate_agent` interceptor runs + before the `post_validate_agent_with_metadata` interceptor. """ return response + def post_validate_agent_with_metadata( + self, + response: agent.AgentValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[agent.AgentValidationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for validate_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_validate_agent_with_metadata` + interceptor in new development instead of the `post_validate_agent` interceptor. + When both interceptors are used, this `post_validate_agent_with_metadata` interceptor runs after the + `post_validate_agent` interceptor. The (possibly modified) response returned by + `post_validate_agent` will be passed to + `post_validate_agent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -815,6 +1048,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1070,6 +1307,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1225,6 +1466,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1371,6 +1616,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_agent_validation_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_agent_validation_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1515,6 +1764,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_generative_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_generative_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1660,6 +1913,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_agents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_agents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1810,6 +2067,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_restore_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_restore_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1971,6 +2232,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2122,6 +2387,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_generative_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_generative_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2275,6 +2544,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_validate_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_validate_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/changelogs/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/changelogs/client.py index 7ea16ff359c0..3dcd189df232 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/changelogs/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/changelogs/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -490,6 +492,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -965,16 +994,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1020,16 +1053,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1130,16 +1167,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1185,16 +1226,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/changelogs/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/changelogs/transports/rest.py index 679423ef23ff..a1cabbfca117 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/changelogs/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/changelogs/transports/rest.py @@ -107,12 +107,35 @@ def pre_get_changelog( def post_get_changelog(self, response: changelog.Changelog) -> changelog.Changelog: """Post-rpc interceptor for get_changelog - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_changelog_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Changelogs server but before - it is returned to user code. + it is returned to user code. This `post_get_changelog` interceptor runs + before the `post_get_changelog_with_metadata` interceptor. """ return response + def post_get_changelog_with_metadata( + self, + response: changelog.Changelog, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[changelog.Changelog, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_changelog + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Changelogs server but before it is returned to user code. + + We recommend only using this `post_get_changelog_with_metadata` + interceptor in new development instead of the `post_get_changelog` interceptor. + When both interceptors are used, this `post_get_changelog_with_metadata` interceptor runs after the + `post_get_changelog` interceptor. The (possibly modified) response returned by + `post_get_changelog` will be passed to + `post_get_changelog_with_metadata`. + """ + return response, metadata + def pre_list_changelogs( self, request: changelog.ListChangelogsRequest, @@ -132,12 +155,37 @@ def post_list_changelogs( ) -> changelog.ListChangelogsResponse: """Post-rpc interceptor for list_changelogs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_changelogs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Changelogs server but before - it is returned to user code. + it is returned to user code. This `post_list_changelogs` interceptor runs + before the `post_list_changelogs_with_metadata` interceptor. """ return response + def post_list_changelogs_with_metadata( + self, + response: changelog.ListChangelogsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + changelog.ListChangelogsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_changelogs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Changelogs server but before it is returned to user code. + + We recommend only using this `post_list_changelogs_with_metadata` + interceptor in new development instead of the `post_list_changelogs` interceptor. + When both interceptors are used, this `post_list_changelogs_with_metadata` interceptor runs after the + `post_list_changelogs` interceptor. The (possibly modified) response returned by + `post_list_changelogs` will be passed to + `post_list_changelogs_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -473,6 +521,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_changelog(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_changelog_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -618,6 +670,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_changelogs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_changelogs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/deployments/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/deployments/client.py index 888c2e6120d4..5877d775ee7b 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/deployments/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/deployments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -570,6 +572,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1056,16 +1085,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1111,16 +1144,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1221,16 +1258,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1276,16 +1317,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/deployments/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/deployments/transports/rest.py index 90837cfd8808..7022b53361ce 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/deployments/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/deployments/transports/rest.py @@ -111,12 +111,35 @@ def post_get_deployment( ) -> deployment.Deployment: """Post-rpc interceptor for get_deployment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_deployment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Deployments server but before - it is returned to user code. + it is returned to user code. This `post_get_deployment` interceptor runs + before the `post_get_deployment_with_metadata` interceptor. """ return response + def post_get_deployment_with_metadata( + self, + response: deployment.Deployment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[deployment.Deployment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_deployment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Deployments server but before it is returned to user code. + + We recommend only using this `post_get_deployment_with_metadata` + interceptor in new development instead of the `post_get_deployment` interceptor. + When both interceptors are used, this `post_get_deployment_with_metadata` interceptor runs after the + `post_get_deployment` interceptor. The (possibly modified) response returned by + `post_get_deployment` will be passed to + `post_get_deployment_with_metadata`. + """ + return response, metadata + def pre_list_deployments( self, request: deployment.ListDeploymentsRequest, @@ -136,12 +159,37 @@ def post_list_deployments( ) -> deployment.ListDeploymentsResponse: """Post-rpc interceptor for list_deployments - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_deployments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Deployments server but before - it is returned to user code. + it is returned to user code. This `post_list_deployments` interceptor runs + before the `post_list_deployments_with_metadata` interceptor. """ return response + def post_list_deployments_with_metadata( + self, + response: deployment.ListDeploymentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + deployment.ListDeploymentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_deployments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Deployments server but before it is returned to user code. + + We recommend only using this `post_list_deployments_with_metadata` + interceptor in new development instead of the `post_list_deployments` interceptor. + When both interceptors are used, this `post_list_deployments_with_metadata` interceptor runs after the + `post_list_deployments` interceptor. The (possibly modified) response returned by + `post_list_deployments` will be passed to + `post_list_deployments_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -480,6 +528,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_deployment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_deployment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -625,6 +677,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_deployments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_deployments_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/entity_types/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/entity_types/client.py index af63050de740..f542750f0765 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/entity_types/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/entity_types/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -493,6 +495,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1608,16 +1637,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1663,16 +1696,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1773,16 +1810,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1828,16 +1869,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/entity_types/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/entity_types/transports/rest.py index a9cad480071f..b413843889ec 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/entity_types/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/entity_types/transports/rest.py @@ -150,12 +150,35 @@ def post_create_entity_type( ) -> gcdc_entity_type.EntityType: """Post-rpc interceptor for create_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_create_entity_type` interceptor runs + before the `post_create_entity_type_with_metadata` interceptor. """ return response + def post_create_entity_type_with_metadata( + self, + response: gcdc_entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_create_entity_type_with_metadata` + interceptor in new development instead of the `post_create_entity_type` interceptor. + When both interceptors are used, this `post_create_entity_type_with_metadata` interceptor runs after the + `post_create_entity_type` interceptor. The (possibly modified) response returned by + `post_create_entity_type` will be passed to + `post_create_entity_type_with_metadata`. + """ + return response, metadata + def pre_delete_entity_type( self, request: entity_type.DeleteEntityTypeRequest, @@ -189,12 +212,35 @@ def post_export_entity_types( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_export_entity_types` interceptor runs + before the `post_export_entity_types_with_metadata` interceptor. """ return response + def post_export_entity_types_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_export_entity_types_with_metadata` + interceptor in new development instead of the `post_export_entity_types` interceptor. + When both interceptors are used, this `post_export_entity_types_with_metadata` interceptor runs after the + `post_export_entity_types` interceptor. The (possibly modified) response returned by + `post_export_entity_types` will be passed to + `post_export_entity_types_with_metadata`. + """ + return response, metadata + def pre_get_entity_type( self, request: entity_type.GetEntityTypeRequest, @@ -214,12 +260,35 @@ def post_get_entity_type( ) -> entity_type.EntityType: """Post-rpc interceptor for get_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_get_entity_type` interceptor runs + before the `post_get_entity_type_with_metadata` interceptor. """ return response + def post_get_entity_type_with_metadata( + self, + response: entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_get_entity_type_with_metadata` + interceptor in new development instead of the `post_get_entity_type` interceptor. + When both interceptors are used, this `post_get_entity_type_with_metadata` interceptor runs after the + `post_get_entity_type` interceptor. The (possibly modified) response returned by + `post_get_entity_type` will be passed to + `post_get_entity_type_with_metadata`. + """ + return response, metadata + def pre_import_entity_types( self, request: entity_type.ImportEntityTypesRequest, @@ -239,12 +308,35 @@ def post_import_entity_types( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_import_entity_types` interceptor runs + before the `post_import_entity_types_with_metadata` interceptor. """ return response + def post_import_entity_types_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_import_entity_types_with_metadata` + interceptor in new development instead of the `post_import_entity_types` interceptor. + When both interceptors are used, this `post_import_entity_types_with_metadata` interceptor runs after the + `post_import_entity_types` interceptor. The (possibly modified) response returned by + `post_import_entity_types` will be passed to + `post_import_entity_types_with_metadata`. + """ + return response, metadata + def pre_list_entity_types( self, request: entity_type.ListEntityTypesRequest, @@ -264,12 +356,37 @@ def post_list_entity_types( ) -> entity_type.ListEntityTypesResponse: """Post-rpc interceptor for list_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_list_entity_types` interceptor runs + before the `post_list_entity_types_with_metadata` interceptor. """ return response + def post_list_entity_types_with_metadata( + self, + response: entity_type.ListEntityTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + entity_type.ListEntityTypesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_list_entity_types_with_metadata` + interceptor in new development instead of the `post_list_entity_types` interceptor. + When both interceptors are used, this `post_list_entity_types_with_metadata` interceptor runs after the + `post_list_entity_types` interceptor. The (possibly modified) response returned by + `post_list_entity_types` will be passed to + `post_list_entity_types_with_metadata`. + """ + return response, metadata + def pre_update_entity_type( self, request: gcdc_entity_type.UpdateEntityTypeRequest, @@ -290,12 +407,35 @@ def post_update_entity_type( ) -> gcdc_entity_type.EntityType: """Post-rpc interceptor for update_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_update_entity_type` interceptor runs + before the `post_update_entity_type_with_metadata` interceptor. """ return response + def post_update_entity_type_with_metadata( + self, + response: gcdc_entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_update_entity_type_with_metadata` + interceptor in new development instead of the `post_update_entity_type` interceptor. + When both interceptors are used, this `post_update_entity_type_with_metadata` interceptor runs after the + `post_update_entity_type` interceptor. The (possibly modified) response returned by + `post_update_entity_type` will be passed to + `post_update_entity_type_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -727,6 +867,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -986,6 +1130,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1164,6 +1312,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1314,6 +1466,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1459,6 +1615,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1645,6 +1805,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/environments/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/environments/client.py index a27ed7a1ea35..b2848dc6fd65 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/environments/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/environments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -645,6 +647,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2021,16 +2050,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2076,16 +2109,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2186,16 +2223,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2241,16 +2282,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/environments/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/environments/transports/rest.py index aefee52aadb4..a2ac92f7ca29 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/environments/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/environments/transports/rest.py @@ -166,12 +166,35 @@ def post_create_environment( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_create_environment` interceptor runs + before the `post_create_environment_with_metadata` interceptor. """ return response + def post_create_environment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_create_environment_with_metadata` + interceptor in new development instead of the `post_create_environment` interceptor. + When both interceptors are used, this `post_create_environment_with_metadata` interceptor runs after the + `post_create_environment` interceptor. The (possibly modified) response returned by + `post_create_environment` will be passed to + `post_create_environment_with_metadata`. + """ + return response, metadata + def pre_delete_environment( self, request: environment.DeleteEnvironmentRequest, @@ -203,12 +226,35 @@ def post_deploy_flow( ) -> operations_pb2.Operation: """Post-rpc interceptor for deploy_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_deploy_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_deploy_flow` interceptor runs + before the `post_deploy_flow_with_metadata` interceptor. """ return response + def post_deploy_flow_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for deploy_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_deploy_flow_with_metadata` + interceptor in new development instead of the `post_deploy_flow` interceptor. + When both interceptors are used, this `post_deploy_flow_with_metadata` interceptor runs after the + `post_deploy_flow` interceptor. The (possibly modified) response returned by + `post_deploy_flow` will be passed to + `post_deploy_flow_with_metadata`. + """ + return response, metadata + def pre_get_environment( self, request: environment.GetEnvironmentRequest, @@ -228,12 +274,35 @@ def post_get_environment( ) -> environment.Environment: """Post-rpc interceptor for get_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_get_environment` interceptor runs + before the `post_get_environment_with_metadata` interceptor. """ return response + def post_get_environment_with_metadata( + self, + response: environment.Environment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.Environment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_get_environment_with_metadata` + interceptor in new development instead of the `post_get_environment` interceptor. + When both interceptors are used, this `post_get_environment_with_metadata` interceptor runs after the + `post_get_environment` interceptor. The (possibly modified) response returned by + `post_get_environment` will be passed to + `post_get_environment_with_metadata`. + """ + return response, metadata + def pre_list_continuous_test_results( self, request: environment.ListContinuousTestResultsRequest, @@ -254,12 +323,38 @@ def post_list_continuous_test_results( ) -> environment.ListContinuousTestResultsResponse: """Post-rpc interceptor for list_continuous_test_results - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_continuous_test_results_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_list_continuous_test_results` interceptor runs + before the `post_list_continuous_test_results_with_metadata` interceptor. """ return response + def post_list_continuous_test_results_with_metadata( + self, + response: environment.ListContinuousTestResultsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + environment.ListContinuousTestResultsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_continuous_test_results + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_list_continuous_test_results_with_metadata` + interceptor in new development instead of the `post_list_continuous_test_results` interceptor. + When both interceptors are used, this `post_list_continuous_test_results_with_metadata` interceptor runs after the + `post_list_continuous_test_results` interceptor. The (possibly modified) response returned by + `post_list_continuous_test_results` will be passed to + `post_list_continuous_test_results_with_metadata`. + """ + return response, metadata + def pre_list_environments( self, request: environment.ListEnvironmentsRequest, @@ -279,12 +374,37 @@ def post_list_environments( ) -> environment.ListEnvironmentsResponse: """Post-rpc interceptor for list_environments - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_environments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_list_environments` interceptor runs + before the `post_list_environments_with_metadata` interceptor. """ return response + def post_list_environments_with_metadata( + self, + response: environment.ListEnvironmentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + environment.ListEnvironmentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_environments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_list_environments_with_metadata` + interceptor in new development instead of the `post_list_environments` interceptor. + When both interceptors are used, this `post_list_environments_with_metadata` interceptor runs after the + `post_list_environments` interceptor. The (possibly modified) response returned by + `post_list_environments` will be passed to + `post_list_environments_with_metadata`. + """ + return response, metadata + def pre_lookup_environment_history( self, request: environment.LookupEnvironmentHistoryRequest, @@ -305,12 +425,38 @@ def post_lookup_environment_history( ) -> environment.LookupEnvironmentHistoryResponse: """Post-rpc interceptor for lookup_environment_history - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_lookup_environment_history_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_lookup_environment_history` interceptor runs + before the `post_lookup_environment_history_with_metadata` interceptor. """ return response + def post_lookup_environment_history_with_metadata( + self, + response: environment.LookupEnvironmentHistoryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + environment.LookupEnvironmentHistoryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for lookup_environment_history + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_lookup_environment_history_with_metadata` + interceptor in new development instead of the `post_lookup_environment_history` interceptor. + When both interceptors are used, this `post_lookup_environment_history_with_metadata` interceptor runs after the + `post_lookup_environment_history` interceptor. The (possibly modified) response returned by + `post_lookup_environment_history` will be passed to + `post_lookup_environment_history_with_metadata`. + """ + return response, metadata + def pre_run_continuous_test( self, request: environment.RunContinuousTestRequest, @@ -330,12 +476,35 @@ def post_run_continuous_test( ) -> operations_pb2.Operation: """Post-rpc interceptor for run_continuous_test - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_run_continuous_test_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_run_continuous_test` interceptor runs + before the `post_run_continuous_test_with_metadata` interceptor. """ return response + def post_run_continuous_test_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for run_continuous_test + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_run_continuous_test_with_metadata` + interceptor in new development instead of the `post_run_continuous_test` interceptor. + When both interceptors are used, this `post_run_continuous_test_with_metadata` interceptor runs after the + `post_run_continuous_test` interceptor. The (possibly modified) response returned by + `post_run_continuous_test` will be passed to + `post_run_continuous_test_with_metadata`. + """ + return response, metadata + def pre_update_environment( self, request: gcdc_environment.UpdateEnvironmentRequest, @@ -356,12 +525,35 @@ def post_update_environment( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_update_environment` interceptor runs + before the `post_update_environment_with_metadata` interceptor. """ return response + def post_update_environment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_update_environment_with_metadata` + interceptor in new development instead of the `post_update_environment` interceptor. + When both interceptors are used, this `post_update_environment_with_metadata` interceptor runs after the + `post_update_environment` interceptor. The (possibly modified) response returned by + `post_update_environment` will be passed to + `post_update_environment_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -759,6 +951,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1022,6 +1218,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_deploy_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_deploy_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1178,6 +1378,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1327,6 +1531,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_continuous_test_results(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_continuous_test_results_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1474,6 +1682,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_environments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_environments_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1625,6 +1837,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_lookup_environment_history(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_lookup_environment_history_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1777,6 +1993,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_run_continuous_test(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_run_continuous_test_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1927,6 +2147,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/experiments/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/experiments/client.py index bc0d79bc99a1..a760ef6f2dc5 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/experiments/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/experiments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -521,6 +523,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1557,16 +1586,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1612,16 +1645,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1722,16 +1759,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1777,16 +1818,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/experiments/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/experiments/transports/rest.py index 4cce41928a24..be29f4a6110c 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/experiments/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/experiments/transports/rest.py @@ -149,12 +149,35 @@ def post_create_experiment( ) -> gcdc_experiment.Experiment: """Post-rpc interceptor for create_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_create_experiment` interceptor runs + before the `post_create_experiment_with_metadata` interceptor. """ return response + def post_create_experiment_with_metadata( + self, + response: gcdc_experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_create_experiment_with_metadata` + interceptor in new development instead of the `post_create_experiment` interceptor. + When both interceptors are used, this `post_create_experiment_with_metadata` interceptor runs after the + `post_create_experiment` interceptor. The (possibly modified) response returned by + `post_create_experiment` will be passed to + `post_create_experiment_with_metadata`. + """ + return response, metadata + def pre_delete_experiment( self, request: experiment.DeleteExperimentRequest, @@ -188,12 +211,35 @@ def post_get_experiment( ) -> experiment.Experiment: """Post-rpc interceptor for get_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_get_experiment` interceptor runs + before the `post_get_experiment_with_metadata` interceptor. """ return response + def post_get_experiment_with_metadata( + self, + response: experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_get_experiment_with_metadata` + interceptor in new development instead of the `post_get_experiment` interceptor. + When both interceptors are used, this `post_get_experiment_with_metadata` interceptor runs after the + `post_get_experiment` interceptor. The (possibly modified) response returned by + `post_get_experiment` will be passed to + `post_get_experiment_with_metadata`. + """ + return response, metadata + def pre_list_experiments( self, request: experiment.ListExperimentsRequest, @@ -213,12 +259,37 @@ def post_list_experiments( ) -> experiment.ListExperimentsResponse: """Post-rpc interceptor for list_experiments - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_experiments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_list_experiments` interceptor runs + before the `post_list_experiments_with_metadata` interceptor. """ return response + def post_list_experiments_with_metadata( + self, + response: experiment.ListExperimentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + experiment.ListExperimentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_experiments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_list_experiments_with_metadata` + interceptor in new development instead of the `post_list_experiments` interceptor. + When both interceptors are used, this `post_list_experiments_with_metadata` interceptor runs after the + `post_list_experiments` interceptor. The (possibly modified) response returned by + `post_list_experiments` will be passed to + `post_list_experiments_with_metadata`. + """ + return response, metadata + def pre_start_experiment( self, request: experiment.StartExperimentRequest, @@ -238,12 +309,35 @@ def post_start_experiment( ) -> experiment.Experiment: """Post-rpc interceptor for start_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_start_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_start_experiment` interceptor runs + before the `post_start_experiment_with_metadata` interceptor. """ return response + def post_start_experiment_with_metadata( + self, + response: experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for start_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_start_experiment_with_metadata` + interceptor in new development instead of the `post_start_experiment` interceptor. + When both interceptors are used, this `post_start_experiment_with_metadata` interceptor runs after the + `post_start_experiment` interceptor. The (possibly modified) response returned by + `post_start_experiment` will be passed to + `post_start_experiment_with_metadata`. + """ + return response, metadata + def pre_stop_experiment( self, request: experiment.StopExperimentRequest, @@ -263,12 +357,35 @@ def post_stop_experiment( ) -> experiment.Experiment: """Post-rpc interceptor for stop_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_stop_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_stop_experiment` interceptor runs + before the `post_stop_experiment_with_metadata` interceptor. """ return response + def post_stop_experiment_with_metadata( + self, + response: experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for stop_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_stop_experiment_with_metadata` + interceptor in new development instead of the `post_stop_experiment` interceptor. + When both interceptors are used, this `post_stop_experiment_with_metadata` interceptor runs after the + `post_stop_experiment` interceptor. The (possibly modified) response returned by + `post_stop_experiment` will be passed to + `post_stop_experiment_with_metadata`. + """ + return response, metadata + def pre_update_experiment( self, request: gcdc_experiment.UpdateExperimentRequest, @@ -288,12 +405,35 @@ def post_update_experiment( ) -> gcdc_experiment.Experiment: """Post-rpc interceptor for update_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_update_experiment` interceptor runs + before the `post_update_experiment_with_metadata` interceptor. """ return response + def post_update_experiment_with_metadata( + self, + response: gcdc_experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_update_experiment_with_metadata` + interceptor in new development instead of the `post_update_experiment` interceptor. + When both interceptors are used, this `post_update_experiment_with_metadata` interceptor runs after the + `post_update_experiment` interceptor. The (possibly modified) response returned by + `post_update_experiment` will be passed to + `post_update_experiment_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -633,6 +773,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -887,6 +1031,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1032,6 +1180,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_experiments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_experiments_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1185,6 +1337,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_start_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_start_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1334,6 +1490,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_stop_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_stop_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1485,6 +1645,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER 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 aa923f273602..1c5806e144b2 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 @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -620,6 +622,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2057,16 +2086,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2112,16 +2145,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2222,16 +2259,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2277,16 +2318,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/transports/rest.py index 9dbe5e5eb8b6..1e9b07eb2d86 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/flows/transports/rest.py @@ -169,12 +169,35 @@ def pre_create_flow( def post_create_flow(self, response: gcdc_flow.Flow) -> gcdc_flow.Flow: """Post-rpc interceptor for create_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_create_flow` interceptor runs + before the `post_create_flow_with_metadata` interceptor. """ return response + def post_create_flow_with_metadata( + self, + response: gcdc_flow.Flow, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_flow.Flow, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_create_flow_with_metadata` + interceptor in new development instead of the `post_create_flow` interceptor. + When both interceptors are used, this `post_create_flow_with_metadata` interceptor runs after the + `post_create_flow` interceptor. The (possibly modified) response returned by + `post_create_flow` will be passed to + `post_create_flow_with_metadata`. + """ + return response, metadata + def pre_delete_flow( self, request: flow.DeleteFlowRequest, @@ -204,12 +227,35 @@ def post_export_flow( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_export_flow` interceptor runs + before the `post_export_flow_with_metadata` interceptor. """ return response + def post_export_flow_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_export_flow_with_metadata` + interceptor in new development instead of the `post_export_flow` interceptor. + When both interceptors are used, this `post_export_flow_with_metadata` interceptor runs after the + `post_export_flow` interceptor. The (possibly modified) response returned by + `post_export_flow` will be passed to + `post_export_flow_with_metadata`. + """ + return response, metadata + def pre_get_flow( self, request: flow.GetFlowRequest, @@ -225,12 +271,33 @@ def pre_get_flow( def post_get_flow(self, response: flow.Flow) -> flow.Flow: """Post-rpc interceptor for get_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_get_flow` interceptor runs + before the `post_get_flow_with_metadata` interceptor. """ return response + def post_get_flow_with_metadata( + self, response: flow.Flow, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[flow.Flow, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_get_flow_with_metadata` + interceptor in new development instead of the `post_get_flow` interceptor. + When both interceptors are used, this `post_get_flow_with_metadata` interceptor runs after the + `post_get_flow` interceptor. The (possibly modified) response returned by + `post_get_flow` will be passed to + `post_get_flow_with_metadata`. + """ + return response, metadata + def pre_get_flow_validation_result( self, request: flow.GetFlowValidationResultRequest, @@ -250,12 +317,35 @@ def post_get_flow_validation_result( ) -> flow.FlowValidationResult: """Post-rpc interceptor for get_flow_validation_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_flow_validation_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_get_flow_validation_result` interceptor runs + before the `post_get_flow_validation_result_with_metadata` interceptor. """ return response + def post_get_flow_validation_result_with_metadata( + self, + response: flow.FlowValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[flow.FlowValidationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_flow_validation_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_get_flow_validation_result_with_metadata` + interceptor in new development instead of the `post_get_flow_validation_result` interceptor. + When both interceptors are used, this `post_get_flow_validation_result_with_metadata` interceptor runs after the + `post_get_flow_validation_result` interceptor. The (possibly modified) response returned by + `post_get_flow_validation_result` will be passed to + `post_get_flow_validation_result_with_metadata`. + """ + return response, metadata + def pre_import_flow( self, request: flow.ImportFlowRequest, @@ -273,12 +363,35 @@ def post_import_flow( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_import_flow` interceptor runs + before the `post_import_flow_with_metadata` interceptor. """ return response + def post_import_flow_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_import_flow_with_metadata` + interceptor in new development instead of the `post_import_flow` interceptor. + When both interceptors are used, this `post_import_flow_with_metadata` interceptor runs after the + `post_import_flow` interceptor. The (possibly modified) response returned by + `post_import_flow` will be passed to + `post_import_flow_with_metadata`. + """ + return response, metadata + def pre_list_flows( self, request: flow.ListFlowsRequest, @@ -296,12 +409,35 @@ def post_list_flows( ) -> flow.ListFlowsResponse: """Post-rpc interceptor for list_flows - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_flows_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_list_flows` interceptor runs + before the `post_list_flows_with_metadata` interceptor. """ return response + def post_list_flows_with_metadata( + self, + response: flow.ListFlowsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[flow.ListFlowsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_flows + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_list_flows_with_metadata` + interceptor in new development instead of the `post_list_flows` interceptor. + When both interceptors are used, this `post_list_flows_with_metadata` interceptor runs after the + `post_list_flows` interceptor. The (possibly modified) response returned by + `post_list_flows` will be passed to + `post_list_flows_with_metadata`. + """ + return response, metadata + def pre_train_flow( self, request: flow.TrainFlowRequest, @@ -319,12 +455,35 @@ def post_train_flow( ) -> operations_pb2.Operation: """Post-rpc interceptor for train_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_train_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_train_flow` interceptor runs + before the `post_train_flow_with_metadata` interceptor. """ return response + def post_train_flow_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for train_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_train_flow_with_metadata` + interceptor in new development instead of the `post_train_flow` interceptor. + When both interceptors are used, this `post_train_flow_with_metadata` interceptor runs after the + `post_train_flow` interceptor. The (possibly modified) response returned by + `post_train_flow` will be passed to + `post_train_flow_with_metadata`. + """ + return response, metadata + def pre_update_flow( self, request: gcdc_flow.UpdateFlowRequest, @@ -340,12 +499,35 @@ def pre_update_flow( def post_update_flow(self, response: gcdc_flow.Flow) -> gcdc_flow.Flow: """Post-rpc interceptor for update_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_update_flow` interceptor runs + before the `post_update_flow_with_metadata` interceptor. """ return response + def post_update_flow_with_metadata( + self, + response: gcdc_flow.Flow, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_flow.Flow, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_update_flow_with_metadata` + interceptor in new development instead of the `post_update_flow` interceptor. + When both interceptors are used, this `post_update_flow_with_metadata` interceptor runs after the + `post_update_flow` interceptor. The (possibly modified) response returned by + `post_update_flow` will be passed to + `post_update_flow_with_metadata`. + """ + return response, metadata + def pre_validate_flow( self, request: flow.ValidateFlowRequest, @@ -363,12 +545,35 @@ def post_validate_flow( ) -> flow.FlowValidationResult: """Post-rpc interceptor for validate_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_validate_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_validate_flow` interceptor runs + before the `post_validate_flow_with_metadata` interceptor. """ return response + def post_validate_flow_with_metadata( + self, + response: flow.FlowValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[flow.FlowValidationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for validate_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_validate_flow_with_metadata` + interceptor in new development instead of the `post_validate_flow` interceptor. + When both interceptors are used, this `post_validate_flow_with_metadata` interceptor runs after the + `post_validate_flow` interceptor. The (possibly modified) response returned by + `post_validate_flow` will be passed to + `post_validate_flow_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -785,6 +990,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1040,6 +1249,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1202,6 +1415,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1348,6 +1565,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_flow_validation_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_flow_validation_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1496,6 +1717,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1639,6 +1864,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_flows(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_flows_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1787,6 +2016,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_train_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_train_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1957,6 +2190,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2106,6 +2343,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_validate_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_validate_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/generators/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/generators/client.py index 7d76ad326392..e3ad4ada49d8 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/generators/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/generators/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -491,6 +493,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1310,16 +1339,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1365,16 +1398,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1475,16 +1512,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1530,16 +1571,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/generators/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/generators/transports/rest.py index 5d67a080b7d0..5cfebc030b04 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/generators/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/generators/transports/rest.py @@ -133,12 +133,35 @@ def post_create_generator( ) -> gcdc_generator.Generator: """Post-rpc interceptor for create_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_create_generator` interceptor runs + before the `post_create_generator_with_metadata` interceptor. """ return response + def post_create_generator_with_metadata( + self, + response: gcdc_generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_create_generator_with_metadata` + interceptor in new development instead of the `post_create_generator` interceptor. + When both interceptors are used, this `post_create_generator_with_metadata` interceptor runs after the + `post_create_generator` interceptor. The (possibly modified) response returned by + `post_create_generator` will be passed to + `post_create_generator_with_metadata`. + """ + return response, metadata + def pre_delete_generator( self, request: generator.DeleteGeneratorRequest, @@ -168,12 +191,35 @@ def pre_get_generator( def post_get_generator(self, response: generator.Generator) -> generator.Generator: """Post-rpc interceptor for get_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_get_generator` interceptor runs + before the `post_get_generator_with_metadata` interceptor. """ return response + def post_get_generator_with_metadata( + self, + response: generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_get_generator_with_metadata` + interceptor in new development instead of the `post_get_generator` interceptor. + When both interceptors are used, this `post_get_generator_with_metadata` interceptor runs after the + `post_get_generator` interceptor. The (possibly modified) response returned by + `post_get_generator` will be passed to + `post_get_generator_with_metadata`. + """ + return response, metadata + def pre_list_generators( self, request: generator.ListGeneratorsRequest, @@ -193,12 +239,37 @@ def post_list_generators( ) -> generator.ListGeneratorsResponse: """Post-rpc interceptor for list_generators - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_generators_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_list_generators` interceptor runs + before the `post_list_generators_with_metadata` interceptor. """ return response + def post_list_generators_with_metadata( + self, + response: generator.ListGeneratorsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generator.ListGeneratorsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_generators + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_list_generators_with_metadata` + interceptor in new development instead of the `post_list_generators` interceptor. + When both interceptors are used, this `post_list_generators_with_metadata` interceptor runs after the + `post_list_generators` interceptor. The (possibly modified) response returned by + `post_list_generators` will be passed to + `post_list_generators_with_metadata`. + """ + return response, metadata + def pre_update_generator( self, request: gcdc_generator.UpdateGeneratorRequest, @@ -218,12 +289,35 @@ def post_update_generator( ) -> gcdc_generator.Generator: """Post-rpc interceptor for update_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_update_generator` interceptor runs + before the `post_update_generator_with_metadata` interceptor. """ return response + def post_update_generator_with_metadata( + self, + response: gcdc_generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_update_generator_with_metadata` + interceptor in new development instead of the `post_update_generator` interceptor. + When both interceptors are used, this `post_update_generator_with_metadata` interceptor runs after the + `post_update_generator` interceptor. The (possibly modified) response returned by + `post_update_generator` will be passed to + `post_update_generator_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -567,6 +661,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -827,6 +925,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -972,6 +1074,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_generators(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_generators_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1129,6 +1235,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER 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 374426f40b2e..6449301f12d8 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 @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -517,6 +519,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1568,16 +1597,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1623,16 +1656,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1733,16 +1770,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1788,16 +1829,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 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 affb4adc9583..3cfe2ed08a50 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 @@ -147,12 +147,35 @@ def pre_create_intent( def post_create_intent(self, response: gcdc_intent.Intent) -> gcdc_intent.Intent: """Post-rpc interceptor for create_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_create_intent` interceptor runs + before the `post_create_intent_with_metadata` interceptor. """ return response + def post_create_intent_with_metadata( + self, + response: gcdc_intent.Intent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_create_intent_with_metadata` + interceptor in new development instead of the `post_create_intent` interceptor. + When both interceptors are used, this `post_create_intent_with_metadata` interceptor runs after the + `post_create_intent` interceptor. The (possibly modified) response returned by + `post_create_intent` will be passed to + `post_create_intent_with_metadata`. + """ + return response, metadata + def pre_delete_intent( self, request: intent.DeleteIntentRequest, @@ -182,12 +205,35 @@ def post_export_intents( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_export_intents` interceptor runs + before the `post_export_intents_with_metadata` interceptor. """ return response + def post_export_intents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_export_intents_with_metadata` + interceptor in new development instead of the `post_export_intents` interceptor. + When both interceptors are used, this `post_export_intents_with_metadata` interceptor runs after the + `post_export_intents` interceptor. The (possibly modified) response returned by + `post_export_intents` will be passed to + `post_export_intents_with_metadata`. + """ + return response, metadata + def pre_get_intent( self, request: intent.GetIntentRequest, @@ -203,12 +249,33 @@ def pre_get_intent( def post_get_intent(self, response: intent.Intent) -> intent.Intent: """Post-rpc interceptor for get_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_get_intent` interceptor runs + before the `post_get_intent_with_metadata` interceptor. """ return response + def post_get_intent_with_metadata( + self, response: intent.Intent, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_get_intent_with_metadata` + interceptor in new development instead of the `post_get_intent` interceptor. + When both interceptors are used, this `post_get_intent_with_metadata` interceptor runs after the + `post_get_intent` interceptor. The (possibly modified) response returned by + `post_get_intent` will be passed to + `post_get_intent_with_metadata`. + """ + return response, metadata + def pre_import_intents( self, request: intent.ImportIntentsRequest, @@ -226,12 +293,35 @@ def post_import_intents( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_import_intents` interceptor runs + before the `post_import_intents_with_metadata` interceptor. """ return response + def post_import_intents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_import_intents_with_metadata` + interceptor in new development instead of the `post_import_intents` interceptor. + When both interceptors are used, this `post_import_intents_with_metadata` interceptor runs after the + `post_import_intents` interceptor. The (possibly modified) response returned by + `post_import_intents` will be passed to + `post_import_intents_with_metadata`. + """ + return response, metadata + def pre_list_intents( self, request: intent.ListIntentsRequest, @@ -249,12 +339,35 @@ def post_list_intents( ) -> intent.ListIntentsResponse: """Post-rpc interceptor for list_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_list_intents` interceptor runs + before the `post_list_intents_with_metadata` interceptor. """ return response + def post_list_intents_with_metadata( + self, + response: intent.ListIntentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[intent.ListIntentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_list_intents_with_metadata` + interceptor in new development instead of the `post_list_intents` interceptor. + When both interceptors are used, this `post_list_intents_with_metadata` interceptor runs after the + `post_list_intents` interceptor. The (possibly modified) response returned by + `post_list_intents` will be passed to + `post_list_intents_with_metadata`. + """ + return response, metadata + def pre_update_intent( self, request: gcdc_intent.UpdateIntentRequest, @@ -272,12 +385,35 @@ def pre_update_intent( def post_update_intent(self, response: gcdc_intent.Intent) -> gcdc_intent.Intent: """Post-rpc interceptor for update_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_update_intent` interceptor runs + before the `post_update_intent_with_metadata` interceptor. """ return response + def post_update_intent_with_metadata( + self, + response: gcdc_intent.Intent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_update_intent_with_metadata` + interceptor in new development instead of the `post_update_intent` interceptor. + When both interceptors are used, this `post_update_intent_with_metadata` interceptor runs after the + `post_update_intent` interceptor. The (possibly modified) response returned by + `post_update_intent` will be passed to + `post_update_intent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -681,6 +817,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -940,6 +1080,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1088,6 +1232,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1238,6 +1386,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1383,6 +1535,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1539,6 +1695,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER 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 b9e474afe879..2ea524f287ce 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 @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -614,6 +616,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1490,16 +1519,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1545,16 +1578,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1655,16 +1692,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1710,16 +1751,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/transports/rest.py index 9c21494d9e33..43965978d4b0 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/pages/transports/rest.py @@ -129,12 +129,35 @@ def pre_create_page( def post_create_page(self, response: gcdc_page.Page) -> gcdc_page.Page: """Post-rpc interceptor for create_page - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_page_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Pages server but before - it is returned to user code. + it is returned to user code. This `post_create_page` interceptor runs + before the `post_create_page_with_metadata` interceptor. """ return response + def post_create_page_with_metadata( + self, + response: gcdc_page.Page, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_page.Page, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_page + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Pages server but before it is returned to user code. + + We recommend only using this `post_create_page_with_metadata` + interceptor in new development instead of the `post_create_page` interceptor. + When both interceptors are used, this `post_create_page_with_metadata` interceptor runs after the + `post_create_page` interceptor. The (possibly modified) response returned by + `post_create_page` will be passed to + `post_create_page_with_metadata`. + """ + return response, metadata + def pre_delete_page( self, request: page.DeletePageRequest, @@ -162,12 +185,33 @@ def pre_get_page( def post_get_page(self, response: page.Page) -> page.Page: """Post-rpc interceptor for get_page - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_page_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Pages server but before - it is returned to user code. + it is returned to user code. This `post_get_page` interceptor runs + before the `post_get_page_with_metadata` interceptor. """ return response + def post_get_page_with_metadata( + self, response: page.Page, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[page.Page, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_page + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Pages server but before it is returned to user code. + + We recommend only using this `post_get_page_with_metadata` + interceptor in new development instead of the `post_get_page` interceptor. + When both interceptors are used, this `post_get_page_with_metadata` interceptor runs after the + `post_get_page` interceptor. The (possibly modified) response returned by + `post_get_page` will be passed to + `post_get_page_with_metadata`. + """ + return response, metadata + def pre_list_pages( self, request: page.ListPagesRequest, @@ -185,12 +229,35 @@ def post_list_pages( ) -> page.ListPagesResponse: """Post-rpc interceptor for list_pages - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_pages_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Pages server but before - it is returned to user code. + it is returned to user code. This `post_list_pages` interceptor runs + before the `post_list_pages_with_metadata` interceptor. """ return response + def post_list_pages_with_metadata( + self, + response: page.ListPagesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[page.ListPagesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_pages + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Pages server but before it is returned to user code. + + We recommend only using this `post_list_pages_with_metadata` + interceptor in new development instead of the `post_list_pages` interceptor. + When both interceptors are used, this `post_list_pages_with_metadata` interceptor runs after the + `post_list_pages` interceptor. The (possibly modified) response returned by + `post_list_pages` will be passed to + `post_list_pages_with_metadata`. + """ + return response, metadata + def pre_update_page( self, request: gcdc_page.UpdatePageRequest, @@ -206,12 +273,35 @@ def pre_update_page( def post_update_page(self, response: gcdc_page.Page) -> gcdc_page.Page: """Post-rpc interceptor for update_page - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_page_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Pages server but before - it is returned to user code. + it is returned to user code. This `post_update_page` interceptor runs + before the `post_update_page_with_metadata` interceptor. """ return response + def post_update_page_with_metadata( + self, + response: gcdc_page.Page, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_page.Page, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_page + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Pages server but before it is returned to user code. + + We recommend only using this `post_update_page_with_metadata` + interceptor in new development instead of the `post_update_page` interceptor. + When both interceptors are used, this `post_update_page_with_metadata` interceptor runs after the + `post_update_page` interceptor. The (possibly modified) response returned by + `post_update_page` will be passed to + `post_update_page_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -567,6 +657,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_page(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_page_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -834,6 +928,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_page(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_page_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -977,6 +1075,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_pages(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_pages_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1145,6 +1247,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_page(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_page_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/security_settings_service/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/security_settings_service/client.py index 858e1e052fcf..07e7350094ba 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/security_settings_service/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/security_settings_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -537,6 +539,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1393,16 +1422,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1448,16 +1481,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1558,16 +1595,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1613,16 +1654,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/security_settings_service/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/security_settings_service/transports/rest.py index ca33a51acaa4..902fc90d72cc 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/security_settings_service/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/security_settings_service/transports/rest.py @@ -136,12 +136,37 @@ def post_create_security_settings( ) -> gcdc_security_settings.SecuritySettings: """Post-rpc interceptor for create_security_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_security_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SecuritySettingsService server but before - it is returned to user code. + it is returned to user code. This `post_create_security_settings` interceptor runs + before the `post_create_security_settings_with_metadata` interceptor. """ return response + def post_create_security_settings_with_metadata( + self, + response: gcdc_security_settings.SecuritySettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_security_settings.SecuritySettings, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_security_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SecuritySettingsService server but before it is returned to user code. + + We recommend only using this `post_create_security_settings_with_metadata` + interceptor in new development instead of the `post_create_security_settings` interceptor. + When both interceptors are used, this `post_create_security_settings_with_metadata` interceptor runs after the + `post_create_security_settings` interceptor. The (possibly modified) response returned by + `post_create_security_settings` will be passed to + `post_create_security_settings_with_metadata`. + """ + return response, metadata + def pre_delete_security_settings( self, request: security_settings.DeleteSecuritySettingsRequest, @@ -177,12 +202,37 @@ def post_get_security_settings( ) -> security_settings.SecuritySettings: """Post-rpc interceptor for get_security_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_security_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SecuritySettingsService server but before - it is returned to user code. + it is returned to user code. This `post_get_security_settings` interceptor runs + before the `post_get_security_settings_with_metadata` interceptor. """ return response + def post_get_security_settings_with_metadata( + self, + response: security_settings.SecuritySettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + security_settings.SecuritySettings, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_security_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SecuritySettingsService server but before it is returned to user code. + + We recommend only using this `post_get_security_settings_with_metadata` + interceptor in new development instead of the `post_get_security_settings` interceptor. + When both interceptors are used, this `post_get_security_settings_with_metadata` interceptor runs after the + `post_get_security_settings` interceptor. The (possibly modified) response returned by + `post_get_security_settings` will be passed to + `post_get_security_settings_with_metadata`. + """ + return response, metadata + def pre_list_security_settings( self, request: security_settings.ListSecuritySettingsRequest, @@ -203,12 +253,38 @@ def post_list_security_settings( ) -> security_settings.ListSecuritySettingsResponse: """Post-rpc interceptor for list_security_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_security_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SecuritySettingsService server but before - it is returned to user code. + it is returned to user code. This `post_list_security_settings` interceptor runs + before the `post_list_security_settings_with_metadata` interceptor. """ return response + def post_list_security_settings_with_metadata( + self, + response: security_settings.ListSecuritySettingsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + security_settings.ListSecuritySettingsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_security_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SecuritySettingsService server but before it is returned to user code. + + We recommend only using this `post_list_security_settings_with_metadata` + interceptor in new development instead of the `post_list_security_settings` interceptor. + When both interceptors are used, this `post_list_security_settings_with_metadata` interceptor runs after the + `post_list_security_settings` interceptor. The (possibly modified) response returned by + `post_list_security_settings` will be passed to + `post_list_security_settings_with_metadata`. + """ + return response, metadata + def pre_update_security_settings( self, request: gcdc_security_settings.UpdateSecuritySettingsRequest, @@ -229,12 +305,37 @@ def post_update_security_settings( ) -> gcdc_security_settings.SecuritySettings: """Post-rpc interceptor for update_security_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_security_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SecuritySettingsService server but before - it is returned to user code. + it is returned to user code. This `post_update_security_settings` interceptor runs + before the `post_update_security_settings_with_metadata` interceptor. """ return response + def post_update_security_settings_with_metadata( + self, + response: gcdc_security_settings.SecuritySettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_security_settings.SecuritySettings, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_security_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SecuritySettingsService server but before it is returned to user code. + + We recommend only using this `post_update_security_settings_with_metadata` + interceptor in new development instead of the `post_update_security_settings` interceptor. + When both interceptors are used, this `post_update_security_settings_with_metadata` interceptor runs after the + `post_update_security_settings` interceptor. The (possibly modified) response returned by + `post_update_security_settings` will be passed to + `post_update_security_settings_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -578,6 +679,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_security_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_security_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -842,6 +947,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_security_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_security_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -990,6 +1099,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_security_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_security_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1148,6 +1261,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_security_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_security_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/session_entity_types/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/session_entity_types/client.py index 5ccbaa543e80..03b0030ddf15 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/session_entity_types/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/session_entity_types/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -498,6 +500,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1411,16 +1440,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1466,16 +1499,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1576,16 +1613,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1631,16 +1672,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/session_entity_types/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/session_entity_types/transports/rest.py index 997aba73d225..802f744614e1 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/session_entity_types/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/session_entity_types/transports/rest.py @@ -136,12 +136,38 @@ def post_create_session_entity_type( ) -> gcdc_session_entity_type.SessionEntityType: """Post-rpc interceptor for create_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_create_session_entity_type` interceptor runs + before the `post_create_session_entity_type_with_metadata` interceptor. """ return response + def post_create_session_entity_type_with_metadata( + self, + response: gcdc_session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_session_entity_type.SessionEntityType, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for create_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_create_session_entity_type_with_metadata` + interceptor in new development instead of the `post_create_session_entity_type` interceptor. + When both interceptors are used, this `post_create_session_entity_type_with_metadata` interceptor runs after the + `post_create_session_entity_type` interceptor. The (possibly modified) response returned by + `post_create_session_entity_type` will be passed to + `post_create_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_delete_session_entity_type( self, request: session_entity_type.DeleteSessionEntityTypeRequest, @@ -177,12 +203,37 @@ def post_get_session_entity_type( ) -> session_entity_type.SessionEntityType: """Post-rpc interceptor for get_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_get_session_entity_type` interceptor runs + before the `post_get_session_entity_type_with_metadata` interceptor. """ return response + def post_get_session_entity_type_with_metadata( + self, + response: session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_entity_type.SessionEntityType, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_get_session_entity_type_with_metadata` + interceptor in new development instead of the `post_get_session_entity_type` interceptor. + When both interceptors are used, this `post_get_session_entity_type_with_metadata` interceptor runs after the + `post_get_session_entity_type` interceptor. The (possibly modified) response returned by + `post_get_session_entity_type` will be passed to + `post_get_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_list_session_entity_types( self, request: session_entity_type.ListSessionEntityTypesRequest, @@ -203,12 +254,38 @@ def post_list_session_entity_types( ) -> session_entity_type.ListSessionEntityTypesResponse: """Post-rpc interceptor for list_session_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_session_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_list_session_entity_types` interceptor runs + before the `post_list_session_entity_types_with_metadata` interceptor. """ return response + def post_list_session_entity_types_with_metadata( + self, + response: session_entity_type.ListSessionEntityTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_entity_type.ListSessionEntityTypesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_session_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_list_session_entity_types_with_metadata` + interceptor in new development instead of the `post_list_session_entity_types` interceptor. + When both interceptors are used, this `post_list_session_entity_types_with_metadata` interceptor runs after the + `post_list_session_entity_types` interceptor. The (possibly modified) response returned by + `post_list_session_entity_types` will be passed to + `post_list_session_entity_types_with_metadata`. + """ + return response, metadata + def pre_update_session_entity_type( self, request: gcdc_session_entity_type.UpdateSessionEntityTypeRequest, @@ -229,12 +306,38 @@ def post_update_session_entity_type( ) -> gcdc_session_entity_type.SessionEntityType: """Post-rpc interceptor for update_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_update_session_entity_type` interceptor runs + before the `post_update_session_entity_type_with_metadata` interceptor. """ return response + def post_update_session_entity_type_with_metadata( + self, + response: gcdc_session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_session_entity_type.SessionEntityType, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_update_session_entity_type_with_metadata` + interceptor in new development instead of the `post_update_session_entity_type` interceptor. + When both interceptors are used, this `post_update_session_entity_type_with_metadata` interceptor runs after the + `post_update_session_entity_type` interceptor. The (possibly modified) response returned by + `post_update_session_entity_type` will be passed to + `post_update_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -593,6 +696,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -871,6 +978,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1021,6 +1132,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_session_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_session_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1195,6 +1310,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/sessions/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/sessions/client.py index 65e55dd9ddb0..fe8991d9ade5 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/sessions/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/sessions/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -714,6 +716,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1581,16 +1610,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1636,16 +1669,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1746,16 +1783,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1801,16 +1842,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/sessions/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/sessions/transports/rest.py index 55a45d745acd..7dfa722c9abd 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/sessions/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/sessions/transports/rest.py @@ -133,12 +133,35 @@ def post_detect_intent( ) -> session.DetectIntentResponse: """Post-rpc interceptor for detect_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_detect_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_detect_intent` interceptor runs + before the `post_detect_intent_with_metadata` interceptor. """ return response + def post_detect_intent_with_metadata( + self, + response: session.DetectIntentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.DetectIntentResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for detect_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_detect_intent_with_metadata` + interceptor in new development instead of the `post_detect_intent` interceptor. + When both interceptors are used, this `post_detect_intent_with_metadata` interceptor runs after the + `post_detect_intent` interceptor. The (possibly modified) response returned by + `post_detect_intent` will be passed to + `post_detect_intent_with_metadata`. + """ + return response, metadata + def pre_fulfill_intent( self, request: session.FulfillIntentRequest, @@ -156,12 +179,35 @@ def post_fulfill_intent( ) -> session.FulfillIntentResponse: """Post-rpc interceptor for fulfill_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fulfill_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_fulfill_intent` interceptor runs + before the `post_fulfill_intent_with_metadata` interceptor. """ return response + def post_fulfill_intent_with_metadata( + self, + response: session.FulfillIntentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.FulfillIntentResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for fulfill_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_fulfill_intent_with_metadata` + interceptor in new development instead of the `post_fulfill_intent` interceptor. + When both interceptors are used, this `post_fulfill_intent_with_metadata` interceptor runs after the + `post_fulfill_intent` interceptor. The (possibly modified) response returned by + `post_fulfill_intent` will be passed to + `post_fulfill_intent_with_metadata`. + """ + return response, metadata + def pre_match_intent( self, request: session.MatchIntentRequest, @@ -179,12 +225,35 @@ def post_match_intent( ) -> session.MatchIntentResponse: """Post-rpc interceptor for match_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_match_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_match_intent` interceptor runs + before the `post_match_intent_with_metadata` interceptor. """ return response + def post_match_intent_with_metadata( + self, + response: session.MatchIntentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.MatchIntentResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for match_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_match_intent_with_metadata` + interceptor in new development instead of the `post_match_intent` interceptor. + When both interceptors are used, this `post_match_intent_with_metadata` interceptor runs after the + `post_match_intent` interceptor. The (possibly modified) response returned by + `post_match_intent` will be passed to + `post_match_intent_with_metadata`. + """ + return response, metadata + def pre_server_streaming_detect_intent( self, request: session.DetectIntentRequest, @@ -202,12 +271,37 @@ def post_server_streaming_detect_intent( ) -> rest_streaming.ResponseIterator: """Post-rpc interceptor for server_streaming_detect_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_server_streaming_detect_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_server_streaming_detect_intent` interceptor runs + before the `post_server_streaming_detect_intent_with_metadata` interceptor. """ return response + def post_server_streaming_detect_intent_with_metadata( + self, + response: rest_streaming.ResponseIterator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + rest_streaming.ResponseIterator, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for server_streaming_detect_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_server_streaming_detect_intent_with_metadata` + interceptor in new development instead of the `post_server_streaming_detect_intent` interceptor. + When both interceptors are used, this `post_server_streaming_detect_intent_with_metadata` interceptor runs after the + `post_server_streaming_detect_intent` interceptor. The (possibly modified) response returned by + `post_server_streaming_detect_intent` will be passed to + `post_server_streaming_detect_intent_with_metadata`. + """ + return response, metadata + def pre_submit_answer_feedback( self, request: session.SubmitAnswerFeedbackRequest, @@ -227,12 +321,35 @@ def post_submit_answer_feedback( ) -> session.AnswerFeedback: """Post-rpc interceptor for submit_answer_feedback - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_submit_answer_feedback_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_submit_answer_feedback` interceptor runs + before the `post_submit_answer_feedback_with_metadata` interceptor. """ return response + def post_submit_answer_feedback_with_metadata( + self, + response: session.AnswerFeedback, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.AnswerFeedback, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for submit_answer_feedback + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_submit_answer_feedback_with_metadata` + interceptor in new development instead of the `post_submit_answer_feedback` interceptor. + When both interceptors are used, this `post_submit_answer_feedback_with_metadata` interceptor runs after the + `post_submit_answer_feedback` interceptor. The (possibly modified) response returned by + `post_submit_answer_feedback` will be passed to + `post_submit_answer_feedback_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -573,6 +690,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_detect_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_detect_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -723,6 +844,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fulfill_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fulfill_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -871,6 +996,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_match_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_match_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1022,6 +1151,13 @@ def __call__( ) resp = self._interceptor.post_server_streaming_detect_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_server_streaming_detect_intent_with_metadata( + resp, response_metadata + ) return resp class _StreamingDetectIntent( @@ -1170,6 +1306,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_submit_answer_feedback(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_submit_answer_feedback_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/test_cases/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/test_cases/client.py index 13ef1b5e4c82..aae1f53172b3 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/test_cases/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/test_cases/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -715,6 +717,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2271,16 +2300,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2326,16 +2359,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2436,16 +2473,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2491,16 +2532,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/test_cases/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/test_cases/transports/rest.py index fee7ab3ff04f..36c9383f0bc3 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/test_cases/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/test_cases/transports/rest.py @@ -203,12 +203,35 @@ def post_batch_run_test_cases( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_run_test_cases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_run_test_cases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_batch_run_test_cases` interceptor runs + before the `post_batch_run_test_cases_with_metadata` interceptor. """ return response + def post_batch_run_test_cases_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_run_test_cases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_batch_run_test_cases_with_metadata` + interceptor in new development instead of the `post_batch_run_test_cases` interceptor. + When both interceptors are used, this `post_batch_run_test_cases_with_metadata` interceptor runs after the + `post_batch_run_test_cases` interceptor. The (possibly modified) response returned by + `post_batch_run_test_cases` will be passed to + `post_batch_run_test_cases_with_metadata`. + """ + return response, metadata + def pre_calculate_coverage( self, request: test_case.CalculateCoverageRequest, @@ -228,12 +251,37 @@ def post_calculate_coverage( ) -> test_case.CalculateCoverageResponse: """Post-rpc interceptor for calculate_coverage - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_calculate_coverage_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_calculate_coverage` interceptor runs + before the `post_calculate_coverage_with_metadata` interceptor. """ return response + def post_calculate_coverage_with_metadata( + self, + response: test_case.CalculateCoverageResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + test_case.CalculateCoverageResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for calculate_coverage + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_calculate_coverage_with_metadata` + interceptor in new development instead of the `post_calculate_coverage` interceptor. + When both interceptors are used, this `post_calculate_coverage_with_metadata` interceptor runs after the + `post_calculate_coverage` interceptor. The (possibly modified) response returned by + `post_calculate_coverage` will be passed to + `post_calculate_coverage_with_metadata`. + """ + return response, metadata + def pre_create_test_case( self, request: gcdc_test_case.CreateTestCaseRequest, @@ -253,12 +301,35 @@ def post_create_test_case( ) -> gcdc_test_case.TestCase: """Post-rpc interceptor for create_test_case - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_test_case_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_create_test_case` interceptor runs + before the `post_create_test_case_with_metadata` interceptor. """ return response + def post_create_test_case_with_metadata( + self, + response: gcdc_test_case.TestCase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_test_case.TestCase, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_test_case + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_create_test_case_with_metadata` + interceptor in new development instead of the `post_create_test_case` interceptor. + When both interceptors are used, this `post_create_test_case_with_metadata` interceptor runs after the + `post_create_test_case` interceptor. The (possibly modified) response returned by + `post_create_test_case` will be passed to + `post_create_test_case_with_metadata`. + """ + return response, metadata + def pre_export_test_cases( self, request: test_case.ExportTestCasesRequest, @@ -278,12 +349,35 @@ def post_export_test_cases( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_test_cases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_test_cases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_export_test_cases` interceptor runs + before the `post_export_test_cases_with_metadata` interceptor. """ return response + def post_export_test_cases_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_test_cases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_export_test_cases_with_metadata` + interceptor in new development instead of the `post_export_test_cases` interceptor. + When both interceptors are used, this `post_export_test_cases_with_metadata` interceptor runs after the + `post_export_test_cases` interceptor. The (possibly modified) response returned by + `post_export_test_cases` will be passed to + `post_export_test_cases_with_metadata`. + """ + return response, metadata + def pre_get_test_case( self, request: test_case.GetTestCaseRequest, @@ -299,12 +393,35 @@ def pre_get_test_case( def post_get_test_case(self, response: test_case.TestCase) -> test_case.TestCase: """Post-rpc interceptor for get_test_case - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_test_case_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_get_test_case` interceptor runs + before the `post_get_test_case_with_metadata` interceptor. """ return response + def post_get_test_case_with_metadata( + self, + response: test_case.TestCase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[test_case.TestCase, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_test_case + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_get_test_case_with_metadata` + interceptor in new development instead of the `post_get_test_case` interceptor. + When both interceptors are used, this `post_get_test_case_with_metadata` interceptor runs after the + `post_get_test_case` interceptor. The (possibly modified) response returned by + `post_get_test_case` will be passed to + `post_get_test_case_with_metadata`. + """ + return response, metadata + def pre_get_test_case_result( self, request: test_case.GetTestCaseResultRequest, @@ -324,12 +441,35 @@ def post_get_test_case_result( ) -> test_case.TestCaseResult: """Post-rpc interceptor for get_test_case_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_test_case_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_get_test_case_result` interceptor runs + before the `post_get_test_case_result_with_metadata` interceptor. """ return response + def post_get_test_case_result_with_metadata( + self, + response: test_case.TestCaseResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[test_case.TestCaseResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_test_case_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_get_test_case_result_with_metadata` + interceptor in new development instead of the `post_get_test_case_result` interceptor. + When both interceptors are used, this `post_get_test_case_result_with_metadata` interceptor runs after the + `post_get_test_case_result` interceptor. The (possibly modified) response returned by + `post_get_test_case_result` will be passed to + `post_get_test_case_result_with_metadata`. + """ + return response, metadata + def pre_import_test_cases( self, request: test_case.ImportTestCasesRequest, @@ -349,12 +489,35 @@ def post_import_test_cases( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_test_cases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_test_cases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_import_test_cases` interceptor runs + before the `post_import_test_cases_with_metadata` interceptor. """ return response + def post_import_test_cases_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_test_cases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_import_test_cases_with_metadata` + interceptor in new development instead of the `post_import_test_cases` interceptor. + When both interceptors are used, this `post_import_test_cases_with_metadata` interceptor runs after the + `post_import_test_cases` interceptor. The (possibly modified) response returned by + `post_import_test_cases` will be passed to + `post_import_test_cases_with_metadata`. + """ + return response, metadata + def pre_list_test_case_results( self, request: test_case.ListTestCaseResultsRequest, @@ -374,12 +537,37 @@ def post_list_test_case_results( ) -> test_case.ListTestCaseResultsResponse: """Post-rpc interceptor for list_test_case_results - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_test_case_results_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_list_test_case_results` interceptor runs + before the `post_list_test_case_results_with_metadata` interceptor. """ return response + def post_list_test_case_results_with_metadata( + self, + response: test_case.ListTestCaseResultsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + test_case.ListTestCaseResultsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_test_case_results + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_list_test_case_results_with_metadata` + interceptor in new development instead of the `post_list_test_case_results` interceptor. + When both interceptors are used, this `post_list_test_case_results_with_metadata` interceptor runs after the + `post_list_test_case_results` interceptor. The (possibly modified) response returned by + `post_list_test_case_results` will be passed to + `post_list_test_case_results_with_metadata`. + """ + return response, metadata + def pre_list_test_cases( self, request: test_case.ListTestCasesRequest, @@ -397,12 +585,37 @@ def post_list_test_cases( ) -> test_case.ListTestCasesResponse: """Post-rpc interceptor for list_test_cases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_test_cases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_list_test_cases` interceptor runs + before the `post_list_test_cases_with_metadata` interceptor. """ return response + def post_list_test_cases_with_metadata( + self, + response: test_case.ListTestCasesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + test_case.ListTestCasesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_test_cases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_list_test_cases_with_metadata` + interceptor in new development instead of the `post_list_test_cases` interceptor. + When both interceptors are used, this `post_list_test_cases_with_metadata` interceptor runs after the + `post_list_test_cases` interceptor. The (possibly modified) response returned by + `post_list_test_cases` will be passed to + `post_list_test_cases_with_metadata`. + """ + return response, metadata + def pre_run_test_case( self, request: test_case.RunTestCaseRequest, @@ -420,12 +633,35 @@ def post_run_test_case( ) -> operations_pb2.Operation: """Post-rpc interceptor for run_test_case - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_run_test_case_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_run_test_case` interceptor runs + before the `post_run_test_case_with_metadata` interceptor. """ return response + def post_run_test_case_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for run_test_case + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_run_test_case_with_metadata` + interceptor in new development instead of the `post_run_test_case` interceptor. + When both interceptors are used, this `post_run_test_case_with_metadata` interceptor runs after the + `post_run_test_case` interceptor. The (possibly modified) response returned by + `post_run_test_case` will be passed to + `post_run_test_case_with_metadata`. + """ + return response, metadata + def pre_update_test_case( self, request: gcdc_test_case.UpdateTestCaseRequest, @@ -445,12 +681,35 @@ def post_update_test_case( ) -> gcdc_test_case.TestCase: """Post-rpc interceptor for update_test_case - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_test_case_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_update_test_case` interceptor runs + before the `post_update_test_case_with_metadata` interceptor. """ return response + def post_update_test_case_with_metadata( + self, + response: gcdc_test_case.TestCase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_test_case.TestCase, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_test_case + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_update_test_case_with_metadata` + interceptor in new development instead of the `post_update_test_case` interceptor. + When both interceptors are used, this `post_update_test_case_with_metadata` interceptor runs after the + `post_update_test_case` interceptor. The (possibly modified) response returned by + `post_update_test_case` will be passed to + `post_update_test_case_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -964,6 +1223,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_run_test_cases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_run_test_cases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1109,6 +1372,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_calculate_coverage(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_calculate_coverage_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1266,6 +1533,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_test_case(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_test_case_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1420,6 +1691,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_test_cases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_test_cases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1563,6 +1838,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_test_case(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_test_case_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1708,6 +1987,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_test_case_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_test_case_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1862,6 +2145,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_test_cases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_test_cases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2007,6 +2294,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_test_case_results(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_test_case_results_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2156,6 +2447,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_test_cases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_test_cases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2306,6 +2601,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_run_test_case(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_run_test_case_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2461,6 +2760,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_test_case(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_test_case_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/transition_route_groups/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/transition_route_groups/client.py index f9858b9c6ea2..32c15e505bcc 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/transition_route_groups/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/transition_route_groups/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -598,6 +600,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1490,16 +1519,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1545,16 +1578,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1655,16 +1692,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1710,16 +1751,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/transition_route_groups/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/transition_route_groups/transports/rest.py index 9c2ac7a61985..32a2ce98ef38 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/transition_route_groups/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/transition_route_groups/transports/rest.py @@ -136,12 +136,38 @@ def post_create_transition_route_group( ) -> gcdc_transition_route_group.TransitionRouteGroup: """Post-rpc interceptor for create_transition_route_group - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_transition_route_group_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TransitionRouteGroups server but before - it is returned to user code. + it is returned to user code. This `post_create_transition_route_group` interceptor runs + before the `post_create_transition_route_group_with_metadata` interceptor. """ return response + def post_create_transition_route_group_with_metadata( + self, + response: gcdc_transition_route_group.TransitionRouteGroup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_transition_route_group.TransitionRouteGroup, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for create_transition_route_group + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TransitionRouteGroups server but before it is returned to user code. + + We recommend only using this `post_create_transition_route_group_with_metadata` + interceptor in new development instead of the `post_create_transition_route_group` interceptor. + When both interceptors are used, this `post_create_transition_route_group_with_metadata` interceptor runs after the + `post_create_transition_route_group` interceptor. The (possibly modified) response returned by + `post_create_transition_route_group` will be passed to + `post_create_transition_route_group_with_metadata`. + """ + return response, metadata + def pre_delete_transition_route_group( self, request: transition_route_group.DeleteTransitionRouteGroupRequest, @@ -177,12 +203,38 @@ def post_get_transition_route_group( ) -> transition_route_group.TransitionRouteGroup: """Post-rpc interceptor for get_transition_route_group - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_transition_route_group_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TransitionRouteGroups server but before - it is returned to user code. + it is returned to user code. This `post_get_transition_route_group` interceptor runs + before the `post_get_transition_route_group_with_metadata` interceptor. """ return response + def post_get_transition_route_group_with_metadata( + self, + response: transition_route_group.TransitionRouteGroup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + transition_route_group.TransitionRouteGroup, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_transition_route_group + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TransitionRouteGroups server but before it is returned to user code. + + We recommend only using this `post_get_transition_route_group_with_metadata` + interceptor in new development instead of the `post_get_transition_route_group` interceptor. + When both interceptors are used, this `post_get_transition_route_group_with_metadata` interceptor runs after the + `post_get_transition_route_group` interceptor. The (possibly modified) response returned by + `post_get_transition_route_group` will be passed to + `post_get_transition_route_group_with_metadata`. + """ + return response, metadata + def pre_list_transition_route_groups( self, request: transition_route_group.ListTransitionRouteGroupsRequest, @@ -203,12 +255,38 @@ def post_list_transition_route_groups( ) -> transition_route_group.ListTransitionRouteGroupsResponse: """Post-rpc interceptor for list_transition_route_groups - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_transition_route_groups_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TransitionRouteGroups server but before - it is returned to user code. + it is returned to user code. This `post_list_transition_route_groups` interceptor runs + before the `post_list_transition_route_groups_with_metadata` interceptor. """ return response + def post_list_transition_route_groups_with_metadata( + self, + response: transition_route_group.ListTransitionRouteGroupsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + transition_route_group.ListTransitionRouteGroupsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_transition_route_groups + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TransitionRouteGroups server but before it is returned to user code. + + We recommend only using this `post_list_transition_route_groups_with_metadata` + interceptor in new development instead of the `post_list_transition_route_groups` interceptor. + When both interceptors are used, this `post_list_transition_route_groups_with_metadata` interceptor runs after the + `post_list_transition_route_groups` interceptor. The (possibly modified) response returned by + `post_list_transition_route_groups` will be passed to + `post_list_transition_route_groups_with_metadata`. + """ + return response, metadata + def pre_update_transition_route_group( self, request: gcdc_transition_route_group.UpdateTransitionRouteGroupRequest, @@ -229,12 +307,38 @@ def post_update_transition_route_group( ) -> gcdc_transition_route_group.TransitionRouteGroup: """Post-rpc interceptor for update_transition_route_group - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_transition_route_group_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TransitionRouteGroups server but before - it is returned to user code. + it is returned to user code. This `post_update_transition_route_group` interceptor runs + before the `post_update_transition_route_group_with_metadata` interceptor. """ return response + def post_update_transition_route_group_with_metadata( + self, + response: gcdc_transition_route_group.TransitionRouteGroup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_transition_route_group.TransitionRouteGroup, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_transition_route_group + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TransitionRouteGroups server but before it is returned to user code. + + We recommend only using this `post_update_transition_route_group_with_metadata` + interceptor in new development instead of the `post_update_transition_route_group` interceptor. + When both interceptors are used, this `post_update_transition_route_group_with_metadata` interceptor runs after the + `post_update_transition_route_group` interceptor. The (possibly modified) response returned by + `post_update_transition_route_group` will be passed to + `post_update_transition_route_group_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -578,6 +682,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_transition_route_group(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_create_transition_route_group_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -842,6 +953,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_transition_route_group(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_transition_route_group_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -991,6 +1106,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_transition_route_groups(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_transition_route_groups_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1148,6 +1267,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_transition_route_group(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_update_transition_route_group_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/versions/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/versions/client.py index 547607403536..a6bd01605621 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/versions/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/versions/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -499,6 +501,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1589,16 +1618,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1644,16 +1677,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1754,16 +1791,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1809,16 +1850,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/versions/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/versions/transports/rest.py index d07d31984b31..103589a93385 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/versions/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/versions/transports/rest.py @@ -147,12 +147,37 @@ def post_compare_versions( ) -> version.CompareVersionsResponse: """Post-rpc interceptor for compare_versions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_compare_versions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_compare_versions` interceptor runs + before the `post_compare_versions_with_metadata` interceptor. """ return response + def post_compare_versions_with_metadata( + self, + response: version.CompareVersionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + version.CompareVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for compare_versions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_compare_versions_with_metadata` + interceptor in new development instead of the `post_compare_versions` interceptor. + When both interceptors are used, this `post_compare_versions_with_metadata` interceptor runs after the + `post_compare_versions` interceptor. The (possibly modified) response returned by + `post_compare_versions` will be passed to + `post_compare_versions_with_metadata`. + """ + return response, metadata + def pre_create_version( self, request: gcdc_version.CreateVersionRequest, @@ -172,12 +197,35 @@ def post_create_version( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_create_version` interceptor runs + before the `post_create_version_with_metadata` interceptor. """ return response + def post_create_version_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_create_version_with_metadata` + interceptor in new development instead of the `post_create_version` interceptor. + When both interceptors are used, this `post_create_version_with_metadata` interceptor runs after the + `post_create_version` interceptor. The (possibly modified) response returned by + `post_create_version` will be passed to + `post_create_version_with_metadata`. + """ + return response, metadata + def pre_delete_version( self, request: version.DeleteVersionRequest, @@ -205,12 +253,35 @@ def pre_get_version( def post_get_version(self, response: version.Version) -> version.Version: """Post-rpc interceptor for get_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_get_version` interceptor runs + before the `post_get_version_with_metadata` interceptor. """ return response + def post_get_version_with_metadata( + self, + response: version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_get_version_with_metadata` + interceptor in new development instead of the `post_get_version` interceptor. + When both interceptors are used, this `post_get_version_with_metadata` interceptor runs after the + `post_get_version` interceptor. The (possibly modified) response returned by + `post_get_version` will be passed to + `post_get_version_with_metadata`. + """ + return response, metadata + def pre_list_versions( self, request: version.ListVersionsRequest, @@ -228,12 +299,35 @@ def post_list_versions( ) -> version.ListVersionsResponse: """Post-rpc interceptor for list_versions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_versions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_list_versions` interceptor runs + before the `post_list_versions_with_metadata` interceptor. """ return response + def post_list_versions_with_metadata( + self, + response: version.ListVersionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[version.ListVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_versions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_list_versions_with_metadata` + interceptor in new development instead of the `post_list_versions` interceptor. + When both interceptors are used, this `post_list_versions_with_metadata` interceptor runs after the + `post_list_versions` interceptor. The (possibly modified) response returned by + `post_list_versions` will be passed to + `post_list_versions_with_metadata`. + """ + return response, metadata + def pre_load_version( self, request: version.LoadVersionRequest, @@ -251,12 +345,35 @@ def post_load_version( ) -> operations_pb2.Operation: """Post-rpc interceptor for load_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_load_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_load_version` interceptor runs + before the `post_load_version_with_metadata` interceptor. """ return response + def post_load_version_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for load_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_load_version_with_metadata` + interceptor in new development instead of the `post_load_version` interceptor. + When both interceptors are used, this `post_load_version_with_metadata` interceptor runs after the + `post_load_version` interceptor. The (possibly modified) response returned by + `post_load_version` will be passed to + `post_load_version_with_metadata`. + """ + return response, metadata + def pre_update_version( self, request: gcdc_version.UpdateVersionRequest, @@ -276,12 +393,35 @@ def post_update_version( ) -> gcdc_version.Version: """Post-rpc interceptor for update_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_update_version` interceptor runs + before the `post_update_version_with_metadata` interceptor. """ return response + def post_update_version_with_metadata( + self, + response: gcdc_version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_update_version_with_metadata` + interceptor in new development instead of the `post_update_version` interceptor. + When both interceptors are used, this `post_update_version_with_metadata` interceptor runs after the + `post_update_version` interceptor. The (possibly modified) response returned by + `post_update_version` will be passed to + `post_update_version_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -686,6 +826,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_compare_versions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_compare_versions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -838,6 +982,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1092,6 +1240,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1237,6 +1389,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_versions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_versions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1387,6 +1543,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_load_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_load_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1538,6 +1698,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/webhooks/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/webhooks/client.py index 1ffa69a54c39..22158cd2cd7c 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/webhooks/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/webhooks/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -516,6 +518,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1338,16 +1367,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1393,16 +1426,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1503,16 +1540,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1558,16 +1599,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/webhooks/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/webhooks/transports/rest.py index 68852d55abc2..8224225a2d83 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/webhooks/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3/services/webhooks/transports/rest.py @@ -133,12 +133,35 @@ def post_create_webhook( ) -> gcdc_webhook.Webhook: """Post-rpc interceptor for create_webhook - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_webhook_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Webhooks server but before - it is returned to user code. + it is returned to user code. This `post_create_webhook` interceptor runs + before the `post_create_webhook_with_metadata` interceptor. """ return response + def post_create_webhook_with_metadata( + self, + response: gcdc_webhook.Webhook, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_webhook.Webhook, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_webhook + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Webhooks server but before it is returned to user code. + + We recommend only using this `post_create_webhook_with_metadata` + interceptor in new development instead of the `post_create_webhook` interceptor. + When both interceptors are used, this `post_create_webhook_with_metadata` interceptor runs after the + `post_create_webhook` interceptor. The (possibly modified) response returned by + `post_create_webhook` will be passed to + `post_create_webhook_with_metadata`. + """ + return response, metadata + def pre_delete_webhook( self, request: webhook.DeleteWebhookRequest, @@ -166,12 +189,35 @@ def pre_get_webhook( def post_get_webhook(self, response: webhook.Webhook) -> webhook.Webhook: """Post-rpc interceptor for get_webhook - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_webhook_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Webhooks server but before - it is returned to user code. + it is returned to user code. This `post_get_webhook` interceptor runs + before the `post_get_webhook_with_metadata` interceptor. """ return response + def post_get_webhook_with_metadata( + self, + response: webhook.Webhook, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[webhook.Webhook, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_webhook + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Webhooks server but before it is returned to user code. + + We recommend only using this `post_get_webhook_with_metadata` + interceptor in new development instead of the `post_get_webhook` interceptor. + When both interceptors are used, this `post_get_webhook_with_metadata` interceptor runs after the + `post_get_webhook` interceptor. The (possibly modified) response returned by + `post_get_webhook` will be passed to + `post_get_webhook_with_metadata`. + """ + return response, metadata + def pre_list_webhooks( self, request: webhook.ListWebhooksRequest, @@ -189,12 +235,35 @@ def post_list_webhooks( ) -> webhook.ListWebhooksResponse: """Post-rpc interceptor for list_webhooks - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_webhooks_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Webhooks server but before - it is returned to user code. + it is returned to user code. This `post_list_webhooks` interceptor runs + before the `post_list_webhooks_with_metadata` interceptor. """ return response + def post_list_webhooks_with_metadata( + self, + response: webhook.ListWebhooksResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[webhook.ListWebhooksResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_webhooks + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Webhooks server but before it is returned to user code. + + We recommend only using this `post_list_webhooks_with_metadata` + interceptor in new development instead of the `post_list_webhooks` interceptor. + When both interceptors are used, this `post_list_webhooks_with_metadata` interceptor runs after the + `post_list_webhooks` interceptor. The (possibly modified) response returned by + `post_list_webhooks` will be passed to + `post_list_webhooks_with_metadata`. + """ + return response, metadata + def pre_update_webhook( self, request: gcdc_webhook.UpdateWebhookRequest, @@ -214,12 +283,35 @@ def post_update_webhook( ) -> gcdc_webhook.Webhook: """Post-rpc interceptor for update_webhook - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_webhook_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Webhooks server but before - it is returned to user code. + it is returned to user code. This `post_update_webhook` interceptor runs + before the `post_update_webhook_with_metadata` interceptor. """ return response + def post_update_webhook_with_metadata( + self, + response: gcdc_webhook.Webhook, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_webhook.Webhook, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_webhook + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Webhooks server but before it is returned to user code. + + We recommend only using this `post_update_webhook_with_metadata` + interceptor in new development instead of the `post_update_webhook` interceptor. + When both interceptors are used, this `post_update_webhook_with_metadata` interceptor runs after the + `post_update_webhook` interceptor. The (possibly modified) response returned by + `post_update_webhook` will be passed to + `post_update_webhook_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -566,6 +658,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_webhook(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_webhook_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -827,6 +923,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_webhook(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_webhook_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -972,6 +1072,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_webhooks(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_webhooks_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1130,6 +1234,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_webhook(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_webhook_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER 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 e553ae451f41..558c8aab67c5 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.38.0" # {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/agents/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/agents/client.py index b5c6e3bd3e6b..2e8bcf836510 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/agents/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/agents/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -684,6 +686,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2205,16 +2234,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2260,16 +2293,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2370,16 +2407,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2425,16 +2466,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/agents/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/agents/transports/rest.py index 42eba78e0bc9..567244067d7c 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/agents/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/agents/transports/rest.py @@ -181,12 +181,35 @@ def pre_create_agent( def post_create_agent(self, response: gcdc_agent.Agent) -> gcdc_agent.Agent: """Post-rpc interceptor for create_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_create_agent` interceptor runs + before the `post_create_agent_with_metadata` interceptor. """ return response + def post_create_agent_with_metadata( + self, + response: gcdc_agent.Agent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_create_agent_with_metadata` + interceptor in new development instead of the `post_create_agent` interceptor. + When both interceptors are used, this `post_create_agent_with_metadata` interceptor runs after the + `post_create_agent` interceptor. The (possibly modified) response returned by + `post_create_agent` will be passed to + `post_create_agent_with_metadata`. + """ + return response, metadata + def pre_delete_agent( self, request: agent.DeleteAgentRequest, @@ -216,12 +239,35 @@ def post_export_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_export_agent` interceptor runs + before the `post_export_agent_with_metadata` interceptor. """ return response + def post_export_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_export_agent_with_metadata` + interceptor in new development instead of the `post_export_agent` interceptor. + When both interceptors are used, this `post_export_agent_with_metadata` interceptor runs after the + `post_export_agent` interceptor. The (possibly modified) response returned by + `post_export_agent` will be passed to + `post_export_agent_with_metadata`. + """ + return response, metadata + def pre_get_agent( self, request: agent.GetAgentRequest, @@ -237,12 +283,33 @@ def pre_get_agent( def post_get_agent(self, response: agent.Agent) -> agent.Agent: """Post-rpc interceptor for get_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_agent` interceptor runs + before the `post_get_agent_with_metadata` interceptor. """ return response + def post_get_agent_with_metadata( + self, response: agent.Agent, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_agent_with_metadata` + interceptor in new development instead of the `post_get_agent` interceptor. + When both interceptors are used, this `post_get_agent_with_metadata` interceptor runs after the + `post_get_agent` interceptor. The (possibly modified) response returned by + `post_get_agent` will be passed to + `post_get_agent_with_metadata`. + """ + return response, metadata + def pre_get_agent_validation_result( self, request: agent.GetAgentValidationResultRequest, @@ -262,12 +329,35 @@ def post_get_agent_validation_result( ) -> agent.AgentValidationResult: """Post-rpc interceptor for get_agent_validation_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_agent_validation_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_agent_validation_result` interceptor runs + before the `post_get_agent_validation_result_with_metadata` interceptor. """ return response + def post_get_agent_validation_result_with_metadata( + self, + response: agent.AgentValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[agent.AgentValidationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_agent_validation_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_agent_validation_result_with_metadata` + interceptor in new development instead of the `post_get_agent_validation_result` interceptor. + When both interceptors are used, this `post_get_agent_validation_result_with_metadata` interceptor runs after the + `post_get_agent_validation_result` interceptor. The (possibly modified) response returned by + `post_get_agent_validation_result` will be passed to + `post_get_agent_validation_result_with_metadata`. + """ + return response, metadata + def pre_get_generative_settings( self, request: agent.GetGenerativeSettingsRequest, @@ -287,12 +377,37 @@ def post_get_generative_settings( ) -> generative_settings.GenerativeSettings: """Post-rpc interceptor for get_generative_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_generative_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_generative_settings` interceptor runs + before the `post_get_generative_settings_with_metadata` interceptor. """ return response + def post_get_generative_settings_with_metadata( + self, + response: generative_settings.GenerativeSettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generative_settings.GenerativeSettings, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_generative_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_generative_settings_with_metadata` + interceptor in new development instead of the `post_get_generative_settings` interceptor. + When both interceptors are used, this `post_get_generative_settings_with_metadata` interceptor runs after the + `post_get_generative_settings` interceptor. The (possibly modified) response returned by + `post_get_generative_settings` will be passed to + `post_get_generative_settings_with_metadata`. + """ + return response, metadata + def pre_list_agents( self, request: agent.ListAgentsRequest, @@ -310,12 +425,35 @@ def post_list_agents( ) -> agent.ListAgentsResponse: """Post-rpc interceptor for list_agents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_agents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_list_agents` interceptor runs + before the `post_list_agents_with_metadata` interceptor. """ return response + def post_list_agents_with_metadata( + self, + response: agent.ListAgentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[agent.ListAgentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_agents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_list_agents_with_metadata` + interceptor in new development instead of the `post_list_agents` interceptor. + When both interceptors are used, this `post_list_agents_with_metadata` interceptor runs after the + `post_list_agents` interceptor. The (possibly modified) response returned by + `post_list_agents` will be passed to + `post_list_agents_with_metadata`. + """ + return response, metadata + def pre_restore_agent( self, request: agent.RestoreAgentRequest, @@ -333,12 +471,35 @@ def post_restore_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for restore_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_restore_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_restore_agent` interceptor runs + before the `post_restore_agent_with_metadata` interceptor. """ return response + def post_restore_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for restore_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_restore_agent_with_metadata` + interceptor in new development instead of the `post_restore_agent` interceptor. + When both interceptors are used, this `post_restore_agent_with_metadata` interceptor runs after the + `post_restore_agent` interceptor. The (possibly modified) response returned by + `post_restore_agent` will be passed to + `post_restore_agent_with_metadata`. + """ + return response, metadata + def pre_update_agent( self, request: gcdc_agent.UpdateAgentRequest, @@ -354,12 +515,35 @@ def pre_update_agent( def post_update_agent(self, response: gcdc_agent.Agent) -> gcdc_agent.Agent: """Post-rpc interceptor for update_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_update_agent` interceptor runs + before the `post_update_agent_with_metadata` interceptor. """ return response + def post_update_agent_with_metadata( + self, + response: gcdc_agent.Agent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_update_agent_with_metadata` + interceptor in new development instead of the `post_update_agent` interceptor. + When both interceptors are used, this `post_update_agent_with_metadata` interceptor runs after the + `post_update_agent` interceptor. The (possibly modified) response returned by + `post_update_agent` will be passed to + `post_update_agent_with_metadata`. + """ + return response, metadata + def pre_update_generative_settings( self, request: agent.UpdateGenerativeSettingsRequest, @@ -379,12 +563,38 @@ def post_update_generative_settings( ) -> gcdc_generative_settings.GenerativeSettings: """Post-rpc interceptor for update_generative_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_generative_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_update_generative_settings` interceptor runs + before the `post_update_generative_settings_with_metadata` interceptor. """ return response + def post_update_generative_settings_with_metadata( + self, + response: gcdc_generative_settings.GenerativeSettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_generative_settings.GenerativeSettings, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_generative_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_update_generative_settings_with_metadata` + interceptor in new development instead of the `post_update_generative_settings` interceptor. + When both interceptors are used, this `post_update_generative_settings_with_metadata` interceptor runs after the + `post_update_generative_settings` interceptor. The (possibly modified) response returned by + `post_update_generative_settings` will be passed to + `post_update_generative_settings_with_metadata`. + """ + return response, metadata + def pre_validate_agent( self, request: agent.ValidateAgentRequest, @@ -402,12 +612,35 @@ def post_validate_agent( ) -> agent.AgentValidationResult: """Post-rpc interceptor for validate_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_validate_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_validate_agent` interceptor runs + before the `post_validate_agent_with_metadata` interceptor. """ return response + def post_validate_agent_with_metadata( + self, + response: agent.AgentValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[agent.AgentValidationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for validate_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_validate_agent_with_metadata` + interceptor in new development instead of the `post_validate_agent` interceptor. + When both interceptors are used, this `post_validate_agent_with_metadata` interceptor runs after the + `post_validate_agent` interceptor. The (possibly modified) response returned by + `post_validate_agent` will be passed to + `post_validate_agent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -817,6 +1050,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1072,6 +1309,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1228,6 +1469,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1374,6 +1619,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_agent_validation_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_agent_validation_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1518,6 +1767,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_generative_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_generative_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1663,6 +1916,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_agents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_agents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1813,6 +2070,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_restore_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_restore_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1975,6 +2236,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2126,6 +2391,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_generative_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_generative_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2279,6 +2548,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_validate_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_validate_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/changelogs/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/changelogs/client.py index 17124cb8bb42..0fcd2e267b76 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/changelogs/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/changelogs/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -490,6 +492,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -965,16 +994,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1020,16 +1053,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1130,16 +1167,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1185,16 +1226,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/changelogs/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/changelogs/transports/rest.py index 70684498a666..69888a78074b 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/changelogs/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/changelogs/transports/rest.py @@ -107,12 +107,35 @@ def pre_get_changelog( def post_get_changelog(self, response: changelog.Changelog) -> changelog.Changelog: """Post-rpc interceptor for get_changelog - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_changelog_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Changelogs server but before - it is returned to user code. + it is returned to user code. This `post_get_changelog` interceptor runs + before the `post_get_changelog_with_metadata` interceptor. """ return response + def post_get_changelog_with_metadata( + self, + response: changelog.Changelog, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[changelog.Changelog, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_changelog + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Changelogs server but before it is returned to user code. + + We recommend only using this `post_get_changelog_with_metadata` + interceptor in new development instead of the `post_get_changelog` interceptor. + When both interceptors are used, this `post_get_changelog_with_metadata` interceptor runs after the + `post_get_changelog` interceptor. The (possibly modified) response returned by + `post_get_changelog` will be passed to + `post_get_changelog_with_metadata`. + """ + return response, metadata + def pre_list_changelogs( self, request: changelog.ListChangelogsRequest, @@ -132,12 +155,37 @@ def post_list_changelogs( ) -> changelog.ListChangelogsResponse: """Post-rpc interceptor for list_changelogs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_changelogs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Changelogs server but before - it is returned to user code. + it is returned to user code. This `post_list_changelogs` interceptor runs + before the `post_list_changelogs_with_metadata` interceptor. """ return response + def post_list_changelogs_with_metadata( + self, + response: changelog.ListChangelogsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + changelog.ListChangelogsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_changelogs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Changelogs server but before it is returned to user code. + + We recommend only using this `post_list_changelogs_with_metadata` + interceptor in new development instead of the `post_list_changelogs` interceptor. + When both interceptors are used, this `post_list_changelogs_with_metadata` interceptor runs after the + `post_list_changelogs` interceptor. The (possibly modified) response returned by + `post_list_changelogs` will be passed to + `post_list_changelogs_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -473,6 +521,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_changelog(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_changelog_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -618,6 +670,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_changelogs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_changelogs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/conversation_history/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/conversation_history/client.py index c65885bf7b65..61b953edc57f 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/conversation_history/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/conversation_history/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -889,6 +891,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1470,16 +1499,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1525,16 +1558,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1635,16 +1672,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1690,16 +1731,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/conversation_history/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/conversation_history/transports/rest.py index 5f75ba65b14d..b6ad58506aba 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/conversation_history/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/conversation_history/transports/rest.py @@ -132,12 +132,37 @@ def post_get_conversation( ) -> conversation_history.Conversation: """Post-rpc interceptor for get_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationHistory server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation` interceptor runs + before the `post_get_conversation_with_metadata` interceptor. """ return response + def post_get_conversation_with_metadata( + self, + response: conversation_history.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_history.Conversation, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationHistory server but before it is returned to user code. + + We recommend only using this `post_get_conversation_with_metadata` + interceptor in new development instead of the `post_get_conversation` interceptor. + When both interceptors are used, this `post_get_conversation_with_metadata` interceptor runs after the + `post_get_conversation` interceptor. The (possibly modified) response returned by + `post_get_conversation` will be passed to + `post_get_conversation_with_metadata`. + """ + return response, metadata + def pre_list_conversations( self, request: conversation_history.ListConversationsRequest, @@ -158,12 +183,38 @@ def post_list_conversations( ) -> conversation_history.ListConversationsResponse: """Post-rpc interceptor for list_conversations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationHistory server but before - it is returned to user code. + it is returned to user code. This `post_list_conversations` interceptor runs + before the `post_list_conversations_with_metadata` interceptor. """ return response + def post_list_conversations_with_metadata( + self, + response: conversation_history.ListConversationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_history.ListConversationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_conversations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationHistory server but before it is returned to user code. + + We recommend only using this `post_list_conversations_with_metadata` + interceptor in new development instead of the `post_list_conversations` interceptor. + When both interceptors are used, this `post_list_conversations_with_metadata` interceptor runs after the + `post_list_conversations` interceptor. The (possibly modified) response returned by + `post_list_conversations` will be passed to + `post_list_conversations_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -607,6 +658,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -757,6 +812,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/deployments/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/deployments/client.py index 8f41ed229e35..4c12856ebb85 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/deployments/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/deployments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -570,6 +572,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1056,16 +1085,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1111,16 +1144,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1221,16 +1258,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1276,16 +1317,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/deployments/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/deployments/transports/rest.py index 61cdb184c537..ed714a27b598 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/deployments/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/deployments/transports/rest.py @@ -111,12 +111,35 @@ def post_get_deployment( ) -> deployment.Deployment: """Post-rpc interceptor for get_deployment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_deployment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Deployments server but before - it is returned to user code. + it is returned to user code. This `post_get_deployment` interceptor runs + before the `post_get_deployment_with_metadata` interceptor. """ return response + def post_get_deployment_with_metadata( + self, + response: deployment.Deployment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[deployment.Deployment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_deployment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Deployments server but before it is returned to user code. + + We recommend only using this `post_get_deployment_with_metadata` + interceptor in new development instead of the `post_get_deployment` interceptor. + When both interceptors are used, this `post_get_deployment_with_metadata` interceptor runs after the + `post_get_deployment` interceptor. The (possibly modified) response returned by + `post_get_deployment` will be passed to + `post_get_deployment_with_metadata`. + """ + return response, metadata + def pre_list_deployments( self, request: deployment.ListDeploymentsRequest, @@ -136,12 +159,37 @@ def post_list_deployments( ) -> deployment.ListDeploymentsResponse: """Post-rpc interceptor for list_deployments - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_deployments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Deployments server but before - it is returned to user code. + it is returned to user code. This `post_list_deployments` interceptor runs + before the `post_list_deployments_with_metadata` interceptor. """ return response + def post_list_deployments_with_metadata( + self, + response: deployment.ListDeploymentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + deployment.ListDeploymentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_deployments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Deployments server but before it is returned to user code. + + We recommend only using this `post_list_deployments_with_metadata` + interceptor in new development instead of the `post_list_deployments` interceptor. + When both interceptors are used, this `post_list_deployments_with_metadata` interceptor runs after the + `post_list_deployments` interceptor. The (possibly modified) response returned by + `post_list_deployments` will be passed to + `post_list_deployments_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -480,6 +528,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_deployment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_deployment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -625,6 +677,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_deployments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_deployments_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/entity_types/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/entity_types/client.py index e9067958c2f1..fc6f10ac8954 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/entity_types/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/entity_types/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -493,6 +495,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1604,16 +1633,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1659,16 +1692,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1769,16 +1806,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1824,16 +1865,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/entity_types/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/entity_types/transports/rest.py index ee2ebb79bf6d..a6919dbce3bf 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/entity_types/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/entity_types/transports/rest.py @@ -150,12 +150,35 @@ def post_create_entity_type( ) -> gcdc_entity_type.EntityType: """Post-rpc interceptor for create_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_create_entity_type` interceptor runs + before the `post_create_entity_type_with_metadata` interceptor. """ return response + def post_create_entity_type_with_metadata( + self, + response: gcdc_entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_create_entity_type_with_metadata` + interceptor in new development instead of the `post_create_entity_type` interceptor. + When both interceptors are used, this `post_create_entity_type_with_metadata` interceptor runs after the + `post_create_entity_type` interceptor. The (possibly modified) response returned by + `post_create_entity_type` will be passed to + `post_create_entity_type_with_metadata`. + """ + return response, metadata + def pre_delete_entity_type( self, request: entity_type.DeleteEntityTypeRequest, @@ -189,12 +212,35 @@ def post_export_entity_types( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_export_entity_types` interceptor runs + before the `post_export_entity_types_with_metadata` interceptor. """ return response + def post_export_entity_types_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_export_entity_types_with_metadata` + interceptor in new development instead of the `post_export_entity_types` interceptor. + When both interceptors are used, this `post_export_entity_types_with_metadata` interceptor runs after the + `post_export_entity_types` interceptor. The (possibly modified) response returned by + `post_export_entity_types` will be passed to + `post_export_entity_types_with_metadata`. + """ + return response, metadata + def pre_get_entity_type( self, request: entity_type.GetEntityTypeRequest, @@ -214,12 +260,35 @@ def post_get_entity_type( ) -> entity_type.EntityType: """Post-rpc interceptor for get_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_get_entity_type` interceptor runs + before the `post_get_entity_type_with_metadata` interceptor. """ return response + def post_get_entity_type_with_metadata( + self, + response: entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_get_entity_type_with_metadata` + interceptor in new development instead of the `post_get_entity_type` interceptor. + When both interceptors are used, this `post_get_entity_type_with_metadata` interceptor runs after the + `post_get_entity_type` interceptor. The (possibly modified) response returned by + `post_get_entity_type` will be passed to + `post_get_entity_type_with_metadata`. + """ + return response, metadata + def pre_import_entity_types( self, request: entity_type.ImportEntityTypesRequest, @@ -239,12 +308,35 @@ def post_import_entity_types( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_import_entity_types` interceptor runs + before the `post_import_entity_types_with_metadata` interceptor. """ return response + def post_import_entity_types_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_import_entity_types_with_metadata` + interceptor in new development instead of the `post_import_entity_types` interceptor. + When both interceptors are used, this `post_import_entity_types_with_metadata` interceptor runs after the + `post_import_entity_types` interceptor. The (possibly modified) response returned by + `post_import_entity_types` will be passed to + `post_import_entity_types_with_metadata`. + """ + return response, metadata + def pre_list_entity_types( self, request: entity_type.ListEntityTypesRequest, @@ -264,12 +356,37 @@ def post_list_entity_types( ) -> entity_type.ListEntityTypesResponse: """Post-rpc interceptor for list_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_list_entity_types` interceptor runs + before the `post_list_entity_types_with_metadata` interceptor. """ return response + def post_list_entity_types_with_metadata( + self, + response: entity_type.ListEntityTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + entity_type.ListEntityTypesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_list_entity_types_with_metadata` + interceptor in new development instead of the `post_list_entity_types` interceptor. + When both interceptors are used, this `post_list_entity_types_with_metadata` interceptor runs after the + `post_list_entity_types` interceptor. The (possibly modified) response returned by + `post_list_entity_types` will be passed to + `post_list_entity_types_with_metadata`. + """ + return response, metadata + def pre_update_entity_type( self, request: gcdc_entity_type.UpdateEntityTypeRequest, @@ -290,12 +407,35 @@ def post_update_entity_type( ) -> gcdc_entity_type.EntityType: """Post-rpc interceptor for update_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_update_entity_type` interceptor runs + before the `post_update_entity_type_with_metadata` interceptor. """ return response + def post_update_entity_type_with_metadata( + self, + response: gcdc_entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_update_entity_type_with_metadata` + interceptor in new development instead of the `post_update_entity_type` interceptor. + When both interceptors are used, this `post_update_entity_type_with_metadata` interceptor runs after the + `post_update_entity_type` interceptor. The (possibly modified) response returned by + `post_update_entity_type` will be passed to + `post_update_entity_type_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -727,6 +867,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -986,6 +1130,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1164,6 +1312,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1314,6 +1466,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1459,6 +1615,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1645,6 +1805,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/environments/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/environments/client.py index cf0e4c147ce6..f85ca79fdd64 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/environments/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/environments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -645,6 +647,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2021,16 +2050,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2076,16 +2109,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2186,16 +2223,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2241,16 +2282,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/environments/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/environments/transports/rest.py index 4f794357c8d3..6163818d34d6 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/environments/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/environments/transports/rest.py @@ -166,12 +166,35 @@ def post_create_environment( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_create_environment` interceptor runs + before the `post_create_environment_with_metadata` interceptor. """ return response + def post_create_environment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_create_environment_with_metadata` + interceptor in new development instead of the `post_create_environment` interceptor. + When both interceptors are used, this `post_create_environment_with_metadata` interceptor runs after the + `post_create_environment` interceptor. The (possibly modified) response returned by + `post_create_environment` will be passed to + `post_create_environment_with_metadata`. + """ + return response, metadata + def pre_delete_environment( self, request: environment.DeleteEnvironmentRequest, @@ -203,12 +226,35 @@ def post_deploy_flow( ) -> operations_pb2.Operation: """Post-rpc interceptor for deploy_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_deploy_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_deploy_flow` interceptor runs + before the `post_deploy_flow_with_metadata` interceptor. """ return response + def post_deploy_flow_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for deploy_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_deploy_flow_with_metadata` + interceptor in new development instead of the `post_deploy_flow` interceptor. + When both interceptors are used, this `post_deploy_flow_with_metadata` interceptor runs after the + `post_deploy_flow` interceptor. The (possibly modified) response returned by + `post_deploy_flow` will be passed to + `post_deploy_flow_with_metadata`. + """ + return response, metadata + def pre_get_environment( self, request: environment.GetEnvironmentRequest, @@ -228,12 +274,35 @@ def post_get_environment( ) -> environment.Environment: """Post-rpc interceptor for get_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_get_environment` interceptor runs + before the `post_get_environment_with_metadata` interceptor. """ return response + def post_get_environment_with_metadata( + self, + response: environment.Environment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.Environment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_get_environment_with_metadata` + interceptor in new development instead of the `post_get_environment` interceptor. + When both interceptors are used, this `post_get_environment_with_metadata` interceptor runs after the + `post_get_environment` interceptor. The (possibly modified) response returned by + `post_get_environment` will be passed to + `post_get_environment_with_metadata`. + """ + return response, metadata + def pre_list_continuous_test_results( self, request: environment.ListContinuousTestResultsRequest, @@ -254,12 +323,38 @@ def post_list_continuous_test_results( ) -> environment.ListContinuousTestResultsResponse: """Post-rpc interceptor for list_continuous_test_results - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_continuous_test_results_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_list_continuous_test_results` interceptor runs + before the `post_list_continuous_test_results_with_metadata` interceptor. """ return response + def post_list_continuous_test_results_with_metadata( + self, + response: environment.ListContinuousTestResultsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + environment.ListContinuousTestResultsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_continuous_test_results + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_list_continuous_test_results_with_metadata` + interceptor in new development instead of the `post_list_continuous_test_results` interceptor. + When both interceptors are used, this `post_list_continuous_test_results_with_metadata` interceptor runs after the + `post_list_continuous_test_results` interceptor. The (possibly modified) response returned by + `post_list_continuous_test_results` will be passed to + `post_list_continuous_test_results_with_metadata`. + """ + return response, metadata + def pre_list_environments( self, request: environment.ListEnvironmentsRequest, @@ -279,12 +374,37 @@ def post_list_environments( ) -> environment.ListEnvironmentsResponse: """Post-rpc interceptor for list_environments - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_environments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_list_environments` interceptor runs + before the `post_list_environments_with_metadata` interceptor. """ return response + def post_list_environments_with_metadata( + self, + response: environment.ListEnvironmentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + environment.ListEnvironmentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_environments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_list_environments_with_metadata` + interceptor in new development instead of the `post_list_environments` interceptor. + When both interceptors are used, this `post_list_environments_with_metadata` interceptor runs after the + `post_list_environments` interceptor. The (possibly modified) response returned by + `post_list_environments` will be passed to + `post_list_environments_with_metadata`. + """ + return response, metadata + def pre_lookup_environment_history( self, request: environment.LookupEnvironmentHistoryRequest, @@ -305,12 +425,38 @@ def post_lookup_environment_history( ) -> environment.LookupEnvironmentHistoryResponse: """Post-rpc interceptor for lookup_environment_history - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_lookup_environment_history_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_lookup_environment_history` interceptor runs + before the `post_lookup_environment_history_with_metadata` interceptor. """ return response + def post_lookup_environment_history_with_metadata( + self, + response: environment.LookupEnvironmentHistoryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + environment.LookupEnvironmentHistoryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for lookup_environment_history + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_lookup_environment_history_with_metadata` + interceptor in new development instead of the `post_lookup_environment_history` interceptor. + When both interceptors are used, this `post_lookup_environment_history_with_metadata` interceptor runs after the + `post_lookup_environment_history` interceptor. The (possibly modified) response returned by + `post_lookup_environment_history` will be passed to + `post_lookup_environment_history_with_metadata`. + """ + return response, metadata + def pre_run_continuous_test( self, request: environment.RunContinuousTestRequest, @@ -330,12 +476,35 @@ def post_run_continuous_test( ) -> operations_pb2.Operation: """Post-rpc interceptor for run_continuous_test - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_run_continuous_test_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_run_continuous_test` interceptor runs + before the `post_run_continuous_test_with_metadata` interceptor. """ return response + def post_run_continuous_test_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for run_continuous_test + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_run_continuous_test_with_metadata` + interceptor in new development instead of the `post_run_continuous_test` interceptor. + When both interceptors are used, this `post_run_continuous_test_with_metadata` interceptor runs after the + `post_run_continuous_test` interceptor. The (possibly modified) response returned by + `post_run_continuous_test` will be passed to + `post_run_continuous_test_with_metadata`. + """ + return response, metadata + def pre_update_environment( self, request: gcdc_environment.UpdateEnvironmentRequest, @@ -356,12 +525,35 @@ def post_update_environment( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_update_environment` interceptor runs + before the `post_update_environment_with_metadata` interceptor. """ return response + def post_update_environment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_update_environment_with_metadata` + interceptor in new development instead of the `post_update_environment` interceptor. + When both interceptors are used, this `post_update_environment_with_metadata` interceptor runs after the + `post_update_environment` interceptor. The (possibly modified) response returned by + `post_update_environment` will be passed to + `post_update_environment_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -759,6 +951,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1022,6 +1218,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_deploy_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_deploy_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1178,6 +1378,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1327,6 +1531,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_continuous_test_results(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_continuous_test_results_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1474,6 +1682,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_environments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_environments_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1625,6 +1837,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_lookup_environment_history(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_lookup_environment_history_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1777,6 +1993,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_run_continuous_test(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_run_continuous_test_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1927,6 +2147,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/examples/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/examples/client.py index 673ec91b0158..ab8c35624543 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/examples/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/examples/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -566,6 +568,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1387,16 +1416,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1442,16 +1475,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1552,16 +1589,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1607,16 +1648,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/examples/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/examples/transports/rest.py index 53a1d578fd0a..3b161503e716 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/examples/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/examples/transports/rest.py @@ -133,12 +133,35 @@ def post_create_example( ) -> gcdc_example.Example: """Post-rpc interceptor for create_example - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_example_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Examples server but before - it is returned to user code. + it is returned to user code. This `post_create_example` interceptor runs + before the `post_create_example_with_metadata` interceptor. """ return response + def post_create_example_with_metadata( + self, + response: gcdc_example.Example, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_example.Example, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_example + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Examples server but before it is returned to user code. + + We recommend only using this `post_create_example_with_metadata` + interceptor in new development instead of the `post_create_example` interceptor. + When both interceptors are used, this `post_create_example_with_metadata` interceptor runs after the + `post_create_example` interceptor. The (possibly modified) response returned by + `post_create_example` will be passed to + `post_create_example_with_metadata`. + """ + return response, metadata + def pre_delete_example( self, request: example.DeleteExampleRequest, @@ -166,12 +189,35 @@ def pre_get_example( def post_get_example(self, response: example.Example) -> example.Example: """Post-rpc interceptor for get_example - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_example_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Examples server but before - it is returned to user code. + it is returned to user code. This `post_get_example` interceptor runs + before the `post_get_example_with_metadata` interceptor. """ return response + def post_get_example_with_metadata( + self, + response: example.Example, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[example.Example, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_example + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Examples server but before it is returned to user code. + + We recommend only using this `post_get_example_with_metadata` + interceptor in new development instead of the `post_get_example` interceptor. + When both interceptors are used, this `post_get_example_with_metadata` interceptor runs after the + `post_get_example` interceptor. The (possibly modified) response returned by + `post_get_example` will be passed to + `post_get_example_with_metadata`. + """ + return response, metadata + def pre_list_examples( self, request: example.ListExamplesRequest, @@ -189,12 +235,35 @@ def post_list_examples( ) -> example.ListExamplesResponse: """Post-rpc interceptor for list_examples - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_examples_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Examples server but before - it is returned to user code. + it is returned to user code. This `post_list_examples` interceptor runs + before the `post_list_examples_with_metadata` interceptor. """ return response + def post_list_examples_with_metadata( + self, + response: example.ListExamplesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[example.ListExamplesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_examples + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Examples server but before it is returned to user code. + + We recommend only using this `post_list_examples_with_metadata` + interceptor in new development instead of the `post_list_examples` interceptor. + When both interceptors are used, this `post_list_examples_with_metadata` interceptor runs after the + `post_list_examples` interceptor. The (possibly modified) response returned by + `post_list_examples` will be passed to + `post_list_examples_with_metadata`. + """ + return response, metadata + def pre_update_example( self, request: gcdc_example.UpdateExampleRequest, @@ -214,12 +283,35 @@ def post_update_example( ) -> gcdc_example.Example: """Post-rpc interceptor for update_example - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_example_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Examples server but before - it is returned to user code. + it is returned to user code. This `post_update_example` interceptor runs + before the `post_update_example_with_metadata` interceptor. """ return response + def post_update_example_with_metadata( + self, + response: gcdc_example.Example, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_example.Example, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_example + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Examples server but before it is returned to user code. + + We recommend only using this `post_update_example_with_metadata` + interceptor in new development instead of the `post_update_example` interceptor. + When both interceptors are used, this `post_update_example_with_metadata` interceptor runs after the + `post_update_example` interceptor. The (possibly modified) response returned by + `post_update_example` will be passed to + `post_update_example_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -565,6 +657,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_example(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_example_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -825,6 +921,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_example(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_example_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -970,6 +1070,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_examples(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_examples_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1127,6 +1231,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_example(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_example_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/experiments/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/experiments/client.py index ac941d1bc57a..21ad602745d4 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/experiments/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/experiments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -521,6 +523,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1559,16 +1588,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1614,16 +1647,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1724,16 +1761,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1779,16 +1820,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/experiments/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/experiments/transports/rest.py index ddad4233a266..5617fc9ee8b5 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/experiments/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/experiments/transports/rest.py @@ -149,12 +149,35 @@ def post_create_experiment( ) -> gcdc_experiment.Experiment: """Post-rpc interceptor for create_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_create_experiment` interceptor runs + before the `post_create_experiment_with_metadata` interceptor. """ return response + def post_create_experiment_with_metadata( + self, + response: gcdc_experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_create_experiment_with_metadata` + interceptor in new development instead of the `post_create_experiment` interceptor. + When both interceptors are used, this `post_create_experiment_with_metadata` interceptor runs after the + `post_create_experiment` interceptor. The (possibly modified) response returned by + `post_create_experiment` will be passed to + `post_create_experiment_with_metadata`. + """ + return response, metadata + def pre_delete_experiment( self, request: experiment.DeleteExperimentRequest, @@ -188,12 +211,35 @@ def post_get_experiment( ) -> experiment.Experiment: """Post-rpc interceptor for get_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_get_experiment` interceptor runs + before the `post_get_experiment_with_metadata` interceptor. """ return response + def post_get_experiment_with_metadata( + self, + response: experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_get_experiment_with_metadata` + interceptor in new development instead of the `post_get_experiment` interceptor. + When both interceptors are used, this `post_get_experiment_with_metadata` interceptor runs after the + `post_get_experiment` interceptor. The (possibly modified) response returned by + `post_get_experiment` will be passed to + `post_get_experiment_with_metadata`. + """ + return response, metadata + def pre_list_experiments( self, request: experiment.ListExperimentsRequest, @@ -213,12 +259,37 @@ def post_list_experiments( ) -> experiment.ListExperimentsResponse: """Post-rpc interceptor for list_experiments - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_experiments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_list_experiments` interceptor runs + before the `post_list_experiments_with_metadata` interceptor. """ return response + def post_list_experiments_with_metadata( + self, + response: experiment.ListExperimentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + experiment.ListExperimentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_experiments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_list_experiments_with_metadata` + interceptor in new development instead of the `post_list_experiments` interceptor. + When both interceptors are used, this `post_list_experiments_with_metadata` interceptor runs after the + `post_list_experiments` interceptor. The (possibly modified) response returned by + `post_list_experiments` will be passed to + `post_list_experiments_with_metadata`. + """ + return response, metadata + def pre_start_experiment( self, request: experiment.StartExperimentRequest, @@ -238,12 +309,35 @@ def post_start_experiment( ) -> experiment.Experiment: """Post-rpc interceptor for start_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_start_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_start_experiment` interceptor runs + before the `post_start_experiment_with_metadata` interceptor. """ return response + def post_start_experiment_with_metadata( + self, + response: experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for start_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_start_experiment_with_metadata` + interceptor in new development instead of the `post_start_experiment` interceptor. + When both interceptors are used, this `post_start_experiment_with_metadata` interceptor runs after the + `post_start_experiment` interceptor. The (possibly modified) response returned by + `post_start_experiment` will be passed to + `post_start_experiment_with_metadata`. + """ + return response, metadata + def pre_stop_experiment( self, request: experiment.StopExperimentRequest, @@ -263,12 +357,35 @@ def post_stop_experiment( ) -> experiment.Experiment: """Post-rpc interceptor for stop_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_stop_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_stop_experiment` interceptor runs + before the `post_stop_experiment_with_metadata` interceptor. """ return response + def post_stop_experiment_with_metadata( + self, + response: experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for stop_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_stop_experiment_with_metadata` + interceptor in new development instead of the `post_stop_experiment` interceptor. + When both interceptors are used, this `post_stop_experiment_with_metadata` interceptor runs after the + `post_stop_experiment` interceptor. The (possibly modified) response returned by + `post_stop_experiment` will be passed to + `post_stop_experiment_with_metadata`. + """ + return response, metadata + def pre_update_experiment( self, request: gcdc_experiment.UpdateExperimentRequest, @@ -288,12 +405,35 @@ def post_update_experiment( ) -> gcdc_experiment.Experiment: """Post-rpc interceptor for update_experiment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_experiment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Experiments server but before - it is returned to user code. + it is returned to user code. This `post_update_experiment` interceptor runs + before the `post_update_experiment_with_metadata` interceptor. """ return response + def post_update_experiment_with_metadata( + self, + response: gcdc_experiment.Experiment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_experiment.Experiment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_experiment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Experiments server but before it is returned to user code. + + We recommend only using this `post_update_experiment_with_metadata` + interceptor in new development instead of the `post_update_experiment` interceptor. + When both interceptors are used, this `post_update_experiment_with_metadata` interceptor runs after the + `post_update_experiment` interceptor. The (possibly modified) response returned by + `post_update_experiment` will be passed to + `post_update_experiment_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -633,6 +773,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -887,6 +1031,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1032,6 +1180,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_experiments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_experiments_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1185,6 +1337,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_start_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_start_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1334,6 +1490,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_stop_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_stop_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1485,6 +1645,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_experiment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_experiment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER 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 1dd77ed0f356..52d7c93470a1 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 @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -670,6 +672,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2107,16 +2136,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2162,16 +2195,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2272,16 +2309,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2327,16 +2368,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/transports/rest.py index b6a572a36f51..a02b924decac 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/flows/transports/rest.py @@ -169,12 +169,35 @@ def pre_create_flow( def post_create_flow(self, response: gcdc_flow.Flow) -> gcdc_flow.Flow: """Post-rpc interceptor for create_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_create_flow` interceptor runs + before the `post_create_flow_with_metadata` interceptor. """ return response + def post_create_flow_with_metadata( + self, + response: gcdc_flow.Flow, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_flow.Flow, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_create_flow_with_metadata` + interceptor in new development instead of the `post_create_flow` interceptor. + When both interceptors are used, this `post_create_flow_with_metadata` interceptor runs after the + `post_create_flow` interceptor. The (possibly modified) response returned by + `post_create_flow` will be passed to + `post_create_flow_with_metadata`. + """ + return response, metadata + def pre_delete_flow( self, request: flow.DeleteFlowRequest, @@ -204,12 +227,35 @@ def post_export_flow( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_export_flow` interceptor runs + before the `post_export_flow_with_metadata` interceptor. """ return response + def post_export_flow_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_export_flow_with_metadata` + interceptor in new development instead of the `post_export_flow` interceptor. + When both interceptors are used, this `post_export_flow_with_metadata` interceptor runs after the + `post_export_flow` interceptor. The (possibly modified) response returned by + `post_export_flow` will be passed to + `post_export_flow_with_metadata`. + """ + return response, metadata + def pre_get_flow( self, request: flow.GetFlowRequest, @@ -225,12 +271,33 @@ def pre_get_flow( def post_get_flow(self, response: flow.Flow) -> flow.Flow: """Post-rpc interceptor for get_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_get_flow` interceptor runs + before the `post_get_flow_with_metadata` interceptor. """ return response + def post_get_flow_with_metadata( + self, response: flow.Flow, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[flow.Flow, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_get_flow_with_metadata` + interceptor in new development instead of the `post_get_flow` interceptor. + When both interceptors are used, this `post_get_flow_with_metadata` interceptor runs after the + `post_get_flow` interceptor. The (possibly modified) response returned by + `post_get_flow` will be passed to + `post_get_flow_with_metadata`. + """ + return response, metadata + def pre_get_flow_validation_result( self, request: flow.GetFlowValidationResultRequest, @@ -250,12 +317,35 @@ def post_get_flow_validation_result( ) -> flow.FlowValidationResult: """Post-rpc interceptor for get_flow_validation_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_flow_validation_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_get_flow_validation_result` interceptor runs + before the `post_get_flow_validation_result_with_metadata` interceptor. """ return response + def post_get_flow_validation_result_with_metadata( + self, + response: flow.FlowValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[flow.FlowValidationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_flow_validation_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_get_flow_validation_result_with_metadata` + interceptor in new development instead of the `post_get_flow_validation_result` interceptor. + When both interceptors are used, this `post_get_flow_validation_result_with_metadata` interceptor runs after the + `post_get_flow_validation_result` interceptor. The (possibly modified) response returned by + `post_get_flow_validation_result` will be passed to + `post_get_flow_validation_result_with_metadata`. + """ + return response, metadata + def pre_import_flow( self, request: flow.ImportFlowRequest, @@ -273,12 +363,35 @@ def post_import_flow( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_import_flow` interceptor runs + before the `post_import_flow_with_metadata` interceptor. """ return response + def post_import_flow_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_import_flow_with_metadata` + interceptor in new development instead of the `post_import_flow` interceptor. + When both interceptors are used, this `post_import_flow_with_metadata` interceptor runs after the + `post_import_flow` interceptor. The (possibly modified) response returned by + `post_import_flow` will be passed to + `post_import_flow_with_metadata`. + """ + return response, metadata + def pre_list_flows( self, request: flow.ListFlowsRequest, @@ -296,12 +409,35 @@ def post_list_flows( ) -> flow.ListFlowsResponse: """Post-rpc interceptor for list_flows - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_flows_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_list_flows` interceptor runs + before the `post_list_flows_with_metadata` interceptor. """ return response + def post_list_flows_with_metadata( + self, + response: flow.ListFlowsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[flow.ListFlowsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_flows + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_list_flows_with_metadata` + interceptor in new development instead of the `post_list_flows` interceptor. + When both interceptors are used, this `post_list_flows_with_metadata` interceptor runs after the + `post_list_flows` interceptor. The (possibly modified) response returned by + `post_list_flows` will be passed to + `post_list_flows_with_metadata`. + """ + return response, metadata + def pre_train_flow( self, request: flow.TrainFlowRequest, @@ -319,12 +455,35 @@ def post_train_flow( ) -> operations_pb2.Operation: """Post-rpc interceptor for train_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_train_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_train_flow` interceptor runs + before the `post_train_flow_with_metadata` interceptor. """ return response + def post_train_flow_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for train_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_train_flow_with_metadata` + interceptor in new development instead of the `post_train_flow` interceptor. + When both interceptors are used, this `post_train_flow_with_metadata` interceptor runs after the + `post_train_flow` interceptor. The (possibly modified) response returned by + `post_train_flow` will be passed to + `post_train_flow_with_metadata`. + """ + return response, metadata + def pre_update_flow( self, request: gcdc_flow.UpdateFlowRequest, @@ -340,12 +499,35 @@ def pre_update_flow( def post_update_flow(self, response: gcdc_flow.Flow) -> gcdc_flow.Flow: """Post-rpc interceptor for update_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_update_flow` interceptor runs + before the `post_update_flow_with_metadata` interceptor. """ return response + def post_update_flow_with_metadata( + self, + response: gcdc_flow.Flow, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_flow.Flow, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_update_flow_with_metadata` + interceptor in new development instead of the `post_update_flow` interceptor. + When both interceptors are used, this `post_update_flow_with_metadata` interceptor runs after the + `post_update_flow` interceptor. The (possibly modified) response returned by + `post_update_flow` will be passed to + `post_update_flow_with_metadata`. + """ + return response, metadata + def pre_validate_flow( self, request: flow.ValidateFlowRequest, @@ -363,12 +545,35 @@ def post_validate_flow( ) -> flow.FlowValidationResult: """Post-rpc interceptor for validate_flow - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_validate_flow_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Flows server but before - it is returned to user code. + it is returned to user code. This `post_validate_flow` interceptor runs + before the `post_validate_flow_with_metadata` interceptor. """ return response + def post_validate_flow_with_metadata( + self, + response: flow.FlowValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[flow.FlowValidationResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for validate_flow + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Flows server but before it is returned to user code. + + We recommend only using this `post_validate_flow_with_metadata` + interceptor in new development instead of the `post_validate_flow` interceptor. + When both interceptors are used, this `post_validate_flow_with_metadata` interceptor runs after the + `post_validate_flow` interceptor. The (possibly modified) response returned by + `post_validate_flow` will be passed to + `post_validate_flow_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -786,6 +991,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1041,6 +1250,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1203,6 +1416,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1349,6 +1566,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_flow_validation_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_flow_validation_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1497,6 +1718,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1640,6 +1865,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_flows(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_flows_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1788,6 +2017,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_train_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_train_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1958,6 +2191,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2107,6 +2344,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_validate_flow(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_validate_flow_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/generators/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/generators/client.py index 2033765ce34f..bd0b651cb52c 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/generators/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/generators/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -492,6 +494,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1311,16 +1340,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1366,16 +1399,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1476,16 +1513,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1531,16 +1572,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/generators/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/generators/transports/rest.py index 841db9475031..be43aa7b0613 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/generators/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/generators/transports/rest.py @@ -133,12 +133,35 @@ def post_create_generator( ) -> gcdc_generator.Generator: """Post-rpc interceptor for create_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_create_generator` interceptor runs + before the `post_create_generator_with_metadata` interceptor. """ return response + def post_create_generator_with_metadata( + self, + response: gcdc_generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_create_generator_with_metadata` + interceptor in new development instead of the `post_create_generator` interceptor. + When both interceptors are used, this `post_create_generator_with_metadata` interceptor runs after the + `post_create_generator` interceptor. The (possibly modified) response returned by + `post_create_generator` will be passed to + `post_create_generator_with_metadata`. + """ + return response, metadata + def pre_delete_generator( self, request: generator.DeleteGeneratorRequest, @@ -168,12 +191,35 @@ def pre_get_generator( def post_get_generator(self, response: generator.Generator) -> generator.Generator: """Post-rpc interceptor for get_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_get_generator` interceptor runs + before the `post_get_generator_with_metadata` interceptor. """ return response + def post_get_generator_with_metadata( + self, + response: generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_get_generator_with_metadata` + interceptor in new development instead of the `post_get_generator` interceptor. + When both interceptors are used, this `post_get_generator_with_metadata` interceptor runs after the + `post_get_generator` interceptor. The (possibly modified) response returned by + `post_get_generator` will be passed to + `post_get_generator_with_metadata`. + """ + return response, metadata + def pre_list_generators( self, request: generator.ListGeneratorsRequest, @@ -193,12 +239,37 @@ def post_list_generators( ) -> generator.ListGeneratorsResponse: """Post-rpc interceptor for list_generators - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_generators_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_list_generators` interceptor runs + before the `post_list_generators_with_metadata` interceptor. """ return response + def post_list_generators_with_metadata( + self, + response: generator.ListGeneratorsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generator.ListGeneratorsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_generators + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_list_generators_with_metadata` + interceptor in new development instead of the `post_list_generators` interceptor. + When both interceptors are used, this `post_list_generators_with_metadata` interceptor runs after the + `post_list_generators` interceptor. The (possibly modified) response returned by + `post_list_generators` will be passed to + `post_list_generators_with_metadata`. + """ + return response, metadata + def pre_update_generator( self, request: gcdc_generator.UpdateGeneratorRequest, @@ -218,12 +289,35 @@ def post_update_generator( ) -> gcdc_generator.Generator: """Post-rpc interceptor for update_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_update_generator` interceptor runs + before the `post_update_generator_with_metadata` interceptor. """ return response + def post_update_generator_with_metadata( + self, + response: gcdc_generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_update_generator_with_metadata` + interceptor in new development instead of the `post_update_generator` interceptor. + When both interceptors are used, this `post_update_generator_with_metadata` interceptor runs after the + `post_update_generator` interceptor. The (possibly modified) response returned by + `post_update_generator` will be passed to + `post_update_generator_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -567,6 +661,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -827,6 +925,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -972,6 +1074,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_generators(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_generators_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1129,6 +1235,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER 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 a71a83d0ebff..08d8c3c519c9 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 @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -517,6 +519,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1568,16 +1597,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1623,16 +1656,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1733,16 +1770,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1788,16 +1829,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( 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 c66b49cee17c..93d4796e4443 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 @@ -147,12 +147,35 @@ def pre_create_intent( def post_create_intent(self, response: gcdc_intent.Intent) -> gcdc_intent.Intent: """Post-rpc interceptor for create_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_create_intent` interceptor runs + before the `post_create_intent_with_metadata` interceptor. """ return response + def post_create_intent_with_metadata( + self, + response: gcdc_intent.Intent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_create_intent_with_metadata` + interceptor in new development instead of the `post_create_intent` interceptor. + When both interceptors are used, this `post_create_intent_with_metadata` interceptor runs after the + `post_create_intent` interceptor. The (possibly modified) response returned by + `post_create_intent` will be passed to + `post_create_intent_with_metadata`. + """ + return response, metadata + def pre_delete_intent( self, request: intent.DeleteIntentRequest, @@ -182,12 +205,35 @@ def post_export_intents( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_export_intents` interceptor runs + before the `post_export_intents_with_metadata` interceptor. """ return response + def post_export_intents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_export_intents_with_metadata` + interceptor in new development instead of the `post_export_intents` interceptor. + When both interceptors are used, this `post_export_intents_with_metadata` interceptor runs after the + `post_export_intents` interceptor. The (possibly modified) response returned by + `post_export_intents` will be passed to + `post_export_intents_with_metadata`. + """ + return response, metadata + def pre_get_intent( self, request: intent.GetIntentRequest, @@ -203,12 +249,33 @@ def pre_get_intent( def post_get_intent(self, response: intent.Intent) -> intent.Intent: """Post-rpc interceptor for get_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_get_intent` interceptor runs + before the `post_get_intent_with_metadata` interceptor. """ return response + def post_get_intent_with_metadata( + self, response: intent.Intent, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_get_intent_with_metadata` + interceptor in new development instead of the `post_get_intent` interceptor. + When both interceptors are used, this `post_get_intent_with_metadata` interceptor runs after the + `post_get_intent` interceptor. The (possibly modified) response returned by + `post_get_intent` will be passed to + `post_get_intent_with_metadata`. + """ + return response, metadata + def pre_import_intents( self, request: intent.ImportIntentsRequest, @@ -226,12 +293,35 @@ def post_import_intents( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_import_intents` interceptor runs + before the `post_import_intents_with_metadata` interceptor. """ return response + def post_import_intents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_import_intents_with_metadata` + interceptor in new development instead of the `post_import_intents` interceptor. + When both interceptors are used, this `post_import_intents_with_metadata` interceptor runs after the + `post_import_intents` interceptor. The (possibly modified) response returned by + `post_import_intents` will be passed to + `post_import_intents_with_metadata`. + """ + return response, metadata + def pre_list_intents( self, request: intent.ListIntentsRequest, @@ -249,12 +339,35 @@ def post_list_intents( ) -> intent.ListIntentsResponse: """Post-rpc interceptor for list_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_list_intents` interceptor runs + before the `post_list_intents_with_metadata` interceptor. """ return response + def post_list_intents_with_metadata( + self, + response: intent.ListIntentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[intent.ListIntentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_list_intents_with_metadata` + interceptor in new development instead of the `post_list_intents` interceptor. + When both interceptors are used, this `post_list_intents_with_metadata` interceptor runs after the + `post_list_intents` interceptor. The (possibly modified) response returned by + `post_list_intents` will be passed to + `post_list_intents_with_metadata`. + """ + return response, metadata + def pre_update_intent( self, request: gcdc_intent.UpdateIntentRequest, @@ -272,12 +385,35 @@ def pre_update_intent( def post_update_intent(self, response: gcdc_intent.Intent) -> gcdc_intent.Intent: """Post-rpc interceptor for update_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_update_intent` interceptor runs + before the `post_update_intent_with_metadata` interceptor. """ return response + def post_update_intent_with_metadata( + self, + response: gcdc_intent.Intent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_update_intent_with_metadata` + interceptor in new development instead of the `post_update_intent` interceptor. + When both interceptors are used, this `post_update_intent_with_metadata` interceptor runs after the + `post_update_intent` interceptor. The (possibly modified) response returned by + `post_update_intent` will be passed to + `post_update_intent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -681,6 +817,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -940,6 +1080,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1088,6 +1232,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1238,6 +1386,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1383,6 +1535,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1539,6 +1695,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER 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 f0a0cbf6d0a9..a7c637871584 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 @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -664,6 +666,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1528,16 +1557,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1583,16 +1616,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1693,16 +1730,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1748,16 +1789,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/transports/rest.py index e52b8632a0d0..e4b3e363d057 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/pages/transports/rest.py @@ -129,12 +129,35 @@ def pre_create_page( def post_create_page(self, response: gcdc_page.Page) -> gcdc_page.Page: """Post-rpc interceptor for create_page - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_page_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Pages server but before - it is returned to user code. + it is returned to user code. This `post_create_page` interceptor runs + before the `post_create_page_with_metadata` interceptor. """ return response + def post_create_page_with_metadata( + self, + response: gcdc_page.Page, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_page.Page, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_page + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Pages server but before it is returned to user code. + + We recommend only using this `post_create_page_with_metadata` + interceptor in new development instead of the `post_create_page` interceptor. + When both interceptors are used, this `post_create_page_with_metadata` interceptor runs after the + `post_create_page` interceptor. The (possibly modified) response returned by + `post_create_page` will be passed to + `post_create_page_with_metadata`. + """ + return response, metadata + def pre_delete_page( self, request: page.DeletePageRequest, @@ -162,12 +185,33 @@ def pre_get_page( def post_get_page(self, response: page.Page) -> page.Page: """Post-rpc interceptor for get_page - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_page_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Pages server but before - it is returned to user code. + it is returned to user code. This `post_get_page` interceptor runs + before the `post_get_page_with_metadata` interceptor. """ return response + def post_get_page_with_metadata( + self, response: page.Page, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[page.Page, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_page + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Pages server but before it is returned to user code. + + We recommend only using this `post_get_page_with_metadata` + interceptor in new development instead of the `post_get_page` interceptor. + When both interceptors are used, this `post_get_page_with_metadata` interceptor runs after the + `post_get_page` interceptor. The (possibly modified) response returned by + `post_get_page` will be passed to + `post_get_page_with_metadata`. + """ + return response, metadata + def pre_list_pages( self, request: page.ListPagesRequest, @@ -185,12 +229,35 @@ def post_list_pages( ) -> page.ListPagesResponse: """Post-rpc interceptor for list_pages - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_pages_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Pages server but before - it is returned to user code. + it is returned to user code. This `post_list_pages` interceptor runs + before the `post_list_pages_with_metadata` interceptor. """ return response + def post_list_pages_with_metadata( + self, + response: page.ListPagesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[page.ListPagesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_pages + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Pages server but before it is returned to user code. + + We recommend only using this `post_list_pages_with_metadata` + interceptor in new development instead of the `post_list_pages` interceptor. + When both interceptors are used, this `post_list_pages_with_metadata` interceptor runs after the + `post_list_pages` interceptor. The (possibly modified) response returned by + `post_list_pages` will be passed to + `post_list_pages_with_metadata`. + """ + return response, metadata + def pre_update_page( self, request: gcdc_page.UpdatePageRequest, @@ -206,12 +273,35 @@ def pre_update_page( def post_update_page(self, response: gcdc_page.Page) -> gcdc_page.Page: """Post-rpc interceptor for update_page - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_page_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Pages server but before - it is returned to user code. + it is returned to user code. This `post_update_page` interceptor runs + before the `post_update_page_with_metadata` interceptor. """ return response + def post_update_page_with_metadata( + self, + response: gcdc_page.Page, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_page.Page, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_page + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Pages server but before it is returned to user code. + + We recommend only using this `post_update_page_with_metadata` + interceptor in new development instead of the `post_update_page` interceptor. + When both interceptors are used, this `post_update_page_with_metadata` interceptor runs after the + `post_update_page` interceptor. The (possibly modified) response returned by + `post_update_page` will be passed to + `post_update_page_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -568,6 +658,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_page(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_page_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -835,6 +929,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_page(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_page_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -978,6 +1076,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_pages(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_pages_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1146,6 +1248,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_page(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_page_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/playbooks/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/playbooks/client.py index 07d17c024723..1cd6432e6195 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/playbooks/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/playbooks/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -597,6 +599,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1870,16 +1899,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1925,16 +1958,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2035,16 +2072,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2090,16 +2131,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/playbooks/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/playbooks/transports/rest.py index c203b24c61d9..2a92868855f9 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/playbooks/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/playbooks/transports/rest.py @@ -161,12 +161,35 @@ def post_create_playbook( ) -> gcdc_playbook.Playbook: """Post-rpc interceptor for create_playbook - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_playbook_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Playbooks server but before - it is returned to user code. + it is returned to user code. This `post_create_playbook` interceptor runs + before the `post_create_playbook_with_metadata` interceptor. """ return response + def post_create_playbook_with_metadata( + self, + response: gcdc_playbook.Playbook, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_playbook.Playbook, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_playbook + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Playbooks server but before it is returned to user code. + + We recommend only using this `post_create_playbook_with_metadata` + interceptor in new development instead of the `post_create_playbook` interceptor. + When both interceptors are used, this `post_create_playbook_with_metadata` interceptor runs after the + `post_create_playbook` interceptor. The (possibly modified) response returned by + `post_create_playbook` will be passed to + `post_create_playbook_with_metadata`. + """ + return response, metadata + def pre_create_playbook_version( self, request: playbook.CreatePlaybookVersionRequest, @@ -186,12 +209,35 @@ def post_create_playbook_version( ) -> playbook.PlaybookVersion: """Post-rpc interceptor for create_playbook_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_playbook_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Playbooks server but before - it is returned to user code. + it is returned to user code. This `post_create_playbook_version` interceptor runs + before the `post_create_playbook_version_with_metadata` interceptor. """ return response + def post_create_playbook_version_with_metadata( + self, + response: playbook.PlaybookVersion, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[playbook.PlaybookVersion, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_playbook_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Playbooks server but before it is returned to user code. + + We recommend only using this `post_create_playbook_version_with_metadata` + interceptor in new development instead of the `post_create_playbook_version` interceptor. + When both interceptors are used, this `post_create_playbook_version_with_metadata` interceptor runs after the + `post_create_playbook_version` interceptor. The (possibly modified) response returned by + `post_create_playbook_version` will be passed to + `post_create_playbook_version_with_metadata`. + """ + return response, metadata + def pre_delete_playbook( self, request: playbook.DeletePlaybookRequest, @@ -233,12 +279,35 @@ def pre_get_playbook( def post_get_playbook(self, response: playbook.Playbook) -> playbook.Playbook: """Post-rpc interceptor for get_playbook - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_playbook_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Playbooks server but before - it is returned to user code. + it is returned to user code. This `post_get_playbook` interceptor runs + before the `post_get_playbook_with_metadata` interceptor. """ return response + def post_get_playbook_with_metadata( + self, + response: playbook.Playbook, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[playbook.Playbook, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_playbook + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Playbooks server but before it is returned to user code. + + We recommend only using this `post_get_playbook_with_metadata` + interceptor in new development instead of the `post_get_playbook` interceptor. + When both interceptors are used, this `post_get_playbook_with_metadata` interceptor runs after the + `post_get_playbook` interceptor. The (possibly modified) response returned by + `post_get_playbook` will be passed to + `post_get_playbook_with_metadata`. + """ + return response, metadata + def pre_get_playbook_version( self, request: playbook.GetPlaybookVersionRequest, @@ -258,12 +327,35 @@ def post_get_playbook_version( ) -> playbook.PlaybookVersion: """Post-rpc interceptor for get_playbook_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_playbook_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Playbooks server but before - it is returned to user code. + it is returned to user code. This `post_get_playbook_version` interceptor runs + before the `post_get_playbook_version_with_metadata` interceptor. """ return response + def post_get_playbook_version_with_metadata( + self, + response: playbook.PlaybookVersion, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[playbook.PlaybookVersion, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_playbook_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Playbooks server but before it is returned to user code. + + We recommend only using this `post_get_playbook_version_with_metadata` + interceptor in new development instead of the `post_get_playbook_version` interceptor. + When both interceptors are used, this `post_get_playbook_version_with_metadata` interceptor runs after the + `post_get_playbook_version` interceptor. The (possibly modified) response returned by + `post_get_playbook_version` will be passed to + `post_get_playbook_version_with_metadata`. + """ + return response, metadata + def pre_list_playbooks( self, request: playbook.ListPlaybooksRequest, @@ -281,12 +373,35 @@ def post_list_playbooks( ) -> playbook.ListPlaybooksResponse: """Post-rpc interceptor for list_playbooks - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_playbooks_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Playbooks server but before - it is returned to user code. + it is returned to user code. This `post_list_playbooks` interceptor runs + before the `post_list_playbooks_with_metadata` interceptor. """ return response + def post_list_playbooks_with_metadata( + self, + response: playbook.ListPlaybooksResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[playbook.ListPlaybooksResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_playbooks + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Playbooks server but before it is returned to user code. + + We recommend only using this `post_list_playbooks_with_metadata` + interceptor in new development instead of the `post_list_playbooks` interceptor. + When both interceptors are used, this `post_list_playbooks_with_metadata` interceptor runs after the + `post_list_playbooks` interceptor. The (possibly modified) response returned by + `post_list_playbooks` will be passed to + `post_list_playbooks_with_metadata`. + """ + return response, metadata + def pre_list_playbook_versions( self, request: playbook.ListPlaybookVersionsRequest, @@ -306,12 +421,37 @@ def post_list_playbook_versions( ) -> playbook.ListPlaybookVersionsResponse: """Post-rpc interceptor for list_playbook_versions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_playbook_versions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Playbooks server but before - it is returned to user code. + it is returned to user code. This `post_list_playbook_versions` interceptor runs + before the `post_list_playbook_versions_with_metadata` interceptor. """ return response + def post_list_playbook_versions_with_metadata( + self, + response: playbook.ListPlaybookVersionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + playbook.ListPlaybookVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_playbook_versions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Playbooks server but before it is returned to user code. + + We recommend only using this `post_list_playbook_versions_with_metadata` + interceptor in new development instead of the `post_list_playbook_versions` interceptor. + When both interceptors are used, this `post_list_playbook_versions_with_metadata` interceptor runs after the + `post_list_playbook_versions` interceptor. The (possibly modified) response returned by + `post_list_playbook_versions` will be passed to + `post_list_playbook_versions_with_metadata`. + """ + return response, metadata + def pre_update_playbook( self, request: gcdc_playbook.UpdatePlaybookRequest, @@ -331,12 +471,35 @@ def post_update_playbook( ) -> gcdc_playbook.Playbook: """Post-rpc interceptor for update_playbook - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_playbook_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Playbooks server but before - it is returned to user code. + it is returned to user code. This `post_update_playbook` interceptor runs + before the `post_update_playbook_with_metadata` interceptor. """ return response + def post_update_playbook_with_metadata( + self, + response: gcdc_playbook.Playbook, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_playbook.Playbook, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_playbook + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Playbooks server but before it is returned to user code. + + We recommend only using this `post_update_playbook_with_metadata` + interceptor in new development instead of the `post_update_playbook` interceptor. + When both interceptors are used, this `post_update_playbook_with_metadata` interceptor runs after the + `post_update_playbook` interceptor. The (possibly modified) response returned by + `post_update_playbook` will be passed to + `post_update_playbook_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -691,6 +854,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_playbook(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_playbook_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -842,6 +1009,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_playbook_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_playbook_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1218,6 +1389,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_playbook(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_playbook_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1363,6 +1538,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_playbook_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_playbook_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1510,6 +1689,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_playbooks(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_playbooks_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1655,6 +1838,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_playbook_versions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_playbook_versions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1823,6 +2010,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_playbook(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_playbook_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/security_settings_service/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/security_settings_service/client.py index 292c4492164c..d3f4fe1adc9d 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/security_settings_service/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/security_settings_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -537,6 +539,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1393,16 +1422,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1448,16 +1481,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1558,16 +1595,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1613,16 +1654,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/security_settings_service/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/security_settings_service/transports/rest.py index 9f2405bf8779..e3eb9875d8ad 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/security_settings_service/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/security_settings_service/transports/rest.py @@ -136,12 +136,37 @@ def post_create_security_settings( ) -> gcdc_security_settings.SecuritySettings: """Post-rpc interceptor for create_security_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_security_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SecuritySettingsService server but before - it is returned to user code. + it is returned to user code. This `post_create_security_settings` interceptor runs + before the `post_create_security_settings_with_metadata` interceptor. """ return response + def post_create_security_settings_with_metadata( + self, + response: gcdc_security_settings.SecuritySettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_security_settings.SecuritySettings, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_security_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SecuritySettingsService server but before it is returned to user code. + + We recommend only using this `post_create_security_settings_with_metadata` + interceptor in new development instead of the `post_create_security_settings` interceptor. + When both interceptors are used, this `post_create_security_settings_with_metadata` interceptor runs after the + `post_create_security_settings` interceptor. The (possibly modified) response returned by + `post_create_security_settings` will be passed to + `post_create_security_settings_with_metadata`. + """ + return response, metadata + def pre_delete_security_settings( self, request: security_settings.DeleteSecuritySettingsRequest, @@ -177,12 +202,37 @@ def post_get_security_settings( ) -> security_settings.SecuritySettings: """Post-rpc interceptor for get_security_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_security_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SecuritySettingsService server but before - it is returned to user code. + it is returned to user code. This `post_get_security_settings` interceptor runs + before the `post_get_security_settings_with_metadata` interceptor. """ return response + def post_get_security_settings_with_metadata( + self, + response: security_settings.SecuritySettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + security_settings.SecuritySettings, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_security_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SecuritySettingsService server but before it is returned to user code. + + We recommend only using this `post_get_security_settings_with_metadata` + interceptor in new development instead of the `post_get_security_settings` interceptor. + When both interceptors are used, this `post_get_security_settings_with_metadata` interceptor runs after the + `post_get_security_settings` interceptor. The (possibly modified) response returned by + `post_get_security_settings` will be passed to + `post_get_security_settings_with_metadata`. + """ + return response, metadata + def pre_list_security_settings( self, request: security_settings.ListSecuritySettingsRequest, @@ -203,12 +253,38 @@ def post_list_security_settings( ) -> security_settings.ListSecuritySettingsResponse: """Post-rpc interceptor for list_security_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_security_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SecuritySettingsService server but before - it is returned to user code. + it is returned to user code. This `post_list_security_settings` interceptor runs + before the `post_list_security_settings_with_metadata` interceptor. """ return response + def post_list_security_settings_with_metadata( + self, + response: security_settings.ListSecuritySettingsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + security_settings.ListSecuritySettingsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_security_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SecuritySettingsService server but before it is returned to user code. + + We recommend only using this `post_list_security_settings_with_metadata` + interceptor in new development instead of the `post_list_security_settings` interceptor. + When both interceptors are used, this `post_list_security_settings_with_metadata` interceptor runs after the + `post_list_security_settings` interceptor. The (possibly modified) response returned by + `post_list_security_settings` will be passed to + `post_list_security_settings_with_metadata`. + """ + return response, metadata + def pre_update_security_settings( self, request: gcdc_security_settings.UpdateSecuritySettingsRequest, @@ -229,12 +305,37 @@ def post_update_security_settings( ) -> gcdc_security_settings.SecuritySettings: """Post-rpc interceptor for update_security_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_security_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SecuritySettingsService server but before - it is returned to user code. + it is returned to user code. This `post_update_security_settings` interceptor runs + before the `post_update_security_settings_with_metadata` interceptor. """ return response + def post_update_security_settings_with_metadata( + self, + response: gcdc_security_settings.SecuritySettings, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_security_settings.SecuritySettings, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_security_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SecuritySettingsService server but before it is returned to user code. + + We recommend only using this `post_update_security_settings_with_metadata` + interceptor in new development instead of the `post_update_security_settings` interceptor. + When both interceptors are used, this `post_update_security_settings_with_metadata` interceptor runs after the + `post_update_security_settings` interceptor. The (possibly modified) response returned by + `post_update_security_settings` will be passed to + `post_update_security_settings_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -578,6 +679,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_security_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_security_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -842,6 +947,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_security_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_security_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -990,6 +1099,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_security_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_security_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1148,6 +1261,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_security_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_security_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/session_entity_types/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/session_entity_types/client.py index e3ad26395795..3d196540ff9f 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/session_entity_types/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/session_entity_types/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -498,6 +500,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1414,16 +1443,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1469,16 +1502,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1579,16 +1616,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1634,16 +1675,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/session_entity_types/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/session_entity_types/transports/rest.py index 5b317a4ef4eb..550b6f313f19 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/session_entity_types/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/session_entity_types/transports/rest.py @@ -136,12 +136,38 @@ def post_create_session_entity_type( ) -> gcdc_session_entity_type.SessionEntityType: """Post-rpc interceptor for create_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_create_session_entity_type` interceptor runs + before the `post_create_session_entity_type_with_metadata` interceptor. """ return response + def post_create_session_entity_type_with_metadata( + self, + response: gcdc_session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_session_entity_type.SessionEntityType, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for create_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_create_session_entity_type_with_metadata` + interceptor in new development instead of the `post_create_session_entity_type` interceptor. + When both interceptors are used, this `post_create_session_entity_type_with_metadata` interceptor runs after the + `post_create_session_entity_type` interceptor. The (possibly modified) response returned by + `post_create_session_entity_type` will be passed to + `post_create_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_delete_session_entity_type( self, request: session_entity_type.DeleteSessionEntityTypeRequest, @@ -177,12 +203,37 @@ def post_get_session_entity_type( ) -> session_entity_type.SessionEntityType: """Post-rpc interceptor for get_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_get_session_entity_type` interceptor runs + before the `post_get_session_entity_type_with_metadata` interceptor. """ return response + def post_get_session_entity_type_with_metadata( + self, + response: session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_entity_type.SessionEntityType, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_get_session_entity_type_with_metadata` + interceptor in new development instead of the `post_get_session_entity_type` interceptor. + When both interceptors are used, this `post_get_session_entity_type_with_metadata` interceptor runs after the + `post_get_session_entity_type` interceptor. The (possibly modified) response returned by + `post_get_session_entity_type` will be passed to + `post_get_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_list_session_entity_types( self, request: session_entity_type.ListSessionEntityTypesRequest, @@ -203,12 +254,38 @@ def post_list_session_entity_types( ) -> session_entity_type.ListSessionEntityTypesResponse: """Post-rpc interceptor for list_session_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_session_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_list_session_entity_types` interceptor runs + before the `post_list_session_entity_types_with_metadata` interceptor. """ return response + def post_list_session_entity_types_with_metadata( + self, + response: session_entity_type.ListSessionEntityTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_entity_type.ListSessionEntityTypesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_session_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_list_session_entity_types_with_metadata` + interceptor in new development instead of the `post_list_session_entity_types` interceptor. + When both interceptors are used, this `post_list_session_entity_types_with_metadata` interceptor runs after the + `post_list_session_entity_types` interceptor. The (possibly modified) response returned by + `post_list_session_entity_types` will be passed to + `post_list_session_entity_types_with_metadata`. + """ + return response, metadata + def pre_update_session_entity_type( self, request: gcdc_session_entity_type.UpdateSessionEntityTypeRequest, @@ -229,12 +306,38 @@ def post_update_session_entity_type( ) -> gcdc_session_entity_type.SessionEntityType: """Post-rpc interceptor for update_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_update_session_entity_type` interceptor runs + before the `post_update_session_entity_type_with_metadata` interceptor. """ return response + def post_update_session_entity_type_with_metadata( + self, + response: gcdc_session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_session_entity_type.SessionEntityType, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_update_session_entity_type_with_metadata` + interceptor in new development instead of the `post_update_session_entity_type` interceptor. + When both interceptors are used, this `post_update_session_entity_type_with_metadata` interceptor runs after the + `post_update_session_entity_type` interceptor. The (possibly modified) response returned by + `post_update_session_entity_type` will be passed to + `post_update_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -593,6 +696,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -871,6 +978,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1021,6 +1132,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_session_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_session_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1195,6 +1310,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/sessions/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/sessions/client.py index f265c3e505f1..e7fc88e4e825 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/sessions/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/sessions/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -788,6 +790,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1655,16 +1684,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1710,16 +1743,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1820,16 +1857,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1875,16 +1916,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/sessions/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/sessions/transports/rest.py index 73c2f451354c..f5e500ab5628 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/sessions/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/sessions/transports/rest.py @@ -133,12 +133,35 @@ def post_detect_intent( ) -> session.DetectIntentResponse: """Post-rpc interceptor for detect_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_detect_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_detect_intent` interceptor runs + before the `post_detect_intent_with_metadata` interceptor. """ return response + def post_detect_intent_with_metadata( + self, + response: session.DetectIntentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.DetectIntentResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for detect_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_detect_intent_with_metadata` + interceptor in new development instead of the `post_detect_intent` interceptor. + When both interceptors are used, this `post_detect_intent_with_metadata` interceptor runs after the + `post_detect_intent` interceptor. The (possibly modified) response returned by + `post_detect_intent` will be passed to + `post_detect_intent_with_metadata`. + """ + return response, metadata + def pre_fulfill_intent( self, request: session.FulfillIntentRequest, @@ -156,12 +179,35 @@ def post_fulfill_intent( ) -> session.FulfillIntentResponse: """Post-rpc interceptor for fulfill_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fulfill_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_fulfill_intent` interceptor runs + before the `post_fulfill_intent_with_metadata` interceptor. """ return response + def post_fulfill_intent_with_metadata( + self, + response: session.FulfillIntentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.FulfillIntentResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for fulfill_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_fulfill_intent_with_metadata` + interceptor in new development instead of the `post_fulfill_intent` interceptor. + When both interceptors are used, this `post_fulfill_intent_with_metadata` interceptor runs after the + `post_fulfill_intent` interceptor. The (possibly modified) response returned by + `post_fulfill_intent` will be passed to + `post_fulfill_intent_with_metadata`. + """ + return response, metadata + def pre_match_intent( self, request: session.MatchIntentRequest, @@ -179,12 +225,35 @@ def post_match_intent( ) -> session.MatchIntentResponse: """Post-rpc interceptor for match_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_match_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_match_intent` interceptor runs + before the `post_match_intent_with_metadata` interceptor. """ return response + def post_match_intent_with_metadata( + self, + response: session.MatchIntentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.MatchIntentResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for match_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_match_intent_with_metadata` + interceptor in new development instead of the `post_match_intent` interceptor. + When both interceptors are used, this `post_match_intent_with_metadata` interceptor runs after the + `post_match_intent` interceptor. The (possibly modified) response returned by + `post_match_intent` will be passed to + `post_match_intent_with_metadata`. + """ + return response, metadata + def pre_server_streaming_detect_intent( self, request: session.DetectIntentRequest, @@ -202,12 +271,37 @@ def post_server_streaming_detect_intent( ) -> rest_streaming.ResponseIterator: """Post-rpc interceptor for server_streaming_detect_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_server_streaming_detect_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_server_streaming_detect_intent` interceptor runs + before the `post_server_streaming_detect_intent_with_metadata` interceptor. """ return response + def post_server_streaming_detect_intent_with_metadata( + self, + response: rest_streaming.ResponseIterator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + rest_streaming.ResponseIterator, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for server_streaming_detect_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_server_streaming_detect_intent_with_metadata` + interceptor in new development instead of the `post_server_streaming_detect_intent` interceptor. + When both interceptors are used, this `post_server_streaming_detect_intent_with_metadata` interceptor runs after the + `post_server_streaming_detect_intent` interceptor. The (possibly modified) response returned by + `post_server_streaming_detect_intent` will be passed to + `post_server_streaming_detect_intent_with_metadata`. + """ + return response, metadata + def pre_submit_answer_feedback( self, request: session.SubmitAnswerFeedbackRequest, @@ -227,12 +321,35 @@ def post_submit_answer_feedback( ) -> session.AnswerFeedback: """Post-rpc interceptor for submit_answer_feedback - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_submit_answer_feedback_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_submit_answer_feedback` interceptor runs + before the `post_submit_answer_feedback_with_metadata` interceptor. """ return response + def post_submit_answer_feedback_with_metadata( + self, + response: session.AnswerFeedback, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.AnswerFeedback, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for submit_answer_feedback + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_submit_answer_feedback_with_metadata` + interceptor in new development instead of the `post_submit_answer_feedback` interceptor. + When both interceptors are used, this `post_submit_answer_feedback_with_metadata` interceptor runs after the + `post_submit_answer_feedback` interceptor. The (possibly modified) response returned by + `post_submit_answer_feedback` will be passed to + `post_submit_answer_feedback_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -573,6 +690,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_detect_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_detect_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -723,6 +844,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fulfill_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fulfill_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -871,6 +996,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_match_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_match_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1022,6 +1151,13 @@ def __call__( ) resp = self._interceptor.post_server_streaming_detect_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_server_streaming_detect_intent_with_metadata( + resp, response_metadata + ) return resp class _StreamingDetectIntent( @@ -1170,6 +1306,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_submit_answer_feedback(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_submit_answer_feedback_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/test_cases/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/test_cases/client.py index c4b9bba7e1ae..e33f2b9fedf0 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/test_cases/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/test_cases/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -763,6 +765,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2319,16 +2348,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2374,16 +2407,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2484,16 +2521,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2539,16 +2580,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/test_cases/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/test_cases/transports/rest.py index 72a125fe1b36..c8035d1f89bc 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/test_cases/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/test_cases/transports/rest.py @@ -203,12 +203,35 @@ def post_batch_run_test_cases( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_run_test_cases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_run_test_cases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_batch_run_test_cases` interceptor runs + before the `post_batch_run_test_cases_with_metadata` interceptor. """ return response + def post_batch_run_test_cases_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_run_test_cases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_batch_run_test_cases_with_metadata` + interceptor in new development instead of the `post_batch_run_test_cases` interceptor. + When both interceptors are used, this `post_batch_run_test_cases_with_metadata` interceptor runs after the + `post_batch_run_test_cases` interceptor. The (possibly modified) response returned by + `post_batch_run_test_cases` will be passed to + `post_batch_run_test_cases_with_metadata`. + """ + return response, metadata + def pre_calculate_coverage( self, request: test_case.CalculateCoverageRequest, @@ -228,12 +251,37 @@ def post_calculate_coverage( ) -> test_case.CalculateCoverageResponse: """Post-rpc interceptor for calculate_coverage - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_calculate_coverage_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_calculate_coverage` interceptor runs + before the `post_calculate_coverage_with_metadata` interceptor. """ return response + def post_calculate_coverage_with_metadata( + self, + response: test_case.CalculateCoverageResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + test_case.CalculateCoverageResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for calculate_coverage + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_calculate_coverage_with_metadata` + interceptor in new development instead of the `post_calculate_coverage` interceptor. + When both interceptors are used, this `post_calculate_coverage_with_metadata` interceptor runs after the + `post_calculate_coverage` interceptor. The (possibly modified) response returned by + `post_calculate_coverage` will be passed to + `post_calculate_coverage_with_metadata`. + """ + return response, metadata + def pre_create_test_case( self, request: gcdc_test_case.CreateTestCaseRequest, @@ -253,12 +301,35 @@ def post_create_test_case( ) -> gcdc_test_case.TestCase: """Post-rpc interceptor for create_test_case - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_test_case_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_create_test_case` interceptor runs + before the `post_create_test_case_with_metadata` interceptor. """ return response + def post_create_test_case_with_metadata( + self, + response: gcdc_test_case.TestCase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_test_case.TestCase, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_test_case + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_create_test_case_with_metadata` + interceptor in new development instead of the `post_create_test_case` interceptor. + When both interceptors are used, this `post_create_test_case_with_metadata` interceptor runs after the + `post_create_test_case` interceptor. The (possibly modified) response returned by + `post_create_test_case` will be passed to + `post_create_test_case_with_metadata`. + """ + return response, metadata + def pre_export_test_cases( self, request: test_case.ExportTestCasesRequest, @@ -278,12 +349,35 @@ def post_export_test_cases( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_test_cases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_test_cases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_export_test_cases` interceptor runs + before the `post_export_test_cases_with_metadata` interceptor. """ return response + def post_export_test_cases_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_test_cases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_export_test_cases_with_metadata` + interceptor in new development instead of the `post_export_test_cases` interceptor. + When both interceptors are used, this `post_export_test_cases_with_metadata` interceptor runs after the + `post_export_test_cases` interceptor. The (possibly modified) response returned by + `post_export_test_cases` will be passed to + `post_export_test_cases_with_metadata`. + """ + return response, metadata + def pre_get_test_case( self, request: test_case.GetTestCaseRequest, @@ -299,12 +393,35 @@ def pre_get_test_case( def post_get_test_case(self, response: test_case.TestCase) -> test_case.TestCase: """Post-rpc interceptor for get_test_case - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_test_case_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_get_test_case` interceptor runs + before the `post_get_test_case_with_metadata` interceptor. """ return response + def post_get_test_case_with_metadata( + self, + response: test_case.TestCase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[test_case.TestCase, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_test_case + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_get_test_case_with_metadata` + interceptor in new development instead of the `post_get_test_case` interceptor. + When both interceptors are used, this `post_get_test_case_with_metadata` interceptor runs after the + `post_get_test_case` interceptor. The (possibly modified) response returned by + `post_get_test_case` will be passed to + `post_get_test_case_with_metadata`. + """ + return response, metadata + def pre_get_test_case_result( self, request: test_case.GetTestCaseResultRequest, @@ -324,12 +441,35 @@ def post_get_test_case_result( ) -> test_case.TestCaseResult: """Post-rpc interceptor for get_test_case_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_test_case_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_get_test_case_result` interceptor runs + before the `post_get_test_case_result_with_metadata` interceptor. """ return response + def post_get_test_case_result_with_metadata( + self, + response: test_case.TestCaseResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[test_case.TestCaseResult, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_test_case_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_get_test_case_result_with_metadata` + interceptor in new development instead of the `post_get_test_case_result` interceptor. + When both interceptors are used, this `post_get_test_case_result_with_metadata` interceptor runs after the + `post_get_test_case_result` interceptor. The (possibly modified) response returned by + `post_get_test_case_result` will be passed to + `post_get_test_case_result_with_metadata`. + """ + return response, metadata + def pre_import_test_cases( self, request: test_case.ImportTestCasesRequest, @@ -349,12 +489,35 @@ def post_import_test_cases( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_test_cases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_test_cases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_import_test_cases` interceptor runs + before the `post_import_test_cases_with_metadata` interceptor. """ return response + def post_import_test_cases_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_test_cases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_import_test_cases_with_metadata` + interceptor in new development instead of the `post_import_test_cases` interceptor. + When both interceptors are used, this `post_import_test_cases_with_metadata` interceptor runs after the + `post_import_test_cases` interceptor. The (possibly modified) response returned by + `post_import_test_cases` will be passed to + `post_import_test_cases_with_metadata`. + """ + return response, metadata + def pre_list_test_case_results( self, request: test_case.ListTestCaseResultsRequest, @@ -374,12 +537,37 @@ def post_list_test_case_results( ) -> test_case.ListTestCaseResultsResponse: """Post-rpc interceptor for list_test_case_results - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_test_case_results_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_list_test_case_results` interceptor runs + before the `post_list_test_case_results_with_metadata` interceptor. """ return response + def post_list_test_case_results_with_metadata( + self, + response: test_case.ListTestCaseResultsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + test_case.ListTestCaseResultsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_test_case_results + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_list_test_case_results_with_metadata` + interceptor in new development instead of the `post_list_test_case_results` interceptor. + When both interceptors are used, this `post_list_test_case_results_with_metadata` interceptor runs after the + `post_list_test_case_results` interceptor. The (possibly modified) response returned by + `post_list_test_case_results` will be passed to + `post_list_test_case_results_with_metadata`. + """ + return response, metadata + def pre_list_test_cases( self, request: test_case.ListTestCasesRequest, @@ -397,12 +585,37 @@ def post_list_test_cases( ) -> test_case.ListTestCasesResponse: """Post-rpc interceptor for list_test_cases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_test_cases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_list_test_cases` interceptor runs + before the `post_list_test_cases_with_metadata` interceptor. """ return response + def post_list_test_cases_with_metadata( + self, + response: test_case.ListTestCasesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + test_case.ListTestCasesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_test_cases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_list_test_cases_with_metadata` + interceptor in new development instead of the `post_list_test_cases` interceptor. + When both interceptors are used, this `post_list_test_cases_with_metadata` interceptor runs after the + `post_list_test_cases` interceptor. The (possibly modified) response returned by + `post_list_test_cases` will be passed to + `post_list_test_cases_with_metadata`. + """ + return response, metadata + def pre_run_test_case( self, request: test_case.RunTestCaseRequest, @@ -420,12 +633,35 @@ def post_run_test_case( ) -> operations_pb2.Operation: """Post-rpc interceptor for run_test_case - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_run_test_case_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_run_test_case` interceptor runs + before the `post_run_test_case_with_metadata` interceptor. """ return response + def post_run_test_case_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for run_test_case + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_run_test_case_with_metadata` + interceptor in new development instead of the `post_run_test_case` interceptor. + When both interceptors are used, this `post_run_test_case_with_metadata` interceptor runs after the + `post_run_test_case` interceptor. The (possibly modified) response returned by + `post_run_test_case` will be passed to + `post_run_test_case_with_metadata`. + """ + return response, metadata + def pre_update_test_case( self, request: gcdc_test_case.UpdateTestCaseRequest, @@ -445,12 +681,35 @@ def post_update_test_case( ) -> gcdc_test_case.TestCase: """Post-rpc interceptor for update_test_case - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_test_case_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TestCases server but before - it is returned to user code. + it is returned to user code. This `post_update_test_case` interceptor runs + before the `post_update_test_case_with_metadata` interceptor. """ return response + def post_update_test_case_with_metadata( + self, + response: gcdc_test_case.TestCase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_test_case.TestCase, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_test_case + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TestCases server but before it is returned to user code. + + We recommend only using this `post_update_test_case_with_metadata` + interceptor in new development instead of the `post_update_test_case` interceptor. + When both interceptors are used, this `post_update_test_case_with_metadata` interceptor runs after the + `post_update_test_case` interceptor. The (possibly modified) response returned by + `post_update_test_case` will be passed to + `post_update_test_case_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -964,6 +1223,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_run_test_cases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_run_test_cases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1109,6 +1372,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_calculate_coverage(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_calculate_coverage_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1266,6 +1533,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_test_case(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_test_case_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1420,6 +1691,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_test_cases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_test_cases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1563,6 +1838,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_test_case(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_test_case_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1708,6 +1987,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_test_case_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_test_case_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1862,6 +2145,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_test_cases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_test_cases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2007,6 +2294,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_test_case_results(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_test_case_results_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2156,6 +2447,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_test_cases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_test_cases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2306,6 +2601,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_run_test_case(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_run_test_case_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2461,6 +2760,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_test_case(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_test_case_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/tools/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/tools/client.py index dd2088a4a928..89befef87029 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/tools/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/tools/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -517,6 +519,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1443,16 +1472,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1498,16 +1531,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1608,16 +1645,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1663,16 +1704,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/tools/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/tools/transports/rest.py index 79597df379b0..ef8f48426c2e 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/tools/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/tools/transports/rest.py @@ -137,12 +137,35 @@ def pre_create_tool( def post_create_tool(self, response: gcdc_tool.Tool) -> gcdc_tool.Tool: """Post-rpc interceptor for create_tool - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_tool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Tools server but before - it is returned to user code. + it is returned to user code. This `post_create_tool` interceptor runs + before the `post_create_tool_with_metadata` interceptor. """ return response + def post_create_tool_with_metadata( + self, + response: gcdc_tool.Tool, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_tool.Tool, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_tool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Tools server but before it is returned to user code. + + We recommend only using this `post_create_tool_with_metadata` + interceptor in new development instead of the `post_create_tool` interceptor. + When both interceptors are used, this `post_create_tool_with_metadata` interceptor runs after the + `post_create_tool` interceptor. The (possibly modified) response returned by + `post_create_tool` will be passed to + `post_create_tool_with_metadata`. + """ + return response, metadata + def pre_delete_tool( self, request: tool.DeleteToolRequest, @@ -172,12 +195,35 @@ def post_export_tools( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_tools - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_tools_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Tools server but before - it is returned to user code. + it is returned to user code. This `post_export_tools` interceptor runs + before the `post_export_tools_with_metadata` interceptor. """ return response + def post_export_tools_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_tools + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Tools server but before it is returned to user code. + + We recommend only using this `post_export_tools_with_metadata` + interceptor in new development instead of the `post_export_tools` interceptor. + When both interceptors are used, this `post_export_tools_with_metadata` interceptor runs after the + `post_export_tools` interceptor. The (possibly modified) response returned by + `post_export_tools` will be passed to + `post_export_tools_with_metadata`. + """ + return response, metadata + def pre_get_tool( self, request: tool.GetToolRequest, @@ -193,12 +239,33 @@ def pre_get_tool( def post_get_tool(self, response: tool.Tool) -> tool.Tool: """Post-rpc interceptor for get_tool - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_tool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Tools server but before - it is returned to user code. + it is returned to user code. This `post_get_tool` interceptor runs + before the `post_get_tool_with_metadata` interceptor. """ return response + def post_get_tool_with_metadata( + self, response: tool.Tool, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[tool.Tool, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_tool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Tools server but before it is returned to user code. + + We recommend only using this `post_get_tool_with_metadata` + interceptor in new development instead of the `post_get_tool` interceptor. + When both interceptors are used, this `post_get_tool_with_metadata` interceptor runs after the + `post_get_tool` interceptor. The (possibly modified) response returned by + `post_get_tool` will be passed to + `post_get_tool_with_metadata`. + """ + return response, metadata + def pre_list_tools( self, request: tool.ListToolsRequest, @@ -216,12 +283,35 @@ def post_list_tools( ) -> tool.ListToolsResponse: """Post-rpc interceptor for list_tools - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_tools_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Tools server but before - it is returned to user code. + it is returned to user code. This `post_list_tools` interceptor runs + before the `post_list_tools_with_metadata` interceptor. """ return response + def post_list_tools_with_metadata( + self, + response: tool.ListToolsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[tool.ListToolsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_tools + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Tools server but before it is returned to user code. + + We recommend only using this `post_list_tools_with_metadata` + interceptor in new development instead of the `post_list_tools` interceptor. + When both interceptors are used, this `post_list_tools_with_metadata` interceptor runs after the + `post_list_tools` interceptor. The (possibly modified) response returned by + `post_list_tools` will be passed to + `post_list_tools_with_metadata`. + """ + return response, metadata + def pre_update_tool( self, request: gcdc_tool.UpdateToolRequest, @@ -237,12 +327,35 @@ def pre_update_tool( def post_update_tool(self, response: gcdc_tool.Tool) -> gcdc_tool.Tool: """Post-rpc interceptor for update_tool - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_tool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Tools server but before - it is returned to user code. + it is returned to user code. This `post_update_tool` interceptor runs + before the `post_update_tool_with_metadata` interceptor. """ return response + def post_update_tool_with_metadata( + self, + response: gcdc_tool.Tool, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_tool.Tool, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_tool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Tools server but before it is returned to user code. + + We recommend only using this `post_update_tool_with_metadata` + interceptor in new development instead of the `post_update_tool` interceptor. + When both interceptors are used, this `post_update_tool_with_metadata` interceptor runs after the + `post_update_tool` interceptor. The (possibly modified) response returned by + `post_update_tool` will be passed to + `post_update_tool_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -643,6 +756,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_tool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_tool_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -898,6 +1015,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_tools(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_tools_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1043,6 +1164,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_tool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_tool_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1186,6 +1311,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_tools(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_tools_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1339,6 +1468,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_tool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_tool_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/transition_route_groups/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/transition_route_groups/client.py index d0e9932a29f0..ca5c205aefaa 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/transition_route_groups/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/transition_route_groups/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -622,6 +624,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1514,16 +1543,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1569,16 +1602,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1679,16 +1716,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1734,16 +1775,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/transition_route_groups/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/transition_route_groups/transports/rest.py index 67ea7095fa23..28e344dd6358 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/transition_route_groups/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/transition_route_groups/transports/rest.py @@ -136,12 +136,38 @@ def post_create_transition_route_group( ) -> gcdc_transition_route_group.TransitionRouteGroup: """Post-rpc interceptor for create_transition_route_group - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_transition_route_group_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TransitionRouteGroups server but before - it is returned to user code. + it is returned to user code. This `post_create_transition_route_group` interceptor runs + before the `post_create_transition_route_group_with_metadata` interceptor. """ return response + def post_create_transition_route_group_with_metadata( + self, + response: gcdc_transition_route_group.TransitionRouteGroup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_transition_route_group.TransitionRouteGroup, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for create_transition_route_group + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TransitionRouteGroups server but before it is returned to user code. + + We recommend only using this `post_create_transition_route_group_with_metadata` + interceptor in new development instead of the `post_create_transition_route_group` interceptor. + When both interceptors are used, this `post_create_transition_route_group_with_metadata` interceptor runs after the + `post_create_transition_route_group` interceptor. The (possibly modified) response returned by + `post_create_transition_route_group` will be passed to + `post_create_transition_route_group_with_metadata`. + """ + return response, metadata + def pre_delete_transition_route_group( self, request: transition_route_group.DeleteTransitionRouteGroupRequest, @@ -177,12 +203,38 @@ def post_get_transition_route_group( ) -> transition_route_group.TransitionRouteGroup: """Post-rpc interceptor for get_transition_route_group - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_transition_route_group_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TransitionRouteGroups server but before - it is returned to user code. + it is returned to user code. This `post_get_transition_route_group` interceptor runs + before the `post_get_transition_route_group_with_metadata` interceptor. """ return response + def post_get_transition_route_group_with_metadata( + self, + response: transition_route_group.TransitionRouteGroup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + transition_route_group.TransitionRouteGroup, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_transition_route_group + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TransitionRouteGroups server but before it is returned to user code. + + We recommend only using this `post_get_transition_route_group_with_metadata` + interceptor in new development instead of the `post_get_transition_route_group` interceptor. + When both interceptors are used, this `post_get_transition_route_group_with_metadata` interceptor runs after the + `post_get_transition_route_group` interceptor. The (possibly modified) response returned by + `post_get_transition_route_group` will be passed to + `post_get_transition_route_group_with_metadata`. + """ + return response, metadata + def pre_list_transition_route_groups( self, request: transition_route_group.ListTransitionRouteGroupsRequest, @@ -203,12 +255,38 @@ def post_list_transition_route_groups( ) -> transition_route_group.ListTransitionRouteGroupsResponse: """Post-rpc interceptor for list_transition_route_groups - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_transition_route_groups_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TransitionRouteGroups server but before - it is returned to user code. + it is returned to user code. This `post_list_transition_route_groups` interceptor runs + before the `post_list_transition_route_groups_with_metadata` interceptor. """ return response + def post_list_transition_route_groups_with_metadata( + self, + response: transition_route_group.ListTransitionRouteGroupsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + transition_route_group.ListTransitionRouteGroupsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_transition_route_groups + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TransitionRouteGroups server but before it is returned to user code. + + We recommend only using this `post_list_transition_route_groups_with_metadata` + interceptor in new development instead of the `post_list_transition_route_groups` interceptor. + When both interceptors are used, this `post_list_transition_route_groups_with_metadata` interceptor runs after the + `post_list_transition_route_groups` interceptor. The (possibly modified) response returned by + `post_list_transition_route_groups` will be passed to + `post_list_transition_route_groups_with_metadata`. + """ + return response, metadata + def pre_update_transition_route_group( self, request: gcdc_transition_route_group.UpdateTransitionRouteGroupRequest, @@ -229,12 +307,38 @@ def post_update_transition_route_group( ) -> gcdc_transition_route_group.TransitionRouteGroup: """Post-rpc interceptor for update_transition_route_group - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_transition_route_group_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the TransitionRouteGroups server but before - it is returned to user code. + it is returned to user code. This `post_update_transition_route_group` interceptor runs + before the `post_update_transition_route_group_with_metadata` interceptor. """ return response + def post_update_transition_route_group_with_metadata( + self, + response: gcdc_transition_route_group.TransitionRouteGroup, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcdc_transition_route_group.TransitionRouteGroup, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_transition_route_group + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the TransitionRouteGroups server but before it is returned to user code. + + We recommend only using this `post_update_transition_route_group_with_metadata` + interceptor in new development instead of the `post_update_transition_route_group` interceptor. + When both interceptors are used, this `post_update_transition_route_group_with_metadata` interceptor runs after the + `post_update_transition_route_group` interceptor. The (possibly modified) response returned by + `post_update_transition_route_group` will be passed to + `post_update_transition_route_group_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -578,6 +682,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_transition_route_group(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_create_transition_route_group_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -842,6 +953,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_transition_route_group(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_transition_route_group_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -991,6 +1106,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_transition_route_groups(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_transition_route_groups_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1148,6 +1267,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_transition_route_group(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_update_transition_route_group_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/versions/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/versions/client.py index e16564327773..44501ea87993 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/versions/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/versions/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -499,6 +501,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1592,16 +1621,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1647,16 +1680,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1757,16 +1794,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1812,16 +1853,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/versions/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/versions/transports/rest.py index 60321cbd7453..ac498b77fdf7 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/versions/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/versions/transports/rest.py @@ -147,12 +147,37 @@ def post_compare_versions( ) -> version.CompareVersionsResponse: """Post-rpc interceptor for compare_versions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_compare_versions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_compare_versions` interceptor runs + before the `post_compare_versions_with_metadata` interceptor. """ return response + def post_compare_versions_with_metadata( + self, + response: version.CompareVersionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + version.CompareVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for compare_versions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_compare_versions_with_metadata` + interceptor in new development instead of the `post_compare_versions` interceptor. + When both interceptors are used, this `post_compare_versions_with_metadata` interceptor runs after the + `post_compare_versions` interceptor. The (possibly modified) response returned by + `post_compare_versions` will be passed to + `post_compare_versions_with_metadata`. + """ + return response, metadata + def pre_create_version( self, request: gcdc_version.CreateVersionRequest, @@ -172,12 +197,35 @@ def post_create_version( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_create_version` interceptor runs + before the `post_create_version_with_metadata` interceptor. """ return response + def post_create_version_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_create_version_with_metadata` + interceptor in new development instead of the `post_create_version` interceptor. + When both interceptors are used, this `post_create_version_with_metadata` interceptor runs after the + `post_create_version` interceptor. The (possibly modified) response returned by + `post_create_version` will be passed to + `post_create_version_with_metadata`. + """ + return response, metadata + def pre_delete_version( self, request: version.DeleteVersionRequest, @@ -205,12 +253,35 @@ def pre_get_version( def post_get_version(self, response: version.Version) -> version.Version: """Post-rpc interceptor for get_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_get_version` interceptor runs + before the `post_get_version_with_metadata` interceptor. """ return response + def post_get_version_with_metadata( + self, + response: version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_get_version_with_metadata` + interceptor in new development instead of the `post_get_version` interceptor. + When both interceptors are used, this `post_get_version_with_metadata` interceptor runs after the + `post_get_version` interceptor. The (possibly modified) response returned by + `post_get_version` will be passed to + `post_get_version_with_metadata`. + """ + return response, metadata + def pre_list_versions( self, request: version.ListVersionsRequest, @@ -228,12 +299,35 @@ def post_list_versions( ) -> version.ListVersionsResponse: """Post-rpc interceptor for list_versions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_versions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_list_versions` interceptor runs + before the `post_list_versions_with_metadata` interceptor. """ return response + def post_list_versions_with_metadata( + self, + response: version.ListVersionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[version.ListVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_versions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_list_versions_with_metadata` + interceptor in new development instead of the `post_list_versions` interceptor. + When both interceptors are used, this `post_list_versions_with_metadata` interceptor runs after the + `post_list_versions` interceptor. The (possibly modified) response returned by + `post_list_versions` will be passed to + `post_list_versions_with_metadata`. + """ + return response, metadata + def pre_load_version( self, request: version.LoadVersionRequest, @@ -251,12 +345,35 @@ def post_load_version( ) -> operations_pb2.Operation: """Post-rpc interceptor for load_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_load_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_load_version` interceptor runs + before the `post_load_version_with_metadata` interceptor. """ return response + def post_load_version_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for load_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_load_version_with_metadata` + interceptor in new development instead of the `post_load_version` interceptor. + When both interceptors are used, this `post_load_version_with_metadata` interceptor runs after the + `post_load_version` interceptor. The (possibly modified) response returned by + `post_load_version` will be passed to + `post_load_version_with_metadata`. + """ + return response, metadata + def pre_update_version( self, request: gcdc_version.UpdateVersionRequest, @@ -276,12 +393,35 @@ def post_update_version( ) -> gcdc_version.Version: """Post-rpc interceptor for update_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_update_version` interceptor runs + before the `post_update_version_with_metadata` interceptor. """ return response + def post_update_version_with_metadata( + self, + response: gcdc_version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_update_version_with_metadata` + interceptor in new development instead of the `post_update_version` interceptor. + When both interceptors are used, this `post_update_version_with_metadata` interceptor runs after the + `post_update_version` interceptor. The (possibly modified) response returned by + `post_update_version` will be passed to + `post_update_version_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -686,6 +826,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_compare_versions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_compare_versions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -838,6 +982,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1092,6 +1240,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1237,6 +1389,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_versions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_versions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1387,6 +1543,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_load_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_load_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1538,6 +1698,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/webhooks/client.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/webhooks/client.py index 83870d02d64a..7c57c9c862ed 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/webhooks/client.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/webhooks/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -516,6 +518,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1338,16 +1367,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1393,16 +1426,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1503,16 +1540,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1558,16 +1599,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/webhooks/transports/rest.py b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/webhooks/transports/rest.py index b844072f006e..544a300a67d0 100644 --- a/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/webhooks/transports/rest.py +++ b/packages/google-cloud-dialogflow-cx/google/cloud/dialogflowcx_v3beta1/services/webhooks/transports/rest.py @@ -133,12 +133,35 @@ def post_create_webhook( ) -> gcdc_webhook.Webhook: """Post-rpc interceptor for create_webhook - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_webhook_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Webhooks server but before - it is returned to user code. + it is returned to user code. This `post_create_webhook` interceptor runs + before the `post_create_webhook_with_metadata` interceptor. """ return response + def post_create_webhook_with_metadata( + self, + response: gcdc_webhook.Webhook, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_webhook.Webhook, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_webhook + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Webhooks server but before it is returned to user code. + + We recommend only using this `post_create_webhook_with_metadata` + interceptor in new development instead of the `post_create_webhook` interceptor. + When both interceptors are used, this `post_create_webhook_with_metadata` interceptor runs after the + `post_create_webhook` interceptor. The (possibly modified) response returned by + `post_create_webhook` will be passed to + `post_create_webhook_with_metadata`. + """ + return response, metadata + def pre_delete_webhook( self, request: webhook.DeleteWebhookRequest, @@ -166,12 +189,35 @@ def pre_get_webhook( def post_get_webhook(self, response: webhook.Webhook) -> webhook.Webhook: """Post-rpc interceptor for get_webhook - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_webhook_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Webhooks server but before - it is returned to user code. + it is returned to user code. This `post_get_webhook` interceptor runs + before the `post_get_webhook_with_metadata` interceptor. """ return response + def post_get_webhook_with_metadata( + self, + response: webhook.Webhook, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[webhook.Webhook, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_webhook + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Webhooks server but before it is returned to user code. + + We recommend only using this `post_get_webhook_with_metadata` + interceptor in new development instead of the `post_get_webhook` interceptor. + When both interceptors are used, this `post_get_webhook_with_metadata` interceptor runs after the + `post_get_webhook` interceptor. The (possibly modified) response returned by + `post_get_webhook` will be passed to + `post_get_webhook_with_metadata`. + """ + return response, metadata + def pre_list_webhooks( self, request: webhook.ListWebhooksRequest, @@ -189,12 +235,35 @@ def post_list_webhooks( ) -> webhook.ListWebhooksResponse: """Post-rpc interceptor for list_webhooks - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_webhooks_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Webhooks server but before - it is returned to user code. + it is returned to user code. This `post_list_webhooks` interceptor runs + before the `post_list_webhooks_with_metadata` interceptor. """ return response + def post_list_webhooks_with_metadata( + self, + response: webhook.ListWebhooksResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[webhook.ListWebhooksResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_webhooks + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Webhooks server but before it is returned to user code. + + We recommend only using this `post_list_webhooks_with_metadata` + interceptor in new development instead of the `post_list_webhooks` interceptor. + When both interceptors are used, this `post_list_webhooks_with_metadata` interceptor runs after the + `post_list_webhooks` interceptor. The (possibly modified) response returned by + `post_list_webhooks` will be passed to + `post_list_webhooks_with_metadata`. + """ + return response, metadata + def pre_update_webhook( self, request: gcdc_webhook.UpdateWebhookRequest, @@ -214,12 +283,35 @@ def post_update_webhook( ) -> gcdc_webhook.Webhook: """Post-rpc interceptor for update_webhook - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_webhook_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Webhooks server but before - it is returned to user code. + it is returned to user code. This `post_update_webhook` interceptor runs + before the `post_update_webhook_with_metadata` interceptor. """ return response + def post_update_webhook_with_metadata( + self, + response: gcdc_webhook.Webhook, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcdc_webhook.Webhook, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_webhook + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Webhooks server but before it is returned to user code. + + We recommend only using this `post_update_webhook_with_metadata` + interceptor in new development instead of the `post_update_webhook` interceptor. + When both interceptors are used, this `post_update_webhook_with_metadata` interceptor runs after the + `post_update_webhook` interceptor. The (possibly modified) response returned by + `post_update_webhook` will be passed to + `post_update_webhook_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -566,6 +658,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_webhook(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_webhook_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -827,6 +923,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_webhook(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_webhook_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -972,6 +1072,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_webhooks(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_webhooks_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1130,6 +1234,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_webhook(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_webhook_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER 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 b445daf1063d..731171c3a5ff 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.38.0" + "version": "0.1.0" }, "snippets": [ { 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 c26c15425384..32e61a2161ba 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.38.0" + "version": "0.1.0" }, "snippets": [ { 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 5626caa01b19..c4139338b971 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 @@ -83,6 +83,13 @@ from google.cloud.dialogflowcx_v3.types import generative_settings from google.cloud.dialogflowcx_v3.types import safety_settings +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -305,6 +312,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AgentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AgentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7446,10 +7496,13 @@ def test_list_agents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_list_agents" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_list_agents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_list_agents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ListAgentsRequest.pb(agent.ListAgentsRequest()) transcode.return_value = { "method": "post", @@ -7471,6 +7524,7 @@ def test_list_agents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.ListAgentsResponse() + post_with_metadata.return_value = agent.ListAgentsResponse(), metadata client.list_agents( request, @@ -7482,6 +7536,7 @@ def test_list_agents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_agent_rest_bad_request(request_type=agent.GetAgentRequest): @@ -7586,10 +7641,13 @@ def test_get_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_get_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetAgentRequest.pb(agent.GetAgentRequest()) transcode.return_value = { "method": "post", @@ -7611,6 +7669,7 @@ def test_get_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.Agent() + post_with_metadata.return_value = agent.Agent(), metadata client.get_agent( request, @@ -7622,6 +7681,7 @@ def test_get_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_agent_rest_bad_request(request_type=gcdc_agent.CreateAgentRequest): @@ -7851,10 +7911,13 @@ def test_create_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_create_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_create_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_create_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_agent.CreateAgentRequest.pb(gcdc_agent.CreateAgentRequest()) transcode.return_value = { "method": "post", @@ -7876,6 +7939,7 @@ def test_create_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_agent.Agent() + post_with_metadata.return_value = gcdc_agent.Agent(), metadata client.create_agent( request, @@ -7887,6 +7951,7 @@ def test_create_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_agent_rest_bad_request(request_type=gcdc_agent.UpdateAgentRequest): @@ -8120,10 +8185,13 @@ def test_update_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_update_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_update_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_update_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_agent.UpdateAgentRequest.pb(gcdc_agent.UpdateAgentRequest()) transcode.return_value = { "method": "post", @@ -8145,6 +8213,7 @@ def test_update_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_agent.Agent() + post_with_metadata.return_value = gcdc_agent.Agent(), metadata client.update_agent( request, @@ -8156,6 +8225,7 @@ def test_update_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_agent_rest_bad_request(request_type=agent.DeleteAgentRequest): @@ -8335,10 +8405,13 @@ def test_export_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_export_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_export_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_export_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ExportAgentRequest.pb(agent.ExportAgentRequest()) transcode.return_value = { "method": "post", @@ -8360,6 +8433,7 @@ def test_export_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_agent( request, @@ -8371,6 +8445,7 @@ def test_export_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_restore_agent_rest_bad_request(request_type=agent.RestoreAgentRequest): @@ -8447,10 +8522,13 @@ def test_restore_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_restore_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_restore_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_restore_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.RestoreAgentRequest.pb(agent.RestoreAgentRequest()) transcode.return_value = { "method": "post", @@ -8472,6 +8550,7 @@ def test_restore_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.restore_agent( request, @@ -8483,6 +8562,7 @@ def test_restore_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_validate_agent_rest_bad_request(request_type=agent.ValidateAgentRequest): @@ -8563,10 +8643,13 @@ def test_validate_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_validate_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_validate_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_validate_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ValidateAgentRequest.pb(agent.ValidateAgentRequest()) transcode.return_value = { "method": "post", @@ -8590,6 +8673,7 @@ def test_validate_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.AgentValidationResult() + post_with_metadata.return_value = agent.AgentValidationResult(), metadata client.validate_agent( request, @@ -8601,6 +8685,7 @@ def test_validate_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_agent_validation_result_rest_bad_request( @@ -8687,10 +8772,14 @@ def test_get_agent_validation_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_agent_validation_result" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, + "post_get_agent_validation_result_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_agent_validation_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetAgentValidationResultRequest.pb( agent.GetAgentValidationResultRequest() ) @@ -8716,6 +8805,7 @@ def test_get_agent_validation_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.AgentValidationResult() + post_with_metadata.return_value = agent.AgentValidationResult(), metadata client.get_agent_validation_result( request, @@ -8727,6 +8817,7 @@ def test_get_agent_validation_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_generative_settings_rest_bad_request( @@ -8815,10 +8906,13 @@ def test_get_generative_settings_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_generative_settings" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_get_generative_settings_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_generative_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetGenerativeSettingsRequest.pb( agent.GetGenerativeSettingsRequest() ) @@ -8844,6 +8938,10 @@ def test_get_generative_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generative_settings.GenerativeSettings() + post_with_metadata.return_value = ( + generative_settings.GenerativeSettings(), + metadata, + ) client.get_generative_settings( request, @@ -8855,6 +8953,7 @@ def test_get_generative_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_generative_settings_rest_bad_request( @@ -9043,10 +9142,14 @@ def test_update_generative_settings_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_update_generative_settings" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, + "post_update_generative_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_update_generative_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.UpdateGenerativeSettingsRequest.pb( agent.UpdateGenerativeSettingsRequest() ) @@ -9072,6 +9175,10 @@ def test_update_generative_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_generative_settings.GenerativeSettings() + post_with_metadata.return_value = ( + gcdc_generative_settings.GenerativeSettings(), + metadata, + ) client.update_generative_settings( request, @@ -9083,6 +9190,7 @@ def test_update_generative_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_changelogs.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_changelogs.py index 3cf9940bb7bb..aaccdf4e4c23 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_changelogs.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_changelogs.py @@ -63,6 +63,13 @@ ) from google.cloud.dialogflowcx_v3.types import changelog +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -298,6 +305,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ChangelogsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ChangelogsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2632,10 +2682,13 @@ def test_list_changelogs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ChangelogsRestInterceptor, "post_list_changelogs" ) as post, mock.patch.object( + transports.ChangelogsRestInterceptor, "post_list_changelogs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ChangelogsRestInterceptor, "pre_list_changelogs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = changelog.ListChangelogsRequest.pb( changelog.ListChangelogsRequest() ) @@ -2661,6 +2714,7 @@ def test_list_changelogs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = changelog.ListChangelogsResponse() + post_with_metadata.return_value = changelog.ListChangelogsResponse(), metadata client.list_changelogs( request, @@ -2672,6 +2726,7 @@ def test_list_changelogs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_changelog_rest_bad_request(request_type=changelog.GetChangelogRequest): @@ -2770,10 +2825,13 @@ def test_get_changelog_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ChangelogsRestInterceptor, "post_get_changelog" ) as post, mock.patch.object( + transports.ChangelogsRestInterceptor, "post_get_changelog_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ChangelogsRestInterceptor, "pre_get_changelog" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = changelog.GetChangelogRequest.pb(changelog.GetChangelogRequest()) transcode.return_value = { "method": "post", @@ -2795,6 +2853,7 @@ def test_get_changelog_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = changelog.Changelog() + post_with_metadata.return_value = changelog.Changelog(), metadata client.get_changelog( request, @@ -2806,6 +2865,7 @@ def test_get_changelog_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_deployments.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_deployments.py index a71209537279..1d45c0c6a8dc 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_deployments.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_deployments.py @@ -63,6 +63,13 @@ ) from google.cloud.dialogflowcx_v3.types import deployment +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -302,6 +309,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DeploymentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DeploymentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2634,10 +2684,13 @@ def test_list_deployments_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeploymentsRestInterceptor, "post_list_deployments" ) as post, mock.patch.object( + transports.DeploymentsRestInterceptor, "post_list_deployments_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DeploymentsRestInterceptor, "pre_list_deployments" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = deployment.ListDeploymentsRequest.pb( deployment.ListDeploymentsRequest() ) @@ -2663,6 +2716,7 @@ def test_list_deployments_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = deployment.ListDeploymentsResponse() + post_with_metadata.return_value = deployment.ListDeploymentsResponse(), metadata client.list_deployments( request, @@ -2674,6 +2728,7 @@ def test_list_deployments_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_deployment_rest_bad_request(request_type=deployment.GetDeploymentRequest): @@ -2764,10 +2819,13 @@ def test_get_deployment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeploymentsRestInterceptor, "post_get_deployment" ) as post, mock.patch.object( + transports.DeploymentsRestInterceptor, "post_get_deployment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DeploymentsRestInterceptor, "pre_get_deployment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = deployment.GetDeploymentRequest.pb( deployment.GetDeploymentRequest() ) @@ -2791,6 +2849,7 @@ def test_get_deployment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = deployment.Deployment() + post_with_metadata.return_value = deployment.Deployment(), metadata client.get_deployment( request, @@ -2802,6 +2861,7 @@ def test_get_deployment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_entity_types.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_entity_types.py index 0baeb7aad661..11e7f021161f 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_entity_types.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_entity_types.py @@ -74,6 +74,13 @@ from google.cloud.dialogflowcx_v3.types import entity_type as gcdc_entity_type from google.cloud.dialogflowcx_v3.types import inline +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -313,6 +320,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5431,10 +5481,13 @@ def test_get_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_get_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_get_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_get_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.GetEntityTypeRequest.pb( entity_type.GetEntityTypeRequest() ) @@ -5458,6 +5511,7 @@ def test_get_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = entity_type.EntityType() + post_with_metadata.return_value = entity_type.EntityType(), metadata client.get_entity_type( request, @@ -5469,6 +5523,7 @@ def test_get_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_entity_type_rest_bad_request( @@ -5645,10 +5700,13 @@ def test_create_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_create_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_create_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_create_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_entity_type.CreateEntityTypeRequest.pb( gcdc_entity_type.CreateEntityTypeRequest() ) @@ -5674,6 +5732,7 @@ def test_create_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_entity_type.EntityType() + post_with_metadata.return_value = gcdc_entity_type.EntityType(), metadata client.create_entity_type( request, @@ -5685,6 +5744,7 @@ def test_create_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_entity_type_rest_bad_request( @@ -5869,10 +5929,13 @@ def test_update_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_update_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_update_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_update_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_entity_type.UpdateEntityTypeRequest.pb( gcdc_entity_type.UpdateEntityTypeRequest() ) @@ -5898,6 +5961,7 @@ def test_update_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_entity_type.EntityType() + post_with_metadata.return_value = gcdc_entity_type.EntityType(), metadata client.update_entity_type( request, @@ -5909,6 +5973,7 @@ def test_update_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_entity_type_rest_bad_request( @@ -6106,10 +6171,13 @@ def test_list_entity_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_list_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_list_entity_types_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_list_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.ListEntityTypesRequest.pb( entity_type.ListEntityTypesRequest() ) @@ -6135,6 +6203,10 @@ def test_list_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = entity_type.ListEntityTypesResponse() + post_with_metadata.return_value = ( + entity_type.ListEntityTypesResponse(), + metadata, + ) client.list_entity_types( request, @@ -6146,6 +6218,7 @@ def test_list_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_entity_types_rest_bad_request( @@ -6226,10 +6299,13 @@ def test_export_entity_types_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_export_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_export_entity_types_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_export_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.ExportEntityTypesRequest.pb( entity_type.ExportEntityTypesRequest() ) @@ -6253,6 +6329,7 @@ def test_export_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_entity_types( request, @@ -6264,6 +6341,7 @@ def test_export_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_entity_types_rest_bad_request( @@ -6344,10 +6422,13 @@ def test_import_entity_types_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_import_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_import_entity_types_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_import_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.ImportEntityTypesRequest.pb( entity_type.ImportEntityTypesRequest() ) @@ -6371,6 +6452,7 @@ def test_import_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_entity_types( request, @@ -6382,6 +6464,7 @@ def test_import_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_environments.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_environments.py index 9c7912bf4c11..66d5fcd65915 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_environments.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_environments.py @@ -77,6 +77,13 @@ from google.cloud.dialogflowcx_v3.types import environment as gcdc_environment from google.cloud.dialogflowcx_v3.types import webhook +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -320,6 +327,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EnvironmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EnvironmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7023,10 +7073,13 @@ def test_list_environments_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_list_environments" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_list_environments_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_list_environments" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.ListEnvironmentsRequest.pb( environment.ListEnvironmentsRequest() ) @@ -7052,6 +7105,10 @@ def test_list_environments_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.ListEnvironmentsResponse() + post_with_metadata.return_value = ( + environment.ListEnvironmentsResponse(), + metadata, + ) client.list_environments( request, @@ -7063,6 +7120,7 @@ def test_list_environments_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_environment_rest_bad_request( @@ -7155,10 +7213,13 @@ def test_get_environment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_get_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_get_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_get_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.GetEnvironmentRequest.pb( environment.GetEnvironmentRequest() ) @@ -7182,6 +7243,7 @@ def test_get_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.Environment() + post_with_metadata.return_value = environment.Environment(), metadata client.get_environment( request, @@ -7193,6 +7255,7 @@ def test_get_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_environment_rest_bad_request( @@ -7387,10 +7450,13 @@ def test_create_environment_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EnvironmentsRestInterceptor, "post_create_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_create_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_create_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_environment.CreateEnvironmentRequest.pb( gcdc_environment.CreateEnvironmentRequest() ) @@ -7414,6 +7480,7 @@ def test_create_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_environment( request, @@ -7425,6 +7492,7 @@ def test_create_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_environment_rest_bad_request( @@ -7627,10 +7695,13 @@ def test_update_environment_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EnvironmentsRestInterceptor, "post_update_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_update_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_update_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_environment.UpdateEnvironmentRequest.pb( gcdc_environment.UpdateEnvironmentRequest() ) @@ -7654,6 +7725,7 @@ def test_update_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_environment( request, @@ -7665,6 +7737,7 @@ def test_update_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_environment_rest_bad_request( @@ -7866,10 +7939,14 @@ def test_lookup_environment_history_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_lookup_environment_history" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, + "post_lookup_environment_history_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_lookup_environment_history" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.LookupEnvironmentHistoryRequest.pb( environment.LookupEnvironmentHistoryRequest() ) @@ -7895,6 +7972,10 @@ def test_lookup_environment_history_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.LookupEnvironmentHistoryResponse() + post_with_metadata.return_value = ( + environment.LookupEnvironmentHistoryResponse(), + metadata, + ) client.lookup_environment_history( request, @@ -7906,6 +7987,7 @@ def test_lookup_environment_history_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_run_continuous_test_rest_bad_request( @@ -7990,10 +8072,13 @@ def test_run_continuous_test_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EnvironmentsRestInterceptor, "post_run_continuous_test" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_run_continuous_test_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_run_continuous_test" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.RunContinuousTestRequest.pb( environment.RunContinuousTestRequest() ) @@ -8017,6 +8102,7 @@ def test_run_continuous_test_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.run_continuous_test( request, @@ -8028,6 +8114,7 @@ def test_run_continuous_test_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_continuous_test_results_rest_bad_request( @@ -8116,10 +8203,14 @@ def test_list_continuous_test_results_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_list_continuous_test_results" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, + "post_list_continuous_test_results_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_list_continuous_test_results" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.ListContinuousTestResultsRequest.pb( environment.ListContinuousTestResultsRequest() ) @@ -8145,6 +8236,10 @@ def test_list_continuous_test_results_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.ListContinuousTestResultsResponse() + post_with_metadata.return_value = ( + environment.ListContinuousTestResultsResponse(), + metadata, + ) client.list_continuous_test_results( request, @@ -8156,6 +8251,7 @@ def test_list_continuous_test_results_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_deploy_flow_rest_bad_request(request_type=environment.DeployFlowRequest): @@ -8238,10 +8334,13 @@ def test_deploy_flow_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EnvironmentsRestInterceptor, "post_deploy_flow" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_deploy_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_deploy_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.DeployFlowRequest.pb(environment.DeployFlowRequest()) transcode.return_value = { "method": "post", @@ -8263,6 +8362,7 @@ def test_deploy_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.deploy_flow( request, @@ -8274,6 +8374,7 @@ def test_deploy_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_experiments.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_experiments.py index d449a8ba8ba8..96553f404571 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_experiments.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_experiments.py @@ -66,6 +66,13 @@ from google.cloud.dialogflowcx_v3.types import experiment from google.cloud.dialogflowcx_v3.types import experiment as gcdc_experiment +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -305,6 +312,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ExperimentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ExperimentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5572,10 +5622,13 @@ def test_list_experiments_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_list_experiments" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_list_experiments_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_list_experiments" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = experiment.ListExperimentsRequest.pb( experiment.ListExperimentsRequest() ) @@ -5601,6 +5654,7 @@ def test_list_experiments_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = experiment.ListExperimentsResponse() + post_with_metadata.return_value = experiment.ListExperimentsResponse(), metadata client.list_experiments( request, @@ -5612,6 +5666,7 @@ def test_list_experiments_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_experiment_rest_bad_request(request_type=experiment.GetExperimentRequest): @@ -5706,10 +5761,13 @@ def test_get_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_get_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_get_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_get_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = experiment.GetExperimentRequest.pb( experiment.GetExperimentRequest() ) @@ -5733,6 +5791,7 @@ def test_get_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = experiment.Experiment() + post_with_metadata.return_value = experiment.Experiment(), metadata client.get_experiment( request, @@ -5744,6 +5803,7 @@ def test_get_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_experiment_rest_bad_request( @@ -5971,10 +6031,13 @@ def test_create_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_create_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_create_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_create_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_experiment.CreateExperimentRequest.pb( gcdc_experiment.CreateExperimentRequest() ) @@ -5998,6 +6061,7 @@ def test_create_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_experiment.Experiment() + post_with_metadata.return_value = gcdc_experiment.Experiment(), metadata client.create_experiment( request, @@ -6009,6 +6073,7 @@ def test_create_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_experiment_rest_bad_request( @@ -6240,10 +6305,13 @@ def test_update_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_update_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_update_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_update_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_experiment.UpdateExperimentRequest.pb( gcdc_experiment.UpdateExperimentRequest() ) @@ -6267,6 +6335,7 @@ def test_update_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_experiment.Experiment() + post_with_metadata.return_value = gcdc_experiment.Experiment(), metadata client.update_experiment( request, @@ -6278,6 +6347,7 @@ def test_update_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_experiment_rest_bad_request( @@ -6487,10 +6557,13 @@ def test_start_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_start_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_start_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_start_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = experiment.StartExperimentRequest.pb( experiment.StartExperimentRequest() ) @@ -6514,6 +6587,7 @@ def test_start_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = experiment.Experiment() + post_with_metadata.return_value = experiment.Experiment(), metadata client.start_experiment( request, @@ -6525,6 +6599,7 @@ def test_start_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_stop_experiment_rest_bad_request( @@ -6621,10 +6696,13 @@ def test_stop_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_stop_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_stop_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_stop_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = experiment.StopExperimentRequest.pb( experiment.StopExperimentRequest() ) @@ -6648,6 +6726,7 @@ def test_stop_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = experiment.Experiment() + post_with_metadata.return_value = experiment.Experiment(), metadata client.stop_experiment( request, @@ -6659,6 +6738,7 @@ def test_stop_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): 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 4de6779d70c5..2fd2b1639881 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 @@ -86,6 +86,13 @@ from google.cloud.dialogflowcx_v3.types import flow from google.cloud.dialogflowcx_v3.types import flow as gcdc_flow +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -304,6 +311,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = FlowsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = FlowsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6900,10 +6950,13 @@ def test_create_flow_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_create_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_create_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_create_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_flow.CreateFlowRequest.pb(gcdc_flow.CreateFlowRequest()) transcode.return_value = { "method": "post", @@ -6925,6 +6978,7 @@ def test_create_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_flow.Flow() + post_with_metadata.return_value = gcdc_flow.Flow(), metadata client.create_flow( request, @@ -6936,6 +6990,7 @@ def test_create_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_flow_rest_bad_request(request_type=flow.DeleteFlowRequest): @@ -7123,10 +7178,13 @@ def test_list_flows_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_list_flows" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_list_flows_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_list_flows" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.ListFlowsRequest.pb(flow.ListFlowsRequest()) transcode.return_value = { "method": "post", @@ -7148,6 +7206,7 @@ def test_list_flows_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = flow.ListFlowsResponse() + post_with_metadata.return_value = flow.ListFlowsResponse(), metadata client.list_flows( request, @@ -7159,6 +7218,7 @@ def test_list_flows_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_flow_rest_bad_request(request_type=flow.GetFlowRequest): @@ -7251,10 +7311,13 @@ def test_get_flow_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_get_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_get_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_get_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.GetFlowRequest.pb(flow.GetFlowRequest()) transcode.return_value = { "method": "post", @@ -7276,6 +7339,7 @@ def test_get_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = flow.Flow() + post_with_metadata.return_value = flow.Flow(), metadata client.get_flow( request, @@ -7287,6 +7351,7 @@ def test_get_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_flow_rest_bad_request(request_type=gcdc_flow.UpdateFlowRequest): @@ -7589,10 +7654,13 @@ def test_update_flow_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_update_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_update_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_update_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_flow.UpdateFlowRequest.pb(gcdc_flow.UpdateFlowRequest()) transcode.return_value = { "method": "post", @@ -7614,6 +7682,7 @@ def test_update_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_flow.Flow() + post_with_metadata.return_value = gcdc_flow.Flow(), metadata client.update_flow( request, @@ -7625,6 +7694,7 @@ def test_update_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_train_flow_rest_bad_request(request_type=flow.TrainFlowRequest): @@ -7705,10 +7775,13 @@ def test_train_flow_rest_interceptors(null_interceptor): ), mock.patch.object( transports.FlowsRestInterceptor, "post_train_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_train_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_train_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.TrainFlowRequest.pb(flow.TrainFlowRequest()) transcode.return_value = { "method": "post", @@ -7730,6 +7803,7 @@ def test_train_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.train_flow( request, @@ -7741,6 +7815,7 @@ def test_train_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_validate_flow_rest_bad_request(request_type=flow.ValidateFlowRequest): @@ -7825,10 +7900,13 @@ def test_validate_flow_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_validate_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_validate_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_validate_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.ValidateFlowRequest.pb(flow.ValidateFlowRequest()) transcode.return_value = { "method": "post", @@ -7850,6 +7928,7 @@ def test_validate_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = flow.FlowValidationResult() + post_with_metadata.return_value = flow.FlowValidationResult(), metadata client.validate_flow( request, @@ -7861,6 +7940,7 @@ def test_validate_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_flow_validation_result_rest_bad_request( @@ -7947,10 +8027,13 @@ def test_get_flow_validation_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_get_flow_validation_result" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_get_flow_validation_result_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_get_flow_validation_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.GetFlowValidationResultRequest.pb( flow.GetFlowValidationResultRequest() ) @@ -7974,6 +8057,7 @@ def test_get_flow_validation_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = flow.FlowValidationResult() + post_with_metadata.return_value = flow.FlowValidationResult(), metadata client.get_flow_validation_result( request, @@ -7985,6 +8069,7 @@ def test_get_flow_validation_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_flow_rest_bad_request(request_type=flow.ImportFlowRequest): @@ -8061,10 +8146,13 @@ def test_import_flow_rest_interceptors(null_interceptor): ), mock.patch.object( transports.FlowsRestInterceptor, "post_import_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_import_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_import_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.ImportFlowRequest.pb(flow.ImportFlowRequest()) transcode.return_value = { "method": "post", @@ -8086,6 +8174,7 @@ def test_import_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_flow( request, @@ -8097,6 +8186,7 @@ def test_import_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_flow_rest_bad_request(request_type=flow.ExportFlowRequest): @@ -8177,10 +8267,13 @@ def test_export_flow_rest_interceptors(null_interceptor): ), mock.patch.object( transports.FlowsRestInterceptor, "post_export_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_export_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_export_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.ExportFlowRequest.pb(flow.ExportFlowRequest()) transcode.return_value = { "method": "post", @@ -8202,6 +8295,7 @@ def test_export_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_flow( request, @@ -8213,6 +8307,7 @@ def test_export_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_generators.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_generators.py index 9b1d756bf30c..3c7337162dce 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_generators.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_generators.py @@ -64,6 +64,13 @@ from google.cloud.dialogflowcx_v3.types import generator from google.cloud.dialogflowcx_v3.types import generator as gcdc_generator +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -299,6 +306,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = GeneratorsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = GeneratorsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4316,10 +4366,13 @@ def test_list_generators_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_list_generators" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_list_generators_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_list_generators" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = generator.ListGeneratorsRequest.pb( generator.ListGeneratorsRequest() ) @@ -4345,6 +4398,7 @@ def test_list_generators_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generator.ListGeneratorsResponse() + post_with_metadata.return_value = generator.ListGeneratorsResponse(), metadata client.list_generators( request, @@ -4356,6 +4410,7 @@ def test_list_generators_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_generator_rest_bad_request(request_type=generator.GetGeneratorRequest): @@ -4444,10 +4499,13 @@ def test_get_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_get_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_get_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_get_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = generator.GetGeneratorRequest.pb(generator.GetGeneratorRequest()) transcode.return_value = { "method": "post", @@ -4469,6 +4527,7 @@ def test_get_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generator.Generator() + post_with_metadata.return_value = generator.Generator(), metadata client.get_generator( request, @@ -4480,6 +4539,7 @@ def test_get_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_generator_rest_bad_request( @@ -4645,10 +4705,13 @@ def test_create_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_create_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_create_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_create_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_generator.CreateGeneratorRequest.pb( gcdc_generator.CreateGeneratorRequest() ) @@ -4672,6 +4735,7 @@ def test_create_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_generator.Generator() + post_with_metadata.return_value = gcdc_generator.Generator(), metadata client.create_generator( request, @@ -4683,6 +4747,7 @@ def test_create_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_generator_rest_bad_request( @@ -4856,10 +4921,13 @@ def test_update_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_update_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_update_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_update_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_generator.UpdateGeneratorRequest.pb( gcdc_generator.UpdateGeneratorRequest() ) @@ -4883,6 +4951,7 @@ def test_update_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_generator.Generator() + post_with_metadata.return_value = gcdc_generator.Generator(), metadata client.update_generator( request, @@ -4894,6 +4963,7 @@ def test_update_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_generator_rest_bad_request( 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 11f348f04901..47a0e7f4e886 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 @@ -74,6 +74,13 @@ from google.cloud.dialogflowcx_v3.types import intent from google.cloud.dialogflowcx_v3.types import intent as gcdc_intent +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -297,6 +304,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = IntentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = IntentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5155,10 +5205,13 @@ def test_list_intents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_list_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_list_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_list_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.ListIntentsRequest.pb(intent.ListIntentsRequest()) transcode.return_value = { "method": "post", @@ -5180,6 +5233,7 @@ def test_list_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = intent.ListIntentsResponse() + post_with_metadata.return_value = intent.ListIntentsResponse(), metadata client.list_intents( request, @@ -5191,6 +5245,7 @@ def test_list_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_intent_rest_bad_request(request_type=intent.GetIntentRequest): @@ -5283,10 +5338,13 @@ def test_get_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_get_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_get_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_get_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.GetIntentRequest.pb(intent.GetIntentRequest()) transcode.return_value = { "method": "post", @@ -5308,6 +5366,7 @@ def test_get_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = intent.Intent() + post_with_metadata.return_value = intent.Intent(), metadata client.get_intent( request, @@ -5319,6 +5378,7 @@ def test_get_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_intent_rest_bad_request(request_type=gcdc_intent.CreateIntentRequest): @@ -5497,10 +5557,13 @@ def test_create_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_create_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_create_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_create_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_intent.CreateIntentRequest.pb( gcdc_intent.CreateIntentRequest() ) @@ -5524,6 +5587,7 @@ def test_create_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_intent.Intent() + post_with_metadata.return_value = gcdc_intent.Intent(), metadata client.create_intent( request, @@ -5535,6 +5599,7 @@ def test_create_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_intent_rest_bad_request(request_type=gcdc_intent.UpdateIntentRequest): @@ -5721,10 +5786,13 @@ def test_update_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_update_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_update_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_update_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_intent.UpdateIntentRequest.pb( gcdc_intent.UpdateIntentRequest() ) @@ -5748,6 +5816,7 @@ def test_update_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_intent.Intent() + post_with_metadata.return_value = gcdc_intent.Intent(), metadata client.update_intent( request, @@ -5759,6 +5828,7 @@ def test_update_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_intent_rest_bad_request(request_type=intent.DeleteIntentRequest): @@ -5942,10 +6012,13 @@ def test_import_intents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.IntentsRestInterceptor, "post_import_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_import_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_import_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.ImportIntentsRequest.pb(intent.ImportIntentsRequest()) transcode.return_value = { "method": "post", @@ -5967,6 +6040,7 @@ def test_import_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_intents( request, @@ -5978,6 +6052,7 @@ def test_import_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_intents_rest_bad_request(request_type=intent.ExportIntentsRequest): @@ -6054,10 +6129,13 @@ def test_export_intents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.IntentsRestInterceptor, "post_export_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_export_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_export_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.ExportIntentsRequest.pb(intent.ExportIntentsRequest()) transcode.return_value = { "method": "post", @@ -6079,6 +6157,7 @@ def test_export_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_intents( request, @@ -6090,6 +6169,7 @@ def test_export_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): 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 56d3d8be60ee..7125dd9038b0 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 @@ -73,6 +73,13 @@ from google.cloud.dialogflowcx_v3.types import page as gcdc_page from google.cloud.dialogflowcx_v3.types import response_message +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -291,6 +298,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = PagesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = PagesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4300,10 +4350,13 @@ def test_list_pages_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PagesRestInterceptor, "post_list_pages" ) as post, mock.patch.object( + transports.PagesRestInterceptor, "post_list_pages_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PagesRestInterceptor, "pre_list_pages" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = page.ListPagesRequest.pb(page.ListPagesRequest()) transcode.return_value = { "method": "post", @@ -4325,6 +4378,7 @@ def test_list_pages_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = page.ListPagesResponse() + post_with_metadata.return_value = page.ListPagesResponse(), metadata client.list_pages( request, @@ -4336,6 +4390,7 @@ def test_list_pages_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_page_rest_bad_request(request_type=page.GetPageRequest): @@ -4426,10 +4481,13 @@ def test_get_page_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PagesRestInterceptor, "post_get_page" ) as post, mock.patch.object( + transports.PagesRestInterceptor, "post_get_page_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PagesRestInterceptor, "pre_get_page" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = page.GetPageRequest.pb(page.GetPageRequest()) transcode.return_value = { "method": "post", @@ -4451,6 +4509,7 @@ def test_get_page_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = page.Page() + post_with_metadata.return_value = page.Page(), metadata client.get_page( request, @@ -4462,6 +4521,7 @@ def test_get_page_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_page_rest_bad_request(request_type=gcdc_page.CreatePageRequest): @@ -4759,10 +4819,13 @@ def test_create_page_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PagesRestInterceptor, "post_create_page" ) as post, mock.patch.object( + transports.PagesRestInterceptor, "post_create_page_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PagesRestInterceptor, "pre_create_page" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_page.CreatePageRequest.pb(gcdc_page.CreatePageRequest()) transcode.return_value = { "method": "post", @@ -4784,6 +4847,7 @@ def test_create_page_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_page.Page() + post_with_metadata.return_value = gcdc_page.Page(), metadata client.create_page( request, @@ -4795,6 +4859,7 @@ def test_create_page_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_page_rest_bad_request(request_type=gcdc_page.UpdatePageRequest): @@ -5096,10 +5161,13 @@ def test_update_page_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PagesRestInterceptor, "post_update_page" ) as post, mock.patch.object( + transports.PagesRestInterceptor, "post_update_page_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PagesRestInterceptor, "pre_update_page" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_page.UpdatePageRequest.pb(gcdc_page.UpdatePageRequest()) transcode.return_value = { "method": "post", @@ -5121,6 +5189,7 @@ def test_update_page_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_page.Page() + post_with_metadata.return_value = gcdc_page.Page(), metadata client.update_page( request, @@ -5132,6 +5201,7 @@ def test_update_page_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_page_rest_bad_request(request_type=page.DeletePageRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_security_settings_service.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_security_settings_service.py index 30662aba9886..ac34dba19ade 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_security_settings_service.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_security_settings_service.py @@ -66,6 +66,13 @@ ) from google.cloud.dialogflowcx_v3.types import security_settings +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -341,6 +348,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SecuritySettingsServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SecuritySettingsServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4833,11 +4883,15 @@ def test_create_security_settings_rest_interceptors(null_interceptor): transports.SecuritySettingsServiceRestInterceptor, "post_create_security_settings", ) as post, mock.patch.object( + transports.SecuritySettingsServiceRestInterceptor, + "post_create_security_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "pre_create_security_settings", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_security_settings.CreateSecuritySettingsRequest.pb( gcdc_security_settings.CreateSecuritySettingsRequest() ) @@ -4863,6 +4917,10 @@ def test_create_security_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_security_settings.SecuritySettings() + post_with_metadata.return_value = ( + gcdc_security_settings.SecuritySettings(), + metadata, + ) client.create_security_settings( request, @@ -4874,6 +4932,7 @@ def test_create_security_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_security_settings_rest_bad_request( @@ -4985,10 +5044,14 @@ def test_get_security_settings_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "post_get_security_settings" ) as post, mock.patch.object( + transports.SecuritySettingsServiceRestInterceptor, + "post_get_security_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "pre_get_security_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = security_settings.GetSecuritySettingsRequest.pb( security_settings.GetSecuritySettingsRequest() ) @@ -5014,6 +5077,7 @@ def test_get_security_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = security_settings.SecuritySettings() + post_with_metadata.return_value = security_settings.SecuritySettings(), metadata client.get_security_settings( request, @@ -5025,6 +5089,7 @@ def test_get_security_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_security_settings_rest_bad_request( @@ -5229,11 +5294,15 @@ def test_update_security_settings_rest_interceptors(null_interceptor): transports.SecuritySettingsServiceRestInterceptor, "post_update_security_settings", ) as post, mock.patch.object( + transports.SecuritySettingsServiceRestInterceptor, + "post_update_security_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "pre_update_security_settings", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_security_settings.UpdateSecuritySettingsRequest.pb( gcdc_security_settings.UpdateSecuritySettingsRequest() ) @@ -5259,6 +5328,10 @@ def test_update_security_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_security_settings.SecuritySettings() + post_with_metadata.return_value = ( + gcdc_security_settings.SecuritySettings(), + metadata, + ) client.update_security_settings( request, @@ -5270,6 +5343,7 @@ def test_update_security_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_security_settings_rest_bad_request( @@ -5354,10 +5428,14 @@ def test_list_security_settings_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "post_list_security_settings" ) as post, mock.patch.object( + transports.SecuritySettingsServiceRestInterceptor, + "post_list_security_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "pre_list_security_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = security_settings.ListSecuritySettingsRequest.pb( security_settings.ListSecuritySettingsRequest() ) @@ -5383,6 +5461,10 @@ def test_list_security_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = security_settings.ListSecuritySettingsResponse() + post_with_metadata.return_value = ( + security_settings.ListSecuritySettingsResponse(), + metadata, + ) client.list_security_settings( request, @@ -5394,6 +5476,7 @@ def test_list_security_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_security_settings_rest_bad_request( diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_session_entity_types.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_session_entity_types.py index 904e42c1e1b6..2b77743432e1 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_session_entity_types.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_session_entity_types.py @@ -67,6 +67,13 @@ from google.cloud.dialogflowcx_v3.types import entity_type from google.cloud.dialogflowcx_v3.types import session_entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -338,6 +345,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionEntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionEntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4589,10 +4639,14 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_list_session_entity_types" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_list_session_entity_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_list_session_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_entity_type.ListSessionEntityTypesRequest.pb( session_entity_type.ListSessionEntityTypesRequest() ) @@ -4618,6 +4672,10 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_entity_type.ListSessionEntityTypesResponse() + post_with_metadata.return_value = ( + session_entity_type.ListSessionEntityTypesResponse(), + metadata, + ) client.list_session_entity_types( request, @@ -4629,6 +4687,7 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_session_entity_type_rest_bad_request( @@ -4722,10 +4781,14 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_get_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_get_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_get_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_entity_type.GetSessionEntityTypeRequest.pb( session_entity_type.GetSessionEntityTypeRequest() ) @@ -4751,6 +4814,10 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + session_entity_type.SessionEntityType(), + metadata, + ) client.get_session_entity_type( request, @@ -4762,6 +4829,7 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_session_entity_type_rest_bad_request( @@ -4931,10 +4999,14 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_create_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_create_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_create_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_session_entity_type.CreateSessionEntityTypeRequest.pb( gcdc_session_entity_type.CreateSessionEntityTypeRequest() ) @@ -4960,6 +5032,10 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + gcdc_session_entity_type.SessionEntityType(), + metadata, + ) client.create_session_entity_type( request, @@ -4971,6 +5047,7 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_session_entity_type_rest_bad_request( @@ -5144,10 +5221,14 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_update_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_update_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_update_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_session_entity_type.UpdateSessionEntityTypeRequest.pb( gcdc_session_entity_type.UpdateSessionEntityTypeRequest() ) @@ -5173,6 +5254,10 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + gcdc_session_entity_type.SessionEntityType(), + metadata, + ) client.update_session_entity_type( request, @@ -5184,6 +5269,7 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_session_entity_type_rest_bad_request( diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_sessions.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_sessions.py index 20647d02f39b..631ab308b1f8 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_sessions.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_sessions.py @@ -72,6 +72,13 @@ session_entity_type, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -302,6 +309,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3481,10 +3531,13 @@ def test_detect_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_detect_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_detect_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_detect_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.DetectIntentRequest.pb(session.DetectIntentRequest()) transcode.return_value = { "method": "post", @@ -3508,6 +3561,7 @@ def test_detect_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.DetectIntentResponse() + post_with_metadata.return_value = session.DetectIntentResponse(), metadata client.detect_intent( request, @@ -3519,6 +3573,7 @@ def test_detect_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_server_streaming_detect_intent_rest_bad_request( @@ -3615,10 +3670,14 @@ def test_server_streaming_detect_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_server_streaming_detect_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, + "post_server_streaming_detect_intent_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_server_streaming_detect_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.DetectIntentRequest.pb(session.DetectIntentRequest()) transcode.return_value = { "method": "post", @@ -3642,6 +3701,7 @@ def test_server_streaming_detect_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.DetectIntentResponse() + post_with_metadata.return_value = session.DetectIntentResponse(), metadata client.server_streaming_detect_intent( request, @@ -3653,6 +3713,7 @@ def test_server_streaming_detect_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_streaming_detect_intent_rest_error(): @@ -3748,10 +3809,13 @@ def test_match_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_match_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_match_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_match_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.MatchIntentRequest.pb(session.MatchIntentRequest()) transcode.return_value = { "method": "post", @@ -3775,6 +3839,7 @@ def test_match_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.MatchIntentResponse() + post_with_metadata.return_value = session.MatchIntentResponse(), metadata client.match_intent( request, @@ -3786,6 +3851,7 @@ def test_match_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fulfill_intent_rest_bad_request(request_type=session.FulfillIntentRequest): @@ -3876,10 +3942,13 @@ def test_fulfill_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_fulfill_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_fulfill_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_fulfill_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.FulfillIntentRequest.pb(session.FulfillIntentRequest()) transcode.return_value = { "method": "post", @@ -3903,6 +3972,7 @@ def test_fulfill_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.FulfillIntentResponse() + post_with_metadata.return_value = session.FulfillIntentResponse(), metadata client.fulfill_intent( request, @@ -3914,6 +3984,7 @@ def test_fulfill_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_submit_answer_feedback_rest_bad_request( @@ -4002,10 +4073,13 @@ def test_submit_answer_feedback_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_submit_answer_feedback" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_submit_answer_feedback_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_submit_answer_feedback" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.SubmitAnswerFeedbackRequest.pb( session.SubmitAnswerFeedbackRequest() ) @@ -4029,6 +4103,7 @@ def test_submit_answer_feedback_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.AnswerFeedback() + post_with_metadata.return_value = session.AnswerFeedback(), metadata client.submit_answer_feedback( request, @@ -4040,6 +4115,7 @@ def test_submit_answer_feedback_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): 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 e073f1ac6722..be283d09ced4 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 @@ -89,6 +89,13 @@ from google.cloud.dialogflowcx_v3.types import test_case from google.cloud.dialogflowcx_v3.types import test_case as gcdc_test_case +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -322,6 +329,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = TestCasesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = TestCasesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -8006,10 +8056,13 @@ def test_list_test_cases_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_list_test_cases" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_list_test_cases_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_list_test_cases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.ListTestCasesRequest.pb(test_case.ListTestCasesRequest()) transcode.return_value = { "method": "post", @@ -8033,6 +8086,7 @@ def test_list_test_cases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.ListTestCasesResponse() + post_with_metadata.return_value = test_case.ListTestCasesResponse(), metadata client.list_test_cases( request, @@ -8044,6 +8098,7 @@ def test_list_test_cases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_delete_test_cases_rest_bad_request( @@ -8241,10 +8296,13 @@ def test_get_test_case_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_get_test_case" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_get_test_case_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_get_test_case" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.GetTestCaseRequest.pb(test_case.GetTestCaseRequest()) transcode.return_value = { "method": "post", @@ -8266,6 +8324,7 @@ def test_get_test_case_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.TestCase() + post_with_metadata.return_value = test_case.TestCase(), metadata client.get_test_case( request, @@ -8277,6 +8336,7 @@ def test_get_test_case_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_test_case_rest_bad_request( @@ -8684,10 +8744,13 @@ def test_create_test_case_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_create_test_case" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_create_test_case_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_create_test_case" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_test_case.CreateTestCaseRequest.pb( gcdc_test_case.CreateTestCaseRequest() ) @@ -8711,6 +8774,7 @@ def test_create_test_case_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_test_case.TestCase() + post_with_metadata.return_value = gcdc_test_case.TestCase(), metadata client.create_test_case( request, @@ -8722,6 +8786,7 @@ def test_create_test_case_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_test_case_rest_bad_request( @@ -9137,10 +9202,13 @@ def test_update_test_case_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_update_test_case" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_update_test_case_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_update_test_case" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_test_case.UpdateTestCaseRequest.pb( gcdc_test_case.UpdateTestCaseRequest() ) @@ -9164,6 +9232,7 @@ def test_update_test_case_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_test_case.TestCase() + post_with_metadata.return_value = gcdc_test_case.TestCase(), metadata client.update_test_case( request, @@ -9175,6 +9244,7 @@ def test_update_test_case_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_run_test_case_rest_bad_request(request_type=test_case.RunTestCaseRequest): @@ -9255,10 +9325,13 @@ def test_run_test_case_rest_interceptors(null_interceptor): ), mock.patch.object( transports.TestCasesRestInterceptor, "post_run_test_case" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_run_test_case_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_run_test_case" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.RunTestCaseRequest.pb(test_case.RunTestCaseRequest()) transcode.return_value = { "method": "post", @@ -9280,6 +9353,7 @@ def test_run_test_case_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.run_test_case( request, @@ -9291,6 +9365,7 @@ def test_run_test_case_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_run_test_cases_rest_bad_request( @@ -9369,10 +9444,13 @@ def test_batch_run_test_cases_rest_interceptors(null_interceptor): ), mock.patch.object( transports.TestCasesRestInterceptor, "post_batch_run_test_cases" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_batch_run_test_cases_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_batch_run_test_cases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.BatchRunTestCasesRequest.pb( test_case.BatchRunTestCasesRequest() ) @@ -9396,6 +9474,7 @@ def test_batch_run_test_cases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_run_test_cases( request, @@ -9407,6 +9486,7 @@ def test_batch_run_test_cases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_calculate_coverage_rest_bad_request( @@ -9489,10 +9569,13 @@ def test_calculate_coverage_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_calculate_coverage" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_calculate_coverage_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_calculate_coverage" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.CalculateCoverageRequest.pb( test_case.CalculateCoverageRequest() ) @@ -9518,6 +9601,10 @@ def test_calculate_coverage_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.CalculateCoverageResponse() + post_with_metadata.return_value = ( + test_case.CalculateCoverageResponse(), + metadata, + ) client.calculate_coverage( request, @@ -9529,6 +9616,7 @@ def test_calculate_coverage_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_test_cases_rest_bad_request( @@ -9607,10 +9695,13 @@ def test_import_test_cases_rest_interceptors(null_interceptor): ), mock.patch.object( transports.TestCasesRestInterceptor, "post_import_test_cases" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_import_test_cases_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_import_test_cases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.ImportTestCasesRequest.pb( test_case.ImportTestCasesRequest() ) @@ -9634,6 +9725,7 @@ def test_import_test_cases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_test_cases( request, @@ -9645,6 +9737,7 @@ def test_import_test_cases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_test_cases_rest_bad_request( @@ -9723,10 +9816,13 @@ def test_export_test_cases_rest_interceptors(null_interceptor): ), mock.patch.object( transports.TestCasesRestInterceptor, "post_export_test_cases" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_export_test_cases_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_export_test_cases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.ExportTestCasesRequest.pb( test_case.ExportTestCasesRequest() ) @@ -9750,6 +9846,7 @@ def test_export_test_cases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_test_cases( request, @@ -9761,6 +9858,7 @@ def test_export_test_cases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_test_case_results_rest_bad_request( @@ -9847,10 +9945,13 @@ def test_list_test_case_results_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_list_test_case_results" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_list_test_case_results_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_list_test_case_results" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.ListTestCaseResultsRequest.pb( test_case.ListTestCaseResultsRequest() ) @@ -9876,6 +9977,10 @@ def test_list_test_case_results_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.ListTestCaseResultsResponse() + post_with_metadata.return_value = ( + test_case.ListTestCaseResultsResponse(), + metadata, + ) client.list_test_case_results( request, @@ -9887,6 +9992,7 @@ def test_list_test_case_results_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_test_case_result_rest_bad_request( @@ -9977,10 +10083,13 @@ def test_get_test_case_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_get_test_case_result" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_get_test_case_result_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_get_test_case_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.GetTestCaseResultRequest.pb( test_case.GetTestCaseResultRequest() ) @@ -10004,6 +10113,7 @@ def test_get_test_case_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.TestCaseResult() + post_with_metadata.return_value = test_case.TestCaseResult(), metadata client.get_test_case_result( request, @@ -10015,6 +10125,7 @@ def test_get_test_case_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): 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 57bb7a0d3e07..74cb07719332 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 @@ -75,6 +75,13 @@ ) from google.cloud.dialogflowcx_v3.types import transition_route_group +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -350,6 +357,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = TransitionRouteGroupsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = TransitionRouteGroupsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4642,11 +4692,15 @@ def test_list_transition_route_groups_rest_interceptors(null_interceptor): transports.TransitionRouteGroupsRestInterceptor, "post_list_transition_route_groups", ) as post, mock.patch.object( + transports.TransitionRouteGroupsRestInterceptor, + "post_list_transition_route_groups_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.TransitionRouteGroupsRestInterceptor, "pre_list_transition_route_groups", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = transition_route_group.ListTransitionRouteGroupsRequest.pb( transition_route_group.ListTransitionRouteGroupsRequest() ) @@ -4672,6 +4726,10 @@ def test_list_transition_route_groups_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = transition_route_group.ListTransitionRouteGroupsResponse() + post_with_metadata.return_value = ( + transition_route_group.ListTransitionRouteGroupsResponse(), + metadata, + ) client.list_transition_route_groups( request, @@ -4683,6 +4741,7 @@ def test_list_transition_route_groups_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_transition_route_group_rest_bad_request( @@ -4774,11 +4833,15 @@ def test_get_transition_route_group_rest_interceptors(null_interceptor): transports.TransitionRouteGroupsRestInterceptor, "post_get_transition_route_group", ) as post, mock.patch.object( + transports.TransitionRouteGroupsRestInterceptor, + "post_get_transition_route_group_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.TransitionRouteGroupsRestInterceptor, "pre_get_transition_route_group", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = transition_route_group.GetTransitionRouteGroupRequest.pb( transition_route_group.GetTransitionRouteGroupRequest() ) @@ -4804,6 +4867,10 @@ def test_get_transition_route_group_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = transition_route_group.TransitionRouteGroup() + post_with_metadata.return_value = ( + transition_route_group.TransitionRouteGroup(), + metadata, + ) client.get_transition_route_group( request, @@ -4815,6 +4882,7 @@ def test_get_transition_route_group_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_transition_route_group_rest_bad_request( @@ -5081,11 +5149,15 @@ def test_create_transition_route_group_rest_interceptors(null_interceptor): transports.TransitionRouteGroupsRestInterceptor, "post_create_transition_route_group", ) as post, mock.patch.object( + transports.TransitionRouteGroupsRestInterceptor, + "post_create_transition_route_group_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.TransitionRouteGroupsRestInterceptor, "pre_create_transition_route_group", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_transition_route_group.CreateTransitionRouteGroupRequest.pb( gcdc_transition_route_group.CreateTransitionRouteGroupRequest() ) @@ -5111,6 +5183,10 @@ def test_create_transition_route_group_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_transition_route_group.TransitionRouteGroup() + post_with_metadata.return_value = ( + gcdc_transition_route_group.TransitionRouteGroup(), + metadata, + ) client.create_transition_route_group( request, @@ -5122,6 +5198,7 @@ def test_create_transition_route_group_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_transition_route_group_rest_bad_request( @@ -5392,11 +5469,15 @@ def test_update_transition_route_group_rest_interceptors(null_interceptor): transports.TransitionRouteGroupsRestInterceptor, "post_update_transition_route_group", ) as post, mock.patch.object( + transports.TransitionRouteGroupsRestInterceptor, + "post_update_transition_route_group_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.TransitionRouteGroupsRestInterceptor, "pre_update_transition_route_group", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_transition_route_group.UpdateTransitionRouteGroupRequest.pb( gcdc_transition_route_group.UpdateTransitionRouteGroupRequest() ) @@ -5422,6 +5503,10 @@ def test_update_transition_route_group_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_transition_route_group.TransitionRouteGroup() + post_with_metadata.return_value = ( + gcdc_transition_route_group.TransitionRouteGroup(), + metadata, + ) client.update_transition_route_group( request, @@ -5433,6 +5518,7 @@ def test_update_transition_route_group_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_transition_route_group_rest_bad_request( diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_versions.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_versions.py index 21f6ee5dd0b8..b783a10a120f 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_versions.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_versions.py @@ -77,6 +77,13 @@ from google.cloud.dialogflowcx_v3.types import version from google.cloud.dialogflowcx_v3.types import version as gcdc_version +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -307,6 +314,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = VersionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = VersionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5427,10 +5477,13 @@ def test_list_versions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_list_versions" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_list_versions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_list_versions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.ListVersionsRequest.pb(version.ListVersionsRequest()) transcode.return_value = { "method": "post", @@ -5454,6 +5507,7 @@ def test_list_versions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.ListVersionsResponse() + post_with_metadata.return_value = version.ListVersionsResponse(), metadata client.list_versions( request, @@ -5465,6 +5519,7 @@ def test_list_versions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_version_rest_bad_request(request_type=version.GetVersionRequest): @@ -5555,10 +5610,13 @@ def test_get_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_get_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_get_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_get_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.GetVersionRequest.pb(version.GetVersionRequest()) transcode.return_value = { "method": "post", @@ -5580,6 +5638,7 @@ def test_get_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.Version() + post_with_metadata.return_value = version.Version(), metadata client.get_version( request, @@ -5591,6 +5650,7 @@ def test_get_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_version_rest_bad_request( @@ -5752,10 +5812,13 @@ def test_create_version_rest_interceptors(null_interceptor): ), mock.patch.object( transports.VersionsRestInterceptor, "post_create_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_create_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_create_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_version.CreateVersionRequest.pb( gcdc_version.CreateVersionRequest() ) @@ -5779,6 +5842,7 @@ def test_create_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_version( request, @@ -5790,6 +5854,7 @@ def test_create_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_version_rest_bad_request( @@ -5965,10 +6030,13 @@ def test_update_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_update_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_update_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_update_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_version.UpdateVersionRequest.pb( gcdc_version.UpdateVersionRequest() ) @@ -5992,6 +6060,7 @@ def test_update_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_version.Version() + post_with_metadata.return_value = gcdc_version.Version(), metadata client.update_version( request, @@ -6003,6 +6072,7 @@ def test_update_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_version_rest_bad_request(request_type=version.DeleteVersionRequest): @@ -6190,10 +6260,13 @@ def test_load_version_rest_interceptors(null_interceptor): ), mock.patch.object( transports.VersionsRestInterceptor, "post_load_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_load_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_load_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.LoadVersionRequest.pb(version.LoadVersionRequest()) transcode.return_value = { "method": "post", @@ -6215,6 +6288,7 @@ def test_load_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.load_version( request, @@ -6226,6 +6300,7 @@ def test_load_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_compare_versions_rest_bad_request(request_type=version.CompareVersionsRequest): @@ -6312,10 +6387,13 @@ def test_compare_versions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_compare_versions" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_compare_versions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_compare_versions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.CompareVersionsRequest.pb(version.CompareVersionsRequest()) transcode.return_value = { "method": "post", @@ -6339,6 +6417,7 @@ def test_compare_versions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.CompareVersionsResponse() + post_with_metadata.return_value = version.CompareVersionsResponse(), metadata client.compare_versions( request, @@ -6350,6 +6429,7 @@ def test_compare_versions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_webhooks.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_webhooks.py index 0773790513b0..807133723757 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_webhooks.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3/test_webhooks.py @@ -65,6 +65,13 @@ from google.cloud.dialogflowcx_v3.types import webhook from google.cloud.dialogflowcx_v3.types import webhook as gcdc_webhook +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -295,6 +302,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = WebhooksClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = WebhooksClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4270,10 +4320,13 @@ def test_list_webhooks_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.WebhooksRestInterceptor, "post_list_webhooks" ) as post, mock.patch.object( + transports.WebhooksRestInterceptor, "post_list_webhooks_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.WebhooksRestInterceptor, "pre_list_webhooks" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = webhook.ListWebhooksRequest.pb(webhook.ListWebhooksRequest()) transcode.return_value = { "method": "post", @@ -4297,6 +4350,7 @@ def test_list_webhooks_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = webhook.ListWebhooksResponse() + post_with_metadata.return_value = webhook.ListWebhooksResponse(), metadata client.list_webhooks( request, @@ -4308,6 +4362,7 @@ def test_list_webhooks_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_webhook_rest_bad_request(request_type=webhook.GetWebhookRequest): @@ -4396,10 +4451,13 @@ def test_get_webhook_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.WebhooksRestInterceptor, "post_get_webhook" ) as post, mock.patch.object( + transports.WebhooksRestInterceptor, "post_get_webhook_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.WebhooksRestInterceptor, "pre_get_webhook" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = webhook.GetWebhookRequest.pb(webhook.GetWebhookRequest()) transcode.return_value = { "method": "post", @@ -4421,6 +4479,7 @@ def test_get_webhook_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = webhook.Webhook() + post_with_metadata.return_value = webhook.Webhook(), metadata client.get_webhook( request, @@ -4432,6 +4491,7 @@ def test_get_webhook_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_webhook_rest_bad_request( @@ -4610,10 +4670,13 @@ def test_create_webhook_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.WebhooksRestInterceptor, "post_create_webhook" ) as post, mock.patch.object( + transports.WebhooksRestInterceptor, "post_create_webhook_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.WebhooksRestInterceptor, "pre_create_webhook" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_webhook.CreateWebhookRequest.pb( gcdc_webhook.CreateWebhookRequest() ) @@ -4637,6 +4700,7 @@ def test_create_webhook_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_webhook.Webhook() + post_with_metadata.return_value = gcdc_webhook.Webhook(), metadata client.create_webhook( request, @@ -4648,6 +4712,7 @@ def test_create_webhook_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_webhook_rest_bad_request( @@ -4834,10 +4899,13 @@ def test_update_webhook_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.WebhooksRestInterceptor, "post_update_webhook" ) as post, mock.patch.object( + transports.WebhooksRestInterceptor, "post_update_webhook_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.WebhooksRestInterceptor, "pre_update_webhook" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_webhook.UpdateWebhookRequest.pb( gcdc_webhook.UpdateWebhookRequest() ) @@ -4861,6 +4929,7 @@ def test_update_webhook_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_webhook.Webhook() + post_with_metadata.return_value = gcdc_webhook.Webhook(), metadata client.update_webhook( request, @@ -4872,6 +4941,7 @@ def test_update_webhook_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_webhook_rest_bad_request(request_type=webhook.DeleteWebhookRequest): 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 c1eaf397da79..e73021a6adb2 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 @@ -88,6 +88,13 @@ from google.cloud.dialogflowcx_v3beta1.types import generative_settings from google.cloud.dialogflowcx_v3beta1.types import safety_settings +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -310,6 +317,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AgentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AgentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7443,10 +7493,13 @@ def test_list_agents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_list_agents" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_list_agents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_list_agents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ListAgentsRequest.pb(agent.ListAgentsRequest()) transcode.return_value = { "method": "post", @@ -7468,6 +7521,7 @@ def test_list_agents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.ListAgentsResponse() + post_with_metadata.return_value = agent.ListAgentsResponse(), metadata client.list_agents( request, @@ -7479,6 +7533,7 @@ def test_list_agents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_agent_rest_bad_request(request_type=agent.GetAgentRequest): @@ -7582,10 +7637,13 @@ def test_get_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_get_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetAgentRequest.pb(agent.GetAgentRequest()) transcode.return_value = { "method": "post", @@ -7607,6 +7665,7 @@ def test_get_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.Agent() + post_with_metadata.return_value = agent.Agent(), metadata client.get_agent( request, @@ -7618,6 +7677,7 @@ def test_get_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_agent_rest_bad_request(request_type=gcdc_agent.CreateAgentRequest): @@ -7851,10 +7911,13 @@ def test_create_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_create_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_create_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_create_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_agent.CreateAgentRequest.pb(gcdc_agent.CreateAgentRequest()) transcode.return_value = { "method": "post", @@ -7876,6 +7939,7 @@ def test_create_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_agent.Agent() + post_with_metadata.return_value = gcdc_agent.Agent(), metadata client.create_agent( request, @@ -7887,6 +7951,7 @@ def test_create_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_agent_rest_bad_request(request_type=gcdc_agent.UpdateAgentRequest): @@ -8124,10 +8189,13 @@ def test_update_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_update_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_update_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_update_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_agent.UpdateAgentRequest.pb(gcdc_agent.UpdateAgentRequest()) transcode.return_value = { "method": "post", @@ -8149,6 +8217,7 @@ def test_update_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_agent.Agent() + post_with_metadata.return_value = gcdc_agent.Agent(), metadata client.update_agent( request, @@ -8160,6 +8229,7 @@ def test_update_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_agent_rest_bad_request(request_type=agent.DeleteAgentRequest): @@ -8339,10 +8409,13 @@ def test_export_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_export_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_export_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_export_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ExportAgentRequest.pb(agent.ExportAgentRequest()) transcode.return_value = { "method": "post", @@ -8364,6 +8437,7 @@ def test_export_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_agent( request, @@ -8375,6 +8449,7 @@ def test_export_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_restore_agent_rest_bad_request(request_type=agent.RestoreAgentRequest): @@ -8451,10 +8526,13 @@ def test_restore_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_restore_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_restore_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_restore_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.RestoreAgentRequest.pb(agent.RestoreAgentRequest()) transcode.return_value = { "method": "post", @@ -8476,6 +8554,7 @@ def test_restore_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.restore_agent( request, @@ -8487,6 +8566,7 @@ def test_restore_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_validate_agent_rest_bad_request(request_type=agent.ValidateAgentRequest): @@ -8567,10 +8647,13 @@ def test_validate_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_validate_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_validate_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_validate_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ValidateAgentRequest.pb(agent.ValidateAgentRequest()) transcode.return_value = { "method": "post", @@ -8594,6 +8677,7 @@ def test_validate_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.AgentValidationResult() + post_with_metadata.return_value = agent.AgentValidationResult(), metadata client.validate_agent( request, @@ -8605,6 +8689,7 @@ def test_validate_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_agent_validation_result_rest_bad_request( @@ -8691,10 +8776,14 @@ def test_get_agent_validation_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_agent_validation_result" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, + "post_get_agent_validation_result_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_agent_validation_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetAgentValidationResultRequest.pb( agent.GetAgentValidationResultRequest() ) @@ -8720,6 +8809,7 @@ def test_get_agent_validation_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.AgentValidationResult() + post_with_metadata.return_value = agent.AgentValidationResult(), metadata client.get_agent_validation_result( request, @@ -8731,6 +8821,7 @@ def test_get_agent_validation_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_generative_settings_rest_bad_request( @@ -8819,10 +8910,13 @@ def test_get_generative_settings_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_generative_settings" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_get_generative_settings_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_generative_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetGenerativeSettingsRequest.pb( agent.GetGenerativeSettingsRequest() ) @@ -8848,6 +8942,10 @@ def test_get_generative_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generative_settings.GenerativeSettings() + post_with_metadata.return_value = ( + generative_settings.GenerativeSettings(), + metadata, + ) client.get_generative_settings( request, @@ -8859,6 +8957,7 @@ def test_get_generative_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_generative_settings_rest_bad_request( @@ -9052,10 +9151,14 @@ def test_update_generative_settings_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_update_generative_settings" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, + "post_update_generative_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_update_generative_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.UpdateGenerativeSettingsRequest.pb( agent.UpdateGenerativeSettingsRequest() ) @@ -9081,6 +9184,10 @@ def test_update_generative_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_generative_settings.GenerativeSettings() + post_with_metadata.return_value = ( + gcdc_generative_settings.GenerativeSettings(), + metadata, + ) client.update_generative_settings( request, @@ -9092,6 +9199,7 @@ def test_update_generative_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_changelogs.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_changelogs.py index aa2e69efc579..0ba413c8d85f 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_changelogs.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_changelogs.py @@ -63,6 +63,13 @@ ) from google.cloud.dialogflowcx_v3beta1.types import changelog +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -298,6 +305,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ChangelogsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ChangelogsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2632,10 +2682,13 @@ def test_list_changelogs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ChangelogsRestInterceptor, "post_list_changelogs" ) as post, mock.patch.object( + transports.ChangelogsRestInterceptor, "post_list_changelogs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ChangelogsRestInterceptor, "pre_list_changelogs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = changelog.ListChangelogsRequest.pb( changelog.ListChangelogsRequest() ) @@ -2661,6 +2714,7 @@ def test_list_changelogs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = changelog.ListChangelogsResponse() + post_with_metadata.return_value = changelog.ListChangelogsResponse(), metadata client.list_changelogs( request, @@ -2672,6 +2726,7 @@ def test_list_changelogs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_changelog_rest_bad_request(request_type=changelog.GetChangelogRequest): @@ -2770,10 +2825,13 @@ def test_get_changelog_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ChangelogsRestInterceptor, "post_get_changelog" ) as post, mock.patch.object( + transports.ChangelogsRestInterceptor, "post_get_changelog_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ChangelogsRestInterceptor, "pre_get_changelog" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = changelog.GetChangelogRequest.pb(changelog.GetChangelogRequest()) transcode.return_value = { "method": "post", @@ -2795,6 +2853,7 @@ def test_get_changelog_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = changelog.Changelog() + post_with_metadata.return_value = changelog.Changelog(), metadata client.get_changelog( request, @@ -2806,6 +2865,7 @@ def test_get_changelog_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_conversation_history.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_conversation_history.py index e8fefb13e582..c1e64b724c7b 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_conversation_history.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_conversation_history.py @@ -70,6 +70,13 @@ page, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationHistoryClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationHistoryClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3329,10 +3379,14 @@ def test_list_conversations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationHistoryRestInterceptor, "post_list_conversations" ) as post, mock.patch.object( + transports.ConversationHistoryRestInterceptor, + "post_list_conversations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationHistoryRestInterceptor, "pre_list_conversations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_history.ListConversationsRequest.pb( conversation_history.ListConversationsRequest() ) @@ -3358,6 +3412,10 @@ def test_list_conversations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_history.ListConversationsResponse() + post_with_metadata.return_value = ( + conversation_history.ListConversationsResponse(), + metadata, + ) client.list_conversations( request, @@ -3369,6 +3427,7 @@ def test_list_conversations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_rest_bad_request( @@ -3461,10 +3520,14 @@ def test_get_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationHistoryRestInterceptor, "post_get_conversation" ) as post, mock.patch.object( + transports.ConversationHistoryRestInterceptor, + "post_get_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationHistoryRestInterceptor, "pre_get_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_history.GetConversationRequest.pb( conversation_history.GetConversationRequest() ) @@ -3490,6 +3553,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_history.Conversation() + post_with_metadata.return_value = conversation_history.Conversation(), metadata client.get_conversation( request, @@ -3501,6 +3565,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_conversation_rest_bad_request( diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_deployments.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_deployments.py index b21e561e6c08..fe03ea53f1da 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_deployments.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_deployments.py @@ -63,6 +63,13 @@ ) from google.cloud.dialogflowcx_v3beta1.types import deployment +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -302,6 +309,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DeploymentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DeploymentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2634,10 +2684,13 @@ def test_list_deployments_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeploymentsRestInterceptor, "post_list_deployments" ) as post, mock.patch.object( + transports.DeploymentsRestInterceptor, "post_list_deployments_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DeploymentsRestInterceptor, "pre_list_deployments" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = deployment.ListDeploymentsRequest.pb( deployment.ListDeploymentsRequest() ) @@ -2663,6 +2716,7 @@ def test_list_deployments_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = deployment.ListDeploymentsResponse() + post_with_metadata.return_value = deployment.ListDeploymentsResponse(), metadata client.list_deployments( request, @@ -2674,6 +2728,7 @@ def test_list_deployments_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_deployment_rest_bad_request(request_type=deployment.GetDeploymentRequest): @@ -2764,10 +2819,13 @@ def test_get_deployment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DeploymentsRestInterceptor, "post_get_deployment" ) as post, mock.patch.object( + transports.DeploymentsRestInterceptor, "post_get_deployment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DeploymentsRestInterceptor, "pre_get_deployment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = deployment.GetDeploymentRequest.pb( deployment.GetDeploymentRequest() ) @@ -2791,6 +2849,7 @@ def test_get_deployment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = deployment.Deployment() + post_with_metadata.return_value = deployment.Deployment(), metadata client.get_deployment( request, @@ -2802,6 +2861,7 @@ def test_get_deployment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_entity_types.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_entity_types.py index 85d85f8be9f6..72aafda702a9 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_entity_types.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_entity_types.py @@ -74,6 +74,13 @@ from google.cloud.dialogflowcx_v3beta1.types import entity_type from google.cloud.dialogflowcx_v3beta1.types import inline +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -313,6 +320,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5431,10 +5481,13 @@ def test_get_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_get_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_get_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_get_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.GetEntityTypeRequest.pb( entity_type.GetEntityTypeRequest() ) @@ -5458,6 +5511,7 @@ def test_get_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = entity_type.EntityType() + post_with_metadata.return_value = entity_type.EntityType(), metadata client.get_entity_type( request, @@ -5469,6 +5523,7 @@ def test_get_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_entity_type_rest_bad_request( @@ -5645,10 +5700,13 @@ def test_create_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_create_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_create_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_create_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_entity_type.CreateEntityTypeRequest.pb( gcdc_entity_type.CreateEntityTypeRequest() ) @@ -5674,6 +5732,7 @@ def test_create_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_entity_type.EntityType() + post_with_metadata.return_value = gcdc_entity_type.EntityType(), metadata client.create_entity_type( request, @@ -5685,6 +5744,7 @@ def test_create_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_entity_type_rest_bad_request( @@ -5869,10 +5929,13 @@ def test_update_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_update_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_update_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_update_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_entity_type.UpdateEntityTypeRequest.pb( gcdc_entity_type.UpdateEntityTypeRequest() ) @@ -5898,6 +5961,7 @@ def test_update_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_entity_type.EntityType() + post_with_metadata.return_value = gcdc_entity_type.EntityType(), metadata client.update_entity_type( request, @@ -5909,6 +5973,7 @@ def test_update_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_entity_type_rest_bad_request( @@ -6106,10 +6171,13 @@ def test_list_entity_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_list_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_list_entity_types_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_list_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.ListEntityTypesRequest.pb( entity_type.ListEntityTypesRequest() ) @@ -6135,6 +6203,10 @@ def test_list_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = entity_type.ListEntityTypesResponse() + post_with_metadata.return_value = ( + entity_type.ListEntityTypesResponse(), + metadata, + ) client.list_entity_types( request, @@ -6146,6 +6218,7 @@ def test_list_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_entity_types_rest_bad_request( @@ -6226,10 +6299,13 @@ def test_export_entity_types_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_export_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_export_entity_types_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_export_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.ExportEntityTypesRequest.pb( entity_type.ExportEntityTypesRequest() ) @@ -6253,6 +6329,7 @@ def test_export_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_entity_types( request, @@ -6264,6 +6341,7 @@ def test_export_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_entity_types_rest_bad_request( @@ -6344,10 +6422,13 @@ def test_import_entity_types_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_import_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_import_entity_types_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_import_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.ImportEntityTypesRequest.pb( entity_type.ImportEntityTypesRequest() ) @@ -6371,6 +6452,7 @@ def test_import_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_entity_types( request, @@ -6382,6 +6464,7 @@ def test_import_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_environments.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_environments.py index e8c1cb3915bb..228e3adc4921 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_environments.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_environments.py @@ -77,6 +77,13 @@ from google.cloud.dialogflowcx_v3beta1.types import environment from google.cloud.dialogflowcx_v3beta1.types import webhook +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -320,6 +327,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EnvironmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EnvironmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7023,10 +7073,13 @@ def test_list_environments_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_list_environments" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_list_environments_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_list_environments" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.ListEnvironmentsRequest.pb( environment.ListEnvironmentsRequest() ) @@ -7052,6 +7105,10 @@ def test_list_environments_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.ListEnvironmentsResponse() + post_with_metadata.return_value = ( + environment.ListEnvironmentsResponse(), + metadata, + ) client.list_environments( request, @@ -7063,6 +7120,7 @@ def test_list_environments_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_environment_rest_bad_request( @@ -7155,10 +7213,13 @@ def test_get_environment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_get_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_get_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_get_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.GetEnvironmentRequest.pb( environment.GetEnvironmentRequest() ) @@ -7182,6 +7243,7 @@ def test_get_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.Environment() + post_with_metadata.return_value = environment.Environment(), metadata client.get_environment( request, @@ -7193,6 +7255,7 @@ def test_get_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_environment_rest_bad_request( @@ -7387,10 +7450,13 @@ def test_create_environment_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EnvironmentsRestInterceptor, "post_create_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_create_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_create_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_environment.CreateEnvironmentRequest.pb( gcdc_environment.CreateEnvironmentRequest() ) @@ -7414,6 +7480,7 @@ def test_create_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_environment( request, @@ -7425,6 +7492,7 @@ def test_create_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_environment_rest_bad_request( @@ -7627,10 +7695,13 @@ def test_update_environment_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EnvironmentsRestInterceptor, "post_update_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_update_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_update_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_environment.UpdateEnvironmentRequest.pb( gcdc_environment.UpdateEnvironmentRequest() ) @@ -7654,6 +7725,7 @@ def test_update_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_environment( request, @@ -7665,6 +7737,7 @@ def test_update_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_environment_rest_bad_request( @@ -7866,10 +7939,14 @@ def test_lookup_environment_history_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_lookup_environment_history" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, + "post_lookup_environment_history_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_lookup_environment_history" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.LookupEnvironmentHistoryRequest.pb( environment.LookupEnvironmentHistoryRequest() ) @@ -7895,6 +7972,10 @@ def test_lookup_environment_history_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.LookupEnvironmentHistoryResponse() + post_with_metadata.return_value = ( + environment.LookupEnvironmentHistoryResponse(), + metadata, + ) client.lookup_environment_history( request, @@ -7906,6 +7987,7 @@ def test_lookup_environment_history_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_run_continuous_test_rest_bad_request( @@ -7990,10 +8072,13 @@ def test_run_continuous_test_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EnvironmentsRestInterceptor, "post_run_continuous_test" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_run_continuous_test_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_run_continuous_test" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.RunContinuousTestRequest.pb( environment.RunContinuousTestRequest() ) @@ -8017,6 +8102,7 @@ def test_run_continuous_test_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.run_continuous_test( request, @@ -8028,6 +8114,7 @@ def test_run_continuous_test_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_continuous_test_results_rest_bad_request( @@ -8116,10 +8203,14 @@ def test_list_continuous_test_results_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_list_continuous_test_results" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, + "post_list_continuous_test_results_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_list_continuous_test_results" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.ListContinuousTestResultsRequest.pb( environment.ListContinuousTestResultsRequest() ) @@ -8145,6 +8236,10 @@ def test_list_continuous_test_results_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.ListContinuousTestResultsResponse() + post_with_metadata.return_value = ( + environment.ListContinuousTestResultsResponse(), + metadata, + ) client.list_continuous_test_results( request, @@ -8156,6 +8251,7 @@ def test_list_continuous_test_results_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_deploy_flow_rest_bad_request(request_type=environment.DeployFlowRequest): @@ -8238,10 +8334,13 @@ def test_deploy_flow_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EnvironmentsRestInterceptor, "post_deploy_flow" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_deploy_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_deploy_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.DeployFlowRequest.pb(environment.DeployFlowRequest()) transcode.return_value = { "method": "post", @@ -8263,6 +8362,7 @@ def test_deploy_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.deploy_flow( request, @@ -8274,6 +8374,7 @@ def test_deploy_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_examples.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_examples.py index 6a32a0516de0..832a1d0ca7d6 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_examples.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_examples.py @@ -66,6 +66,13 @@ from google.cloud.dialogflowcx_v3beta1.types import example from google.cloud.dialogflowcx_v3beta1.types import example as gcdc_example +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -296,6 +303,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ExamplesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ExamplesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4449,10 +4499,13 @@ def test_create_example_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExamplesRestInterceptor, "post_create_example" ) as post, mock.patch.object( + transports.ExamplesRestInterceptor, "post_create_example_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExamplesRestInterceptor, "pre_create_example" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_example.CreateExampleRequest.pb( gcdc_example.CreateExampleRequest() ) @@ -4476,6 +4529,7 @@ def test_create_example_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_example.Example() + post_with_metadata.return_value = gcdc_example.Example(), metadata client.create_example( request, @@ -4487,6 +4541,7 @@ def test_create_example_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_example_rest_bad_request(request_type=example.DeleteExampleRequest): @@ -4678,10 +4733,13 @@ def test_list_examples_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExamplesRestInterceptor, "post_list_examples" ) as post, mock.patch.object( + transports.ExamplesRestInterceptor, "post_list_examples_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExamplesRestInterceptor, "pre_list_examples" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = example.ListExamplesRequest.pb(example.ListExamplesRequest()) transcode.return_value = { "method": "post", @@ -4705,6 +4763,7 @@ def test_list_examples_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = example.ListExamplesResponse() + post_with_metadata.return_value = example.ListExamplesResponse(), metadata client.list_examples( request, @@ -4716,6 +4775,7 @@ def test_list_examples_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_example_rest_bad_request(request_type=example.GetExampleRequest): @@ -4810,10 +4870,13 @@ def test_get_example_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExamplesRestInterceptor, "post_get_example" ) as post, mock.patch.object( + transports.ExamplesRestInterceptor, "post_get_example_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExamplesRestInterceptor, "pre_get_example" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = example.GetExampleRequest.pb(example.GetExampleRequest()) transcode.return_value = { "method": "post", @@ -4835,6 +4898,7 @@ def test_get_example_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = example.Example() + post_with_metadata.return_value = example.Example(), metadata client.get_example( request, @@ -4846,6 +4910,7 @@ def test_get_example_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_example_rest_bad_request( @@ -5055,10 +5120,13 @@ def test_update_example_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExamplesRestInterceptor, "post_update_example" ) as post, mock.patch.object( + transports.ExamplesRestInterceptor, "post_update_example_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExamplesRestInterceptor, "pre_update_example" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_example.UpdateExampleRequest.pb( gcdc_example.UpdateExampleRequest() ) @@ -5082,6 +5150,7 @@ def test_update_example_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_example.Example() + post_with_metadata.return_value = gcdc_example.Example(), metadata client.update_example( request, @@ -5093,6 +5162,7 @@ def test_update_example_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_experiments.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_experiments.py index aeb282ea4337..eb3c0083b93b 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_experiments.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_experiments.py @@ -66,6 +66,13 @@ from google.cloud.dialogflowcx_v3beta1.types import experiment as gcdc_experiment from google.cloud.dialogflowcx_v3beta1.types import experiment +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -305,6 +312,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ExperimentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ExperimentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5572,10 +5622,13 @@ def test_list_experiments_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_list_experiments" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_list_experiments_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_list_experiments" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = experiment.ListExperimentsRequest.pb( experiment.ListExperimentsRequest() ) @@ -5601,6 +5654,7 @@ def test_list_experiments_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = experiment.ListExperimentsResponse() + post_with_metadata.return_value = experiment.ListExperimentsResponse(), metadata client.list_experiments( request, @@ -5612,6 +5666,7 @@ def test_list_experiments_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_experiment_rest_bad_request(request_type=experiment.GetExperimentRequest): @@ -5706,10 +5761,13 @@ def test_get_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_get_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_get_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_get_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = experiment.GetExperimentRequest.pb( experiment.GetExperimentRequest() ) @@ -5733,6 +5791,7 @@ def test_get_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = experiment.Experiment() + post_with_metadata.return_value = experiment.Experiment(), metadata client.get_experiment( request, @@ -5744,6 +5803,7 @@ def test_get_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_experiment_rest_bad_request( @@ -5971,10 +6031,13 @@ def test_create_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_create_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_create_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_create_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_experiment.CreateExperimentRequest.pb( gcdc_experiment.CreateExperimentRequest() ) @@ -5998,6 +6061,7 @@ def test_create_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_experiment.Experiment() + post_with_metadata.return_value = gcdc_experiment.Experiment(), metadata client.create_experiment( request, @@ -6009,6 +6073,7 @@ def test_create_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_experiment_rest_bad_request( @@ -6240,10 +6305,13 @@ def test_update_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_update_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_update_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_update_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_experiment.UpdateExperimentRequest.pb( gcdc_experiment.UpdateExperimentRequest() ) @@ -6267,6 +6335,7 @@ def test_update_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_experiment.Experiment() + post_with_metadata.return_value = gcdc_experiment.Experiment(), metadata client.update_experiment( request, @@ -6278,6 +6347,7 @@ def test_update_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_experiment_rest_bad_request( @@ -6487,10 +6557,13 @@ def test_start_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_start_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_start_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_start_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = experiment.StartExperimentRequest.pb( experiment.StartExperimentRequest() ) @@ -6514,6 +6587,7 @@ def test_start_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = experiment.Experiment() + post_with_metadata.return_value = experiment.Experiment(), metadata client.start_experiment( request, @@ -6525,6 +6599,7 @@ def test_start_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_stop_experiment_rest_bad_request( @@ -6621,10 +6696,13 @@ def test_stop_experiment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ExperimentsRestInterceptor, "post_stop_experiment" ) as post, mock.patch.object( + transports.ExperimentsRestInterceptor, "post_stop_experiment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ExperimentsRestInterceptor, "pre_stop_experiment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = experiment.StopExperimentRequest.pb( experiment.StopExperimentRequest() ) @@ -6648,6 +6726,7 @@ def test_stop_experiment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = experiment.Experiment() + post_with_metadata.return_value = experiment.Experiment(), metadata client.stop_experiment( request, @@ -6659,6 +6738,7 @@ def test_stop_experiment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): 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 5d7d1efcfc08..cee6a7339dd4 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 @@ -90,6 +90,13 @@ from google.cloud.dialogflowcx_v3beta1.types import flow from google.cloud.dialogflowcx_v3beta1.types import flow as gcdc_flow +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -308,6 +315,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = FlowsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = FlowsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6909,10 +6959,13 @@ def test_create_flow_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_create_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_create_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_create_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_flow.CreateFlowRequest.pb(gcdc_flow.CreateFlowRequest()) transcode.return_value = { "method": "post", @@ -6934,6 +6987,7 @@ def test_create_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_flow.Flow() + post_with_metadata.return_value = gcdc_flow.Flow(), metadata client.create_flow( request, @@ -6945,6 +6999,7 @@ def test_create_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_flow_rest_bad_request(request_type=flow.DeleteFlowRequest): @@ -7132,10 +7187,13 @@ def test_list_flows_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_list_flows" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_list_flows_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_list_flows" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.ListFlowsRequest.pb(flow.ListFlowsRequest()) transcode.return_value = { "method": "post", @@ -7157,6 +7215,7 @@ def test_list_flows_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = flow.ListFlowsResponse() + post_with_metadata.return_value = flow.ListFlowsResponse(), metadata client.list_flows( request, @@ -7168,6 +7227,7 @@ def test_list_flows_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_flow_rest_bad_request(request_type=flow.GetFlowRequest): @@ -7260,10 +7320,13 @@ def test_get_flow_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_get_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_get_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_get_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.GetFlowRequest.pb(flow.GetFlowRequest()) transcode.return_value = { "method": "post", @@ -7285,6 +7348,7 @@ def test_get_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = flow.Flow() + post_with_metadata.return_value = flow.Flow(), metadata client.get_flow( request, @@ -7296,6 +7360,7 @@ def test_get_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_flow_rest_bad_request(request_type=gcdc_flow.UpdateFlowRequest): @@ -7603,10 +7668,13 @@ def test_update_flow_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_update_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_update_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_update_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_flow.UpdateFlowRequest.pb(gcdc_flow.UpdateFlowRequest()) transcode.return_value = { "method": "post", @@ -7628,6 +7696,7 @@ def test_update_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_flow.Flow() + post_with_metadata.return_value = gcdc_flow.Flow(), metadata client.update_flow( request, @@ -7639,6 +7708,7 @@ def test_update_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_train_flow_rest_bad_request(request_type=flow.TrainFlowRequest): @@ -7719,10 +7789,13 @@ def test_train_flow_rest_interceptors(null_interceptor): ), mock.patch.object( transports.FlowsRestInterceptor, "post_train_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_train_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_train_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.TrainFlowRequest.pb(flow.TrainFlowRequest()) transcode.return_value = { "method": "post", @@ -7744,6 +7817,7 @@ def test_train_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.train_flow( request, @@ -7755,6 +7829,7 @@ def test_train_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_validate_flow_rest_bad_request(request_type=flow.ValidateFlowRequest): @@ -7839,10 +7914,13 @@ def test_validate_flow_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_validate_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_validate_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_validate_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.ValidateFlowRequest.pb(flow.ValidateFlowRequest()) transcode.return_value = { "method": "post", @@ -7864,6 +7942,7 @@ def test_validate_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = flow.FlowValidationResult() + post_with_metadata.return_value = flow.FlowValidationResult(), metadata client.validate_flow( request, @@ -7875,6 +7954,7 @@ def test_validate_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_flow_validation_result_rest_bad_request( @@ -7961,10 +8041,13 @@ def test_get_flow_validation_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FlowsRestInterceptor, "post_get_flow_validation_result" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_get_flow_validation_result_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_get_flow_validation_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.GetFlowValidationResultRequest.pb( flow.GetFlowValidationResultRequest() ) @@ -7988,6 +8071,7 @@ def test_get_flow_validation_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = flow.FlowValidationResult() + post_with_metadata.return_value = flow.FlowValidationResult(), metadata client.get_flow_validation_result( request, @@ -7999,6 +8083,7 @@ def test_get_flow_validation_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_flow_rest_bad_request(request_type=flow.ImportFlowRequest): @@ -8075,10 +8160,13 @@ def test_import_flow_rest_interceptors(null_interceptor): ), mock.patch.object( transports.FlowsRestInterceptor, "post_import_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_import_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_import_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.ImportFlowRequest.pb(flow.ImportFlowRequest()) transcode.return_value = { "method": "post", @@ -8100,6 +8188,7 @@ def test_import_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_flow( request, @@ -8111,6 +8200,7 @@ def test_import_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_flow_rest_bad_request(request_type=flow.ExportFlowRequest): @@ -8191,10 +8281,13 @@ def test_export_flow_rest_interceptors(null_interceptor): ), mock.patch.object( transports.FlowsRestInterceptor, "post_export_flow" ) as post, mock.patch.object( + transports.FlowsRestInterceptor, "post_export_flow_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FlowsRestInterceptor, "pre_export_flow" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = flow.ExportFlowRequest.pb(flow.ExportFlowRequest()) transcode.return_value = { "method": "post", @@ -8216,6 +8309,7 @@ def test_export_flow_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_flow( request, @@ -8227,6 +8321,7 @@ def test_export_flow_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_generators.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_generators.py index ab01091adfa0..d32ae5ec8bf2 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_generators.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_generators.py @@ -65,6 +65,13 @@ from google.cloud.dialogflowcx_v3beta1.types import generator from google.cloud.dialogflowcx_v3beta1.types import generator as gcdc_generator +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -300,6 +307,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = GeneratorsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = GeneratorsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4317,10 +4367,13 @@ def test_list_generators_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_list_generators" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_list_generators_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_list_generators" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = generator.ListGeneratorsRequest.pb( generator.ListGeneratorsRequest() ) @@ -4346,6 +4399,7 @@ def test_list_generators_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generator.ListGeneratorsResponse() + post_with_metadata.return_value = generator.ListGeneratorsResponse(), metadata client.list_generators( request, @@ -4357,6 +4411,7 @@ def test_list_generators_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_generator_rest_bad_request(request_type=generator.GetGeneratorRequest): @@ -4445,10 +4500,13 @@ def test_get_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_get_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_get_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_get_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = generator.GetGeneratorRequest.pb(generator.GetGeneratorRequest()) transcode.return_value = { "method": "post", @@ -4470,6 +4528,7 @@ def test_get_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generator.Generator() + post_with_metadata.return_value = generator.Generator(), metadata client.get_generator( request, @@ -4481,6 +4540,7 @@ def test_get_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_generator_rest_bad_request( @@ -4650,10 +4710,13 @@ def test_create_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_create_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_create_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_create_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_generator.CreateGeneratorRequest.pb( gcdc_generator.CreateGeneratorRequest() ) @@ -4677,6 +4740,7 @@ def test_create_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_generator.Generator() + post_with_metadata.return_value = gcdc_generator.Generator(), metadata client.create_generator( request, @@ -4688,6 +4752,7 @@ def test_create_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_generator_rest_bad_request( @@ -4865,10 +4930,13 @@ def test_update_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_update_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_update_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_update_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_generator.UpdateGeneratorRequest.pb( gcdc_generator.UpdateGeneratorRequest() ) @@ -4892,6 +4960,7 @@ def test_update_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_generator.Generator() + post_with_metadata.return_value = gcdc_generator.Generator(), metadata client.update_generator( request, @@ -4903,6 +4972,7 @@ def test_update_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_generator_rest_bad_request( 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 ea072597a3c6..d86a266e4824 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 @@ -74,6 +74,13 @@ from google.cloud.dialogflowcx_v3beta1.types import intent from google.cloud.dialogflowcx_v3beta1.types import intent as gcdc_intent +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -297,6 +304,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = IntentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = IntentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5155,10 +5205,13 @@ def test_list_intents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_list_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_list_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_list_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.ListIntentsRequest.pb(intent.ListIntentsRequest()) transcode.return_value = { "method": "post", @@ -5180,6 +5233,7 @@ def test_list_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = intent.ListIntentsResponse() + post_with_metadata.return_value = intent.ListIntentsResponse(), metadata client.list_intents( request, @@ -5191,6 +5245,7 @@ def test_list_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_intent_rest_bad_request(request_type=intent.GetIntentRequest): @@ -5283,10 +5338,13 @@ def test_get_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_get_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_get_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_get_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.GetIntentRequest.pb(intent.GetIntentRequest()) transcode.return_value = { "method": "post", @@ -5308,6 +5366,7 @@ def test_get_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = intent.Intent() + post_with_metadata.return_value = intent.Intent(), metadata client.get_intent( request, @@ -5319,6 +5378,7 @@ def test_get_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_intent_rest_bad_request(request_type=gcdc_intent.CreateIntentRequest): @@ -5497,10 +5557,13 @@ def test_create_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_create_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_create_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_create_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_intent.CreateIntentRequest.pb( gcdc_intent.CreateIntentRequest() ) @@ -5524,6 +5587,7 @@ def test_create_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_intent.Intent() + post_with_metadata.return_value = gcdc_intent.Intent(), metadata client.create_intent( request, @@ -5535,6 +5599,7 @@ def test_create_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_intent_rest_bad_request(request_type=gcdc_intent.UpdateIntentRequest): @@ -5721,10 +5786,13 @@ def test_update_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_update_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_update_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_update_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_intent.UpdateIntentRequest.pb( gcdc_intent.UpdateIntentRequest() ) @@ -5748,6 +5816,7 @@ def test_update_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_intent.Intent() + post_with_metadata.return_value = gcdc_intent.Intent(), metadata client.update_intent( request, @@ -5759,6 +5828,7 @@ def test_update_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_intent_rest_bad_request(request_type=intent.DeleteIntentRequest): @@ -5942,10 +6012,13 @@ def test_import_intents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.IntentsRestInterceptor, "post_import_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_import_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_import_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.ImportIntentsRequest.pb(intent.ImportIntentsRequest()) transcode.return_value = { "method": "post", @@ -5967,6 +6040,7 @@ def test_import_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_intents( request, @@ -5978,6 +6052,7 @@ def test_import_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_intents_rest_bad_request(request_type=intent.ExportIntentsRequest): @@ -6054,10 +6129,13 @@ def test_export_intents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.IntentsRestInterceptor, "post_export_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_export_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_export_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.ExportIntentsRequest.pb(intent.ExportIntentsRequest()) transcode.return_value = { "method": "post", @@ -6079,6 +6157,7 @@ def test_export_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_intents( request, @@ -6090,6 +6169,7 @@ def test_export_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): 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 af6aa09bd5c2..fa3bcf3b9638 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 @@ -73,6 +73,13 @@ from google.cloud.dialogflowcx_v3beta1.types import page as gcdc_page from google.cloud.dialogflowcx_v3beta1.types import response_message, tool_call +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -291,6 +298,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = PagesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = PagesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4300,10 +4350,13 @@ def test_list_pages_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PagesRestInterceptor, "post_list_pages" ) as post, mock.patch.object( + transports.PagesRestInterceptor, "post_list_pages_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PagesRestInterceptor, "pre_list_pages" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = page.ListPagesRequest.pb(page.ListPagesRequest()) transcode.return_value = { "method": "post", @@ -4325,6 +4378,7 @@ def test_list_pages_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = page.ListPagesResponse() + post_with_metadata.return_value = page.ListPagesResponse(), metadata client.list_pages( request, @@ -4336,6 +4390,7 @@ def test_list_pages_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_page_rest_bad_request(request_type=page.GetPageRequest): @@ -4426,10 +4481,13 @@ def test_get_page_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PagesRestInterceptor, "post_get_page" ) as post, mock.patch.object( + transports.PagesRestInterceptor, "post_get_page_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PagesRestInterceptor, "pre_get_page" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = page.GetPageRequest.pb(page.GetPageRequest()) transcode.return_value = { "method": "post", @@ -4451,6 +4509,7 @@ def test_get_page_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = page.Page() + post_with_metadata.return_value = page.Page(), metadata client.get_page( request, @@ -4462,6 +4521,7 @@ def test_get_page_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_page_rest_bad_request(request_type=gcdc_page.CreatePageRequest): @@ -4764,10 +4824,13 @@ def test_create_page_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PagesRestInterceptor, "post_create_page" ) as post, mock.patch.object( + transports.PagesRestInterceptor, "post_create_page_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PagesRestInterceptor, "pre_create_page" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_page.CreatePageRequest.pb(gcdc_page.CreatePageRequest()) transcode.return_value = { "method": "post", @@ -4789,6 +4852,7 @@ def test_create_page_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_page.Page() + post_with_metadata.return_value = gcdc_page.Page(), metadata client.create_page( request, @@ -4800,6 +4864,7 @@ def test_create_page_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_page_rest_bad_request(request_type=gcdc_page.UpdatePageRequest): @@ -5106,10 +5171,13 @@ def test_update_page_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PagesRestInterceptor, "post_update_page" ) as post, mock.patch.object( + transports.PagesRestInterceptor, "post_update_page_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PagesRestInterceptor, "pre_update_page" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_page.UpdatePageRequest.pb(gcdc_page.UpdatePageRequest()) transcode.return_value = { "method": "post", @@ -5131,6 +5199,7 @@ def test_update_page_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_page.Page() + post_with_metadata.return_value = gcdc_page.Page(), metadata client.update_page( request, @@ -5142,6 +5211,7 @@ def test_update_page_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_page_rest_bad_request(request_type=page.DeletePageRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_playbooks.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_playbooks.py index 92c097d8aee7..8eb32d21a222 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_playbooks.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_playbooks.py @@ -71,6 +71,13 @@ from google.cloud.dialogflowcx_v3beta1.types import playbook from google.cloud.dialogflowcx_v3beta1.types import playbook as gcdc_playbook +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -304,6 +311,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = PlaybooksClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = PlaybooksClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7061,10 +7111,13 @@ def test_create_playbook_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PlaybooksRestInterceptor, "post_create_playbook" ) as post, mock.patch.object( + transports.PlaybooksRestInterceptor, "post_create_playbook_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PlaybooksRestInterceptor, "pre_create_playbook" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_playbook.CreatePlaybookRequest.pb( gcdc_playbook.CreatePlaybookRequest() ) @@ -7088,6 +7141,7 @@ def test_create_playbook_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_playbook.Playbook() + post_with_metadata.return_value = gcdc_playbook.Playbook(), metadata client.create_playbook( request, @@ -7099,6 +7153,7 @@ def test_create_playbook_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_playbook_rest_bad_request(request_type=playbook.DeletePlaybookRequest): @@ -7286,10 +7341,13 @@ def test_list_playbooks_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PlaybooksRestInterceptor, "post_list_playbooks" ) as post, mock.patch.object( + transports.PlaybooksRestInterceptor, "post_list_playbooks_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PlaybooksRestInterceptor, "pre_list_playbooks" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = playbook.ListPlaybooksRequest.pb(playbook.ListPlaybooksRequest()) transcode.return_value = { "method": "post", @@ -7313,6 +7371,7 @@ def test_list_playbooks_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = playbook.ListPlaybooksResponse() + post_with_metadata.return_value = playbook.ListPlaybooksResponse(), metadata client.list_playbooks( request, @@ -7324,6 +7383,7 @@ def test_list_playbooks_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_playbook_rest_bad_request(request_type=playbook.GetPlaybookRequest): @@ -7420,10 +7480,13 @@ def test_get_playbook_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PlaybooksRestInterceptor, "post_get_playbook" ) as post, mock.patch.object( + transports.PlaybooksRestInterceptor, "post_get_playbook_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PlaybooksRestInterceptor, "pre_get_playbook" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = playbook.GetPlaybookRequest.pb(playbook.GetPlaybookRequest()) transcode.return_value = { "method": "post", @@ -7445,6 +7508,7 @@ def test_get_playbook_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = playbook.Playbook() + post_with_metadata.return_value = playbook.Playbook(), metadata client.get_playbook( request, @@ -7456,6 +7520,7 @@ def test_get_playbook_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_playbook_rest_bad_request( @@ -7648,10 +7713,13 @@ def test_update_playbook_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PlaybooksRestInterceptor, "post_update_playbook" ) as post, mock.patch.object( + transports.PlaybooksRestInterceptor, "post_update_playbook_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PlaybooksRestInterceptor, "pre_update_playbook" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_playbook.UpdatePlaybookRequest.pb( gcdc_playbook.UpdatePlaybookRequest() ) @@ -7675,6 +7743,7 @@ def test_update_playbook_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_playbook.Playbook() + post_with_metadata.return_value = gcdc_playbook.Playbook(), metadata client.update_playbook( request, @@ -7686,6 +7755,7 @@ def test_update_playbook_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_playbook_version_rest_bad_request( @@ -7913,10 +7983,14 @@ def test_create_playbook_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PlaybooksRestInterceptor, "post_create_playbook_version" ) as post, mock.patch.object( + transports.PlaybooksRestInterceptor, + "post_create_playbook_version_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.PlaybooksRestInterceptor, "pre_create_playbook_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = playbook.CreatePlaybookVersionRequest.pb( playbook.CreatePlaybookVersionRequest() ) @@ -7940,6 +8014,7 @@ def test_create_playbook_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = playbook.PlaybookVersion() + post_with_metadata.return_value = playbook.PlaybookVersion(), metadata client.create_playbook_version( request, @@ -7951,6 +8026,7 @@ def test_create_playbook_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_playbook_version_rest_bad_request( @@ -8039,10 +8115,13 @@ def test_get_playbook_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PlaybooksRestInterceptor, "post_get_playbook_version" ) as post, mock.patch.object( + transports.PlaybooksRestInterceptor, "post_get_playbook_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PlaybooksRestInterceptor, "pre_get_playbook_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = playbook.GetPlaybookVersionRequest.pb( playbook.GetPlaybookVersionRequest() ) @@ -8066,6 +8145,7 @@ def test_get_playbook_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = playbook.PlaybookVersion() + post_with_metadata.return_value = playbook.PlaybookVersion(), metadata client.get_playbook_version( request, @@ -8077,6 +8157,7 @@ def test_get_playbook_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_playbook_versions_rest_bad_request( @@ -8163,10 +8244,13 @@ def test_list_playbook_versions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.PlaybooksRestInterceptor, "post_list_playbook_versions" ) as post, mock.patch.object( + transports.PlaybooksRestInterceptor, "post_list_playbook_versions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.PlaybooksRestInterceptor, "pre_list_playbook_versions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = playbook.ListPlaybookVersionsRequest.pb( playbook.ListPlaybookVersionsRequest() ) @@ -8192,6 +8276,10 @@ def test_list_playbook_versions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = playbook.ListPlaybookVersionsResponse() + post_with_metadata.return_value = ( + playbook.ListPlaybookVersionsResponse(), + metadata, + ) client.list_playbook_versions( request, @@ -8203,6 +8291,7 @@ def test_list_playbook_versions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_playbook_version_rest_bad_request( diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_security_settings_service.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_security_settings_service.py index 3769df0e3832..4b058bce68e3 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_security_settings_service.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_security_settings_service.py @@ -66,6 +66,13 @@ ) from google.cloud.dialogflowcx_v3beta1.types import security_settings +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -341,6 +348,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SecuritySettingsServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SecuritySettingsServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4833,11 +4883,15 @@ def test_create_security_settings_rest_interceptors(null_interceptor): transports.SecuritySettingsServiceRestInterceptor, "post_create_security_settings", ) as post, mock.patch.object( + transports.SecuritySettingsServiceRestInterceptor, + "post_create_security_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "pre_create_security_settings", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_security_settings.CreateSecuritySettingsRequest.pb( gcdc_security_settings.CreateSecuritySettingsRequest() ) @@ -4863,6 +4917,10 @@ def test_create_security_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_security_settings.SecuritySettings() + post_with_metadata.return_value = ( + gcdc_security_settings.SecuritySettings(), + metadata, + ) client.create_security_settings( request, @@ -4874,6 +4932,7 @@ def test_create_security_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_security_settings_rest_bad_request( @@ -4985,10 +5044,14 @@ def test_get_security_settings_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "post_get_security_settings" ) as post, mock.patch.object( + transports.SecuritySettingsServiceRestInterceptor, + "post_get_security_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "pre_get_security_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = security_settings.GetSecuritySettingsRequest.pb( security_settings.GetSecuritySettingsRequest() ) @@ -5014,6 +5077,7 @@ def test_get_security_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = security_settings.SecuritySettings() + post_with_metadata.return_value = security_settings.SecuritySettings(), metadata client.get_security_settings( request, @@ -5025,6 +5089,7 @@ def test_get_security_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_security_settings_rest_bad_request( @@ -5229,11 +5294,15 @@ def test_update_security_settings_rest_interceptors(null_interceptor): transports.SecuritySettingsServiceRestInterceptor, "post_update_security_settings", ) as post, mock.patch.object( + transports.SecuritySettingsServiceRestInterceptor, + "post_update_security_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "pre_update_security_settings", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_security_settings.UpdateSecuritySettingsRequest.pb( gcdc_security_settings.UpdateSecuritySettingsRequest() ) @@ -5259,6 +5328,10 @@ def test_update_security_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_security_settings.SecuritySettings() + post_with_metadata.return_value = ( + gcdc_security_settings.SecuritySettings(), + metadata, + ) client.update_security_settings( request, @@ -5270,6 +5343,7 @@ def test_update_security_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_security_settings_rest_bad_request( @@ -5354,10 +5428,14 @@ def test_list_security_settings_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "post_list_security_settings" ) as post, mock.patch.object( + transports.SecuritySettingsServiceRestInterceptor, + "post_list_security_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SecuritySettingsServiceRestInterceptor, "pre_list_security_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = security_settings.ListSecuritySettingsRequest.pb( security_settings.ListSecuritySettingsRequest() ) @@ -5383,6 +5461,10 @@ def test_list_security_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = security_settings.ListSecuritySettingsResponse() + post_with_metadata.return_value = ( + security_settings.ListSecuritySettingsResponse(), + metadata, + ) client.list_security_settings( request, @@ -5394,6 +5476,7 @@ def test_list_security_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_security_settings_rest_bad_request( diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_session_entity_types.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_session_entity_types.py index a99d3bd9d7dc..63142f2d3c4a 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_session_entity_types.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_session_entity_types.py @@ -67,6 +67,13 @@ from google.cloud.dialogflowcx_v3beta1.types import entity_type from google.cloud.dialogflowcx_v3beta1.types import session_entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -338,6 +345,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionEntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionEntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4589,10 +4639,14 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_list_session_entity_types" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_list_session_entity_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_list_session_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_entity_type.ListSessionEntityTypesRequest.pb( session_entity_type.ListSessionEntityTypesRequest() ) @@ -4618,6 +4672,10 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_entity_type.ListSessionEntityTypesResponse() + post_with_metadata.return_value = ( + session_entity_type.ListSessionEntityTypesResponse(), + metadata, + ) client.list_session_entity_types( request, @@ -4629,6 +4687,7 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_session_entity_type_rest_bad_request( @@ -4722,10 +4781,14 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_get_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_get_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_get_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_entity_type.GetSessionEntityTypeRequest.pb( session_entity_type.GetSessionEntityTypeRequest() ) @@ -4751,6 +4814,10 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + session_entity_type.SessionEntityType(), + metadata, + ) client.get_session_entity_type( request, @@ -4762,6 +4829,7 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_session_entity_type_rest_bad_request( @@ -4931,10 +4999,14 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_create_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_create_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_create_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_session_entity_type.CreateSessionEntityTypeRequest.pb( gcdc_session_entity_type.CreateSessionEntityTypeRequest() ) @@ -4960,6 +5032,10 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + gcdc_session_entity_type.SessionEntityType(), + metadata, + ) client.create_session_entity_type( request, @@ -4971,6 +5047,7 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_session_entity_type_rest_bad_request( @@ -5144,10 +5221,14 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_update_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_update_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_update_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_session_entity_type.UpdateSessionEntityTypeRequest.pb( gcdc_session_entity_type.UpdateSessionEntityTypeRequest() ) @@ -5173,6 +5254,10 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + gcdc_session_entity_type.SessionEntityType(), + metadata, + ) client.update_session_entity_type( request, @@ -5184,6 +5269,7 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_session_entity_type_rest_bad_request( diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_sessions.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_sessions.py index 6494bba9cab1..de0f3fc09332 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_sessions.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_sessions.py @@ -74,6 +74,13 @@ tool_call, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -304,6 +311,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3483,10 +3533,13 @@ def test_detect_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_detect_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_detect_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_detect_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.DetectIntentRequest.pb(session.DetectIntentRequest()) transcode.return_value = { "method": "post", @@ -3510,6 +3563,7 @@ def test_detect_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.DetectIntentResponse() + post_with_metadata.return_value = session.DetectIntentResponse(), metadata client.detect_intent( request, @@ -3521,6 +3575,7 @@ def test_detect_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_server_streaming_detect_intent_rest_bad_request( @@ -3617,10 +3672,14 @@ def test_server_streaming_detect_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_server_streaming_detect_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, + "post_server_streaming_detect_intent_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_server_streaming_detect_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.DetectIntentRequest.pb(session.DetectIntentRequest()) transcode.return_value = { "method": "post", @@ -3644,6 +3703,7 @@ def test_server_streaming_detect_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.DetectIntentResponse() + post_with_metadata.return_value = session.DetectIntentResponse(), metadata client.server_streaming_detect_intent( request, @@ -3655,6 +3715,7 @@ def test_server_streaming_detect_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_streaming_detect_intent_rest_error(): @@ -3750,10 +3811,13 @@ def test_match_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_match_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_match_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_match_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.MatchIntentRequest.pb(session.MatchIntentRequest()) transcode.return_value = { "method": "post", @@ -3777,6 +3841,7 @@ def test_match_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.MatchIntentResponse() + post_with_metadata.return_value = session.MatchIntentResponse(), metadata client.match_intent( request, @@ -3788,6 +3853,7 @@ def test_match_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fulfill_intent_rest_bad_request(request_type=session.FulfillIntentRequest): @@ -3878,10 +3944,13 @@ def test_fulfill_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_fulfill_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_fulfill_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_fulfill_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.FulfillIntentRequest.pb(session.FulfillIntentRequest()) transcode.return_value = { "method": "post", @@ -3905,6 +3974,7 @@ def test_fulfill_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.FulfillIntentResponse() + post_with_metadata.return_value = session.FulfillIntentResponse(), metadata client.fulfill_intent( request, @@ -3916,6 +3986,7 @@ def test_fulfill_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_submit_answer_feedback_rest_bad_request( @@ -4004,10 +4075,13 @@ def test_submit_answer_feedback_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_submit_answer_feedback" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_submit_answer_feedback_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_submit_answer_feedback" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session.SubmitAnswerFeedbackRequest.pb( session.SubmitAnswerFeedbackRequest() ) @@ -4031,6 +4105,7 @@ def test_submit_answer_feedback_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.AnswerFeedback() + post_with_metadata.return_value = session.AnswerFeedback(), metadata client.submit_answer_feedback( request, @@ -4042,6 +4117,7 @@ def test_submit_answer_feedback_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): 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 7409fb4e76db..9d709090878e 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 @@ -90,6 +90,13 @@ from google.cloud.dialogflowcx_v3beta1.types import test_case as gcdc_test_case from google.cloud.dialogflowcx_v3beta1.types import tool_call +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -323,6 +330,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = TestCasesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = TestCasesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -8007,10 +8057,13 @@ def test_list_test_cases_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_list_test_cases" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_list_test_cases_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_list_test_cases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.ListTestCasesRequest.pb(test_case.ListTestCasesRequest()) transcode.return_value = { "method": "post", @@ -8034,6 +8087,7 @@ def test_list_test_cases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.ListTestCasesResponse() + post_with_metadata.return_value = test_case.ListTestCasesResponse(), metadata client.list_test_cases( request, @@ -8045,6 +8099,7 @@ def test_list_test_cases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_delete_test_cases_rest_bad_request( @@ -8242,10 +8297,13 @@ def test_get_test_case_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_get_test_case" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_get_test_case_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_get_test_case" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.GetTestCaseRequest.pb(test_case.GetTestCaseRequest()) transcode.return_value = { "method": "post", @@ -8267,6 +8325,7 @@ def test_get_test_case_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.TestCase() + post_with_metadata.return_value = test_case.TestCase(), metadata client.get_test_case( request, @@ -8278,6 +8337,7 @@ def test_get_test_case_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_test_case_rest_bad_request( @@ -8696,10 +8756,13 @@ def test_create_test_case_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_create_test_case" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_create_test_case_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_create_test_case" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_test_case.CreateTestCaseRequest.pb( gcdc_test_case.CreateTestCaseRequest() ) @@ -8723,6 +8786,7 @@ def test_create_test_case_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_test_case.TestCase() + post_with_metadata.return_value = gcdc_test_case.TestCase(), metadata client.create_test_case( request, @@ -8734,6 +8798,7 @@ def test_create_test_case_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_test_case_rest_bad_request( @@ -9160,10 +9225,13 @@ def test_update_test_case_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_update_test_case" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_update_test_case_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_update_test_case" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_test_case.UpdateTestCaseRequest.pb( gcdc_test_case.UpdateTestCaseRequest() ) @@ -9187,6 +9255,7 @@ def test_update_test_case_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_test_case.TestCase() + post_with_metadata.return_value = gcdc_test_case.TestCase(), metadata client.update_test_case( request, @@ -9198,6 +9267,7 @@ def test_update_test_case_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_run_test_case_rest_bad_request(request_type=test_case.RunTestCaseRequest): @@ -9278,10 +9348,13 @@ def test_run_test_case_rest_interceptors(null_interceptor): ), mock.patch.object( transports.TestCasesRestInterceptor, "post_run_test_case" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_run_test_case_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_run_test_case" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.RunTestCaseRequest.pb(test_case.RunTestCaseRequest()) transcode.return_value = { "method": "post", @@ -9303,6 +9376,7 @@ def test_run_test_case_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.run_test_case( request, @@ -9314,6 +9388,7 @@ def test_run_test_case_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_run_test_cases_rest_bad_request( @@ -9392,10 +9467,13 @@ def test_batch_run_test_cases_rest_interceptors(null_interceptor): ), mock.patch.object( transports.TestCasesRestInterceptor, "post_batch_run_test_cases" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_batch_run_test_cases_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_batch_run_test_cases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.BatchRunTestCasesRequest.pb( test_case.BatchRunTestCasesRequest() ) @@ -9419,6 +9497,7 @@ def test_batch_run_test_cases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_run_test_cases( request, @@ -9430,6 +9509,7 @@ def test_batch_run_test_cases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_calculate_coverage_rest_bad_request( @@ -9512,10 +9592,13 @@ def test_calculate_coverage_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_calculate_coverage" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_calculate_coverage_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_calculate_coverage" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.CalculateCoverageRequest.pb( test_case.CalculateCoverageRequest() ) @@ -9541,6 +9624,10 @@ def test_calculate_coverage_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.CalculateCoverageResponse() + post_with_metadata.return_value = ( + test_case.CalculateCoverageResponse(), + metadata, + ) client.calculate_coverage( request, @@ -9552,6 +9639,7 @@ def test_calculate_coverage_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_test_cases_rest_bad_request( @@ -9630,10 +9718,13 @@ def test_import_test_cases_rest_interceptors(null_interceptor): ), mock.patch.object( transports.TestCasesRestInterceptor, "post_import_test_cases" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_import_test_cases_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_import_test_cases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.ImportTestCasesRequest.pb( test_case.ImportTestCasesRequest() ) @@ -9657,6 +9748,7 @@ def test_import_test_cases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_test_cases( request, @@ -9668,6 +9760,7 @@ def test_import_test_cases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_test_cases_rest_bad_request( @@ -9746,10 +9839,13 @@ def test_export_test_cases_rest_interceptors(null_interceptor): ), mock.patch.object( transports.TestCasesRestInterceptor, "post_export_test_cases" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_export_test_cases_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_export_test_cases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.ExportTestCasesRequest.pb( test_case.ExportTestCasesRequest() ) @@ -9773,6 +9869,7 @@ def test_export_test_cases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_test_cases( request, @@ -9784,6 +9881,7 @@ def test_export_test_cases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_test_case_results_rest_bad_request( @@ -9870,10 +9968,13 @@ def test_list_test_case_results_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_list_test_case_results" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_list_test_case_results_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_list_test_case_results" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.ListTestCaseResultsRequest.pb( test_case.ListTestCaseResultsRequest() ) @@ -9899,6 +10000,10 @@ def test_list_test_case_results_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.ListTestCaseResultsResponse() + post_with_metadata.return_value = ( + test_case.ListTestCaseResultsResponse(), + metadata, + ) client.list_test_case_results( request, @@ -9910,6 +10015,7 @@ def test_list_test_case_results_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_test_case_result_rest_bad_request( @@ -10000,10 +10106,13 @@ def test_get_test_case_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.TestCasesRestInterceptor, "post_get_test_case_result" ) as post, mock.patch.object( + transports.TestCasesRestInterceptor, "post_get_test_case_result_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.TestCasesRestInterceptor, "pre_get_test_case_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = test_case.GetTestCaseResultRequest.pb( test_case.GetTestCaseResultRequest() ) @@ -10027,6 +10136,7 @@ def test_get_test_case_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = test_case.TestCaseResult() + post_with_metadata.return_value = test_case.TestCaseResult(), metadata client.get_test_case_result( request, @@ -10038,6 +10148,7 @@ def test_get_test_case_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_tools.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_tools.py index 466463ecbb5a..0b0b49e3128c 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_tools.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_tools.py @@ -75,6 +75,13 @@ from google.cloud.dialogflowcx_v3beta1.types import tool from google.cloud.dialogflowcx_v3beta1.types import tool as gcdc_tool +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -293,6 +300,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ToolsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ToolsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4800,10 +4850,13 @@ def test_create_tool_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ToolsRestInterceptor, "post_create_tool" ) as post, mock.patch.object( + transports.ToolsRestInterceptor, "post_create_tool_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ToolsRestInterceptor, "pre_create_tool" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_tool.CreateToolRequest.pb(gcdc_tool.CreateToolRequest()) transcode.return_value = { "method": "post", @@ -4825,6 +4878,7 @@ def test_create_tool_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_tool.Tool() + post_with_metadata.return_value = gcdc_tool.Tool(), metadata client.create_tool( request, @@ -4836,6 +4890,7 @@ def test_create_tool_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_tools_rest_bad_request(request_type=tool.ListToolsRequest): @@ -4916,10 +4971,13 @@ def test_list_tools_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ToolsRestInterceptor, "post_list_tools" ) as post, mock.patch.object( + transports.ToolsRestInterceptor, "post_list_tools_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ToolsRestInterceptor, "pre_list_tools" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = tool.ListToolsRequest.pb(tool.ListToolsRequest()) transcode.return_value = { "method": "post", @@ -4941,6 +4999,7 @@ def test_list_tools_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = tool.ListToolsResponse() + post_with_metadata.return_value = tool.ListToolsResponse(), metadata client.list_tools( request, @@ -4952,6 +5011,7 @@ def test_list_tools_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_tools_rest_bad_request(request_type=tool.ExportToolsRequest): @@ -5028,10 +5088,13 @@ def test_export_tools_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ToolsRestInterceptor, "post_export_tools" ) as post, mock.patch.object( + transports.ToolsRestInterceptor, "post_export_tools_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ToolsRestInterceptor, "pre_export_tools" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = tool.ExportToolsRequest.pb(tool.ExportToolsRequest()) transcode.return_value = { "method": "post", @@ -5053,6 +5116,7 @@ def test_export_tools_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_tools( request, @@ -5064,6 +5128,7 @@ def test_export_tools_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_tool_rest_bad_request(request_type=tool.GetToolRequest): @@ -5154,10 +5219,13 @@ def test_get_tool_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ToolsRestInterceptor, "post_get_tool" ) as post, mock.patch.object( + transports.ToolsRestInterceptor, "post_get_tool_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ToolsRestInterceptor, "pre_get_tool" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = tool.GetToolRequest.pb(tool.GetToolRequest()) transcode.return_value = { "method": "post", @@ -5179,6 +5247,7 @@ def test_get_tool_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = tool.Tool() + post_with_metadata.return_value = tool.Tool(), metadata client.get_tool( request, @@ -5190,6 +5259,7 @@ def test_get_tool_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_tool_rest_bad_request(request_type=gcdc_tool.UpdateToolRequest): @@ -5390,10 +5460,13 @@ def test_update_tool_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ToolsRestInterceptor, "post_update_tool" ) as post, mock.patch.object( + transports.ToolsRestInterceptor, "post_update_tool_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ToolsRestInterceptor, "pre_update_tool" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_tool.UpdateToolRequest.pb(gcdc_tool.UpdateToolRequest()) transcode.return_value = { "method": "post", @@ -5415,6 +5488,7 @@ def test_update_tool_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_tool.Tool() + post_with_metadata.return_value = gcdc_tool.Tool(), metadata client.update_tool( request, @@ -5426,6 +5500,7 @@ def test_update_tool_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_tool_rest_bad_request(request_type=tool.DeleteToolRequest): 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 0ea032b635c9..c77bc3c5ec40 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 @@ -76,6 +76,13 @@ ) from google.cloud.dialogflowcx_v3beta1.types import transition_route_group +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -351,6 +358,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = TransitionRouteGroupsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = TransitionRouteGroupsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4643,11 +4693,15 @@ def test_list_transition_route_groups_rest_interceptors(null_interceptor): transports.TransitionRouteGroupsRestInterceptor, "post_list_transition_route_groups", ) as post, mock.patch.object( + transports.TransitionRouteGroupsRestInterceptor, + "post_list_transition_route_groups_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.TransitionRouteGroupsRestInterceptor, "pre_list_transition_route_groups", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = transition_route_group.ListTransitionRouteGroupsRequest.pb( transition_route_group.ListTransitionRouteGroupsRequest() ) @@ -4673,6 +4727,10 @@ def test_list_transition_route_groups_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = transition_route_group.ListTransitionRouteGroupsResponse() + post_with_metadata.return_value = ( + transition_route_group.ListTransitionRouteGroupsResponse(), + metadata, + ) client.list_transition_route_groups( request, @@ -4684,6 +4742,7 @@ def test_list_transition_route_groups_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_transition_route_group_rest_bad_request( @@ -4775,11 +4834,15 @@ def test_get_transition_route_group_rest_interceptors(null_interceptor): transports.TransitionRouteGroupsRestInterceptor, "post_get_transition_route_group", ) as post, mock.patch.object( + transports.TransitionRouteGroupsRestInterceptor, + "post_get_transition_route_group_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.TransitionRouteGroupsRestInterceptor, "pre_get_transition_route_group", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = transition_route_group.GetTransitionRouteGroupRequest.pb( transition_route_group.GetTransitionRouteGroupRequest() ) @@ -4805,6 +4868,10 @@ def test_get_transition_route_group_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = transition_route_group.TransitionRouteGroup() + post_with_metadata.return_value = ( + transition_route_group.TransitionRouteGroup(), + metadata, + ) client.get_transition_route_group( request, @@ -4816,6 +4883,7 @@ def test_get_transition_route_group_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_transition_route_group_rest_bad_request( @@ -5086,11 +5154,15 @@ def test_create_transition_route_group_rest_interceptors(null_interceptor): transports.TransitionRouteGroupsRestInterceptor, "post_create_transition_route_group", ) as post, mock.patch.object( + transports.TransitionRouteGroupsRestInterceptor, + "post_create_transition_route_group_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.TransitionRouteGroupsRestInterceptor, "pre_create_transition_route_group", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_transition_route_group.CreateTransitionRouteGroupRequest.pb( gcdc_transition_route_group.CreateTransitionRouteGroupRequest() ) @@ -5116,6 +5188,10 @@ def test_create_transition_route_group_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_transition_route_group.TransitionRouteGroup() + post_with_metadata.return_value = ( + gcdc_transition_route_group.TransitionRouteGroup(), + metadata, + ) client.create_transition_route_group( request, @@ -5127,6 +5203,7 @@ def test_create_transition_route_group_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_transition_route_group_rest_bad_request( @@ -5401,11 +5478,15 @@ def test_update_transition_route_group_rest_interceptors(null_interceptor): transports.TransitionRouteGroupsRestInterceptor, "post_update_transition_route_group", ) as post, mock.patch.object( + transports.TransitionRouteGroupsRestInterceptor, + "post_update_transition_route_group_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.TransitionRouteGroupsRestInterceptor, "pre_update_transition_route_group", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_transition_route_group.UpdateTransitionRouteGroupRequest.pb( gcdc_transition_route_group.UpdateTransitionRouteGroupRequest() ) @@ -5431,6 +5512,10 @@ def test_update_transition_route_group_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_transition_route_group.TransitionRouteGroup() + post_with_metadata.return_value = ( + gcdc_transition_route_group.TransitionRouteGroup(), + metadata, + ) client.update_transition_route_group( request, @@ -5442,6 +5527,7 @@ def test_update_transition_route_group_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_transition_route_group_rest_bad_request( diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_versions.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_versions.py index 90df4faf1ccf..9f468059f958 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_versions.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_versions.py @@ -77,6 +77,13 @@ from google.cloud.dialogflowcx_v3beta1.types import version from google.cloud.dialogflowcx_v3beta1.types import version as gcdc_version +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -307,6 +314,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = VersionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = VersionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5427,10 +5477,13 @@ def test_list_versions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_list_versions" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_list_versions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_list_versions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.ListVersionsRequest.pb(version.ListVersionsRequest()) transcode.return_value = { "method": "post", @@ -5454,6 +5507,7 @@ def test_list_versions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.ListVersionsResponse() + post_with_metadata.return_value = version.ListVersionsResponse(), metadata client.list_versions( request, @@ -5465,6 +5519,7 @@ def test_list_versions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_version_rest_bad_request(request_type=version.GetVersionRequest): @@ -5555,10 +5610,13 @@ def test_get_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_get_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_get_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_get_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.GetVersionRequest.pb(version.GetVersionRequest()) transcode.return_value = { "method": "post", @@ -5580,6 +5638,7 @@ def test_get_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.Version() + post_with_metadata.return_value = version.Version(), metadata client.get_version( request, @@ -5591,6 +5650,7 @@ def test_get_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_version_rest_bad_request( @@ -5752,10 +5812,13 @@ def test_create_version_rest_interceptors(null_interceptor): ), mock.patch.object( transports.VersionsRestInterceptor, "post_create_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_create_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_create_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_version.CreateVersionRequest.pb( gcdc_version.CreateVersionRequest() ) @@ -5779,6 +5842,7 @@ def test_create_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_version( request, @@ -5790,6 +5854,7 @@ def test_create_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_version_rest_bad_request( @@ -5965,10 +6030,13 @@ def test_update_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_update_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_update_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_update_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_version.UpdateVersionRequest.pb( gcdc_version.UpdateVersionRequest() ) @@ -5992,6 +6060,7 @@ def test_update_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_version.Version() + post_with_metadata.return_value = gcdc_version.Version(), metadata client.update_version( request, @@ -6003,6 +6072,7 @@ def test_update_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_version_rest_bad_request(request_type=version.DeleteVersionRequest): @@ -6190,10 +6260,13 @@ def test_load_version_rest_interceptors(null_interceptor): ), mock.patch.object( transports.VersionsRestInterceptor, "post_load_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_load_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_load_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.LoadVersionRequest.pb(version.LoadVersionRequest()) transcode.return_value = { "method": "post", @@ -6215,6 +6288,7 @@ def test_load_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.load_version( request, @@ -6226,6 +6300,7 @@ def test_load_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_compare_versions_rest_bad_request(request_type=version.CompareVersionsRequest): @@ -6312,10 +6387,13 @@ def test_compare_versions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_compare_versions" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_compare_versions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_compare_versions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.CompareVersionsRequest.pb(version.CompareVersionsRequest()) transcode.return_value = { "method": "post", @@ -6339,6 +6417,7 @@ def test_compare_versions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.CompareVersionsResponse() + post_with_metadata.return_value = version.CompareVersionsResponse(), metadata client.compare_versions( request, @@ -6350,6 +6429,7 @@ def test_compare_versions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_webhooks.py b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_webhooks.py index ddfdf27d0a82..ad997ffa492b 100644 --- a/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_webhooks.py +++ b/packages/google-cloud-dialogflow-cx/tests/unit/gapic/dialogflowcx_v3beta1/test_webhooks.py @@ -65,6 +65,13 @@ from google.cloud.dialogflowcx_v3beta1.types import webhook from google.cloud.dialogflowcx_v3beta1.types import webhook as gcdc_webhook +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -295,6 +302,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = WebhooksClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = WebhooksClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4270,10 +4320,13 @@ def test_list_webhooks_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.WebhooksRestInterceptor, "post_list_webhooks" ) as post, mock.patch.object( + transports.WebhooksRestInterceptor, "post_list_webhooks_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.WebhooksRestInterceptor, "pre_list_webhooks" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = webhook.ListWebhooksRequest.pb(webhook.ListWebhooksRequest()) transcode.return_value = { "method": "post", @@ -4297,6 +4350,7 @@ def test_list_webhooks_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = webhook.ListWebhooksResponse() + post_with_metadata.return_value = webhook.ListWebhooksResponse(), metadata client.list_webhooks( request, @@ -4308,6 +4362,7 @@ def test_list_webhooks_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_webhook_rest_bad_request(request_type=webhook.GetWebhookRequest): @@ -4396,10 +4451,13 @@ def test_get_webhook_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.WebhooksRestInterceptor, "post_get_webhook" ) as post, mock.patch.object( + transports.WebhooksRestInterceptor, "post_get_webhook_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.WebhooksRestInterceptor, "pre_get_webhook" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = webhook.GetWebhookRequest.pb(webhook.GetWebhookRequest()) transcode.return_value = { "method": "post", @@ -4421,6 +4479,7 @@ def test_get_webhook_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = webhook.Webhook() + post_with_metadata.return_value = webhook.Webhook(), metadata client.get_webhook( request, @@ -4432,6 +4491,7 @@ def test_get_webhook_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_webhook_rest_bad_request( @@ -4610,10 +4670,13 @@ def test_create_webhook_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.WebhooksRestInterceptor, "post_create_webhook" ) as post, mock.patch.object( + transports.WebhooksRestInterceptor, "post_create_webhook_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.WebhooksRestInterceptor, "pre_create_webhook" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_webhook.CreateWebhookRequest.pb( gcdc_webhook.CreateWebhookRequest() ) @@ -4637,6 +4700,7 @@ def test_create_webhook_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_webhook.Webhook() + post_with_metadata.return_value = gcdc_webhook.Webhook(), metadata client.create_webhook( request, @@ -4648,6 +4712,7 @@ def test_create_webhook_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_webhook_rest_bad_request( @@ -4834,10 +4899,13 @@ def test_update_webhook_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.WebhooksRestInterceptor, "post_update_webhook" ) as post, mock.patch.object( + transports.WebhooksRestInterceptor, "post_update_webhook_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.WebhooksRestInterceptor, "pre_update_webhook" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcdc_webhook.UpdateWebhookRequest.pb( gcdc_webhook.UpdateWebhookRequest() ) @@ -4861,6 +4929,7 @@ def test_update_webhook_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcdc_webhook.Webhook() + post_with_metadata.return_value = gcdc_webhook.Webhook(), metadata client.update_webhook( request, @@ -4872,6 +4941,7 @@ def test_update_webhook_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_webhook_rest_bad_request(request_type=webhook.DeleteWebhookRequest): diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow/gapic_version.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow/gapic_version.py index 75872a31e259..558c8aab67c5 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow/gapic_version.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.38.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/gapic_version.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/gapic_version.py index 75872a31e259..558c8aab67c5 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/gapic_version.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.38.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/agents/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/agents/client.py index d78e35631c64..33292167f346 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/agents/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/agents/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -484,6 +486,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1816,16 +1845,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1871,16 +1904,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1981,16 +2018,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2036,16 +2077,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/agents/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/agents/transports/rest.py index f14c8a452f2a..77e7b09533c9 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/agents/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/agents/transports/rest.py @@ -176,12 +176,35 @@ def post_export_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_export_agent` interceptor runs + before the `post_export_agent_with_metadata` interceptor. """ return response + def post_export_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_export_agent_with_metadata` + interceptor in new development instead of the `post_export_agent` interceptor. + When both interceptors are used, this `post_export_agent_with_metadata` interceptor runs after the + `post_export_agent` interceptor. The (possibly modified) response returned by + `post_export_agent` will be passed to + `post_export_agent_with_metadata`. + """ + return response, metadata + def pre_get_agent( self, request: agent.GetAgentRequest, @@ -197,12 +220,33 @@ def pre_get_agent( def post_get_agent(self, response: agent.Agent) -> agent.Agent: """Post-rpc interceptor for get_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_agent` interceptor runs + before the `post_get_agent_with_metadata` interceptor. """ return response + def post_get_agent_with_metadata( + self, response: agent.Agent, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_agent_with_metadata` + interceptor in new development instead of the `post_get_agent` interceptor. + When both interceptors are used, this `post_get_agent_with_metadata` interceptor runs after the + `post_get_agent` interceptor. The (possibly modified) response returned by + `post_get_agent` will be passed to + `post_get_agent_with_metadata`. + """ + return response, metadata + def pre_get_validation_result( self, request: agent.GetValidationResultRequest, @@ -222,12 +266,37 @@ def post_get_validation_result( ) -> validation_result.ValidationResult: """Post-rpc interceptor for get_validation_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_validation_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_validation_result` interceptor runs + before the `post_get_validation_result_with_metadata` interceptor. """ return response + def post_get_validation_result_with_metadata( + self, + response: validation_result.ValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + validation_result.ValidationResult, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_validation_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_validation_result_with_metadata` + interceptor in new development instead of the `post_get_validation_result` interceptor. + When both interceptors are used, this `post_get_validation_result_with_metadata` interceptor runs after the + `post_get_validation_result` interceptor. The (possibly modified) response returned by + `post_get_validation_result` will be passed to + `post_get_validation_result_with_metadata`. + """ + return response, metadata + def pre_import_agent( self, request: agent.ImportAgentRequest, @@ -245,12 +314,35 @@ def post_import_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_import_agent` interceptor runs + before the `post_import_agent_with_metadata` interceptor. """ return response + def post_import_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_import_agent_with_metadata` + interceptor in new development instead of the `post_import_agent` interceptor. + When both interceptors are used, this `post_import_agent_with_metadata` interceptor runs after the + `post_import_agent` interceptor. The (possibly modified) response returned by + `post_import_agent` will be passed to + `post_import_agent_with_metadata`. + """ + return response, metadata + def pre_restore_agent( self, request: agent.RestoreAgentRequest, @@ -268,12 +360,35 @@ def post_restore_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for restore_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_restore_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_restore_agent` interceptor runs + before the `post_restore_agent_with_metadata` interceptor. """ return response + def post_restore_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for restore_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_restore_agent_with_metadata` + interceptor in new development instead of the `post_restore_agent` interceptor. + When both interceptors are used, this `post_restore_agent_with_metadata` interceptor runs after the + `post_restore_agent` interceptor. The (possibly modified) response returned by + `post_restore_agent` will be passed to + `post_restore_agent_with_metadata`. + """ + return response, metadata + def pre_search_agents( self, request: agent.SearchAgentsRequest, @@ -291,12 +406,35 @@ def post_search_agents( ) -> agent.SearchAgentsResponse: """Post-rpc interceptor for search_agents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_agents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_search_agents` interceptor runs + before the `post_search_agents_with_metadata` interceptor. """ return response + def post_search_agents_with_metadata( + self, + response: agent.SearchAgentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[agent.SearchAgentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search_agents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_search_agents_with_metadata` + interceptor in new development instead of the `post_search_agents` interceptor. + When both interceptors are used, this `post_search_agents_with_metadata` interceptor runs after the + `post_search_agents` interceptor. The (possibly modified) response returned by + `post_search_agents` will be passed to + `post_search_agents_with_metadata`. + """ + return response, metadata + def pre_set_agent( self, request: gcd_agent.SetAgentRequest, @@ -312,12 +450,35 @@ def pre_set_agent( def post_set_agent(self, response: gcd_agent.Agent) -> gcd_agent.Agent: """Post-rpc interceptor for set_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_set_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_set_agent` interceptor runs + before the `post_set_agent_with_metadata` interceptor. """ return response + def post_set_agent_with_metadata( + self, + response: gcd_agent.Agent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for set_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_set_agent_with_metadata` + interceptor in new development instead of the `post_set_agent` interceptor. + When both interceptors are used, this `post_set_agent_with_metadata` interceptor runs after the + `post_set_agent` interceptor. The (possibly modified) response returned by + `post_set_agent` will be passed to + `post_set_agent_with_metadata`. + """ + return response, metadata + def pre_train_agent( self, request: agent.TrainAgentRequest, @@ -335,12 +496,35 @@ def post_train_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for train_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_train_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_train_agent` interceptor runs + before the `post_train_agent_with_metadata` interceptor. """ return response + def post_train_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for train_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_train_agent_with_metadata` + interceptor in new development instead of the `post_train_agent` interceptor. + When both interceptors are used, this `post_train_agent_with_metadata` interceptor runs after the + `post_train_agent` interceptor. The (possibly modified) response returned by + `post_train_agent` will be passed to + `post_train_agent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -842,6 +1026,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -995,6 +1183,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1140,6 +1332,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_validation_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_validation_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1290,6 +1486,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1440,6 +1640,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_restore_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_restore_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1585,6 +1789,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_agents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_agents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1744,6 +1952,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_set_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_set_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1892,6 +2104,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_train_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_train_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/answer_records/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/answer_records/client.py index 92520ab73796..3c4bd7612a7b 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/answer_records/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/answer_records/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -525,6 +527,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1049,16 +1078,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1104,16 +1137,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1214,16 +1251,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1269,16 +1310,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/answer_records/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/answer_records/transports/rest.py index b9598bf7bd94..9a13609a5036 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/answer_records/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/answer_records/transports/rest.py @@ -112,12 +112,37 @@ def post_list_answer_records( ) -> answer_record.ListAnswerRecordsResponse: """Post-rpc interceptor for list_answer_records - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_answer_records_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AnswerRecords server but before - it is returned to user code. + it is returned to user code. This `post_list_answer_records` interceptor runs + before the `post_list_answer_records_with_metadata` interceptor. """ return response + def post_list_answer_records_with_metadata( + self, + response: answer_record.ListAnswerRecordsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + answer_record.ListAnswerRecordsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_answer_records + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AnswerRecords server but before it is returned to user code. + + We recommend only using this `post_list_answer_records_with_metadata` + interceptor in new development instead of the `post_list_answer_records` interceptor. + When both interceptors are used, this `post_list_answer_records_with_metadata` interceptor runs after the + `post_list_answer_records` interceptor. The (possibly modified) response returned by + `post_list_answer_records` will be passed to + `post_list_answer_records_with_metadata`. + """ + return response, metadata + def pre_update_answer_record( self, request: gcd_answer_record.UpdateAnswerRecordRequest, @@ -138,12 +163,35 @@ def post_update_answer_record( ) -> gcd_answer_record.AnswerRecord: """Post-rpc interceptor for update_answer_record - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_answer_record_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AnswerRecords server but before - it is returned to user code. + it is returned to user code. This `post_update_answer_record` interceptor runs + before the `post_update_answer_record_with_metadata` interceptor. """ return response + def post_update_answer_record_with_metadata( + self, + response: gcd_answer_record.AnswerRecord, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_answer_record.AnswerRecord, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_answer_record + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AnswerRecords server but before it is returned to user code. + + We recommend only using this `post_update_answer_record_with_metadata` + interceptor in new development instead of the `post_update_answer_record` interceptor. + When both interceptors are used, this `post_update_answer_record_with_metadata` interceptor runs after the + `post_update_answer_record` interceptor. The (possibly modified) response returned by + `post_update_answer_record` will be passed to + `post_update_answer_record_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -477,6 +525,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_answer_records(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_answer_records_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -660,6 +712,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_answer_record(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_answer_record_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/contexts/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/contexts/client.py index 5139b72d4d72..fdd52e3580b2 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/contexts/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/contexts/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -488,6 +490,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1462,16 +1491,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1517,16 +1550,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1627,16 +1664,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1682,16 +1723,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/contexts/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/contexts/transports/rest.py index 9d7803ecae3c..745e8f941bc4 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/contexts/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/contexts/transports/rest.py @@ -135,12 +135,35 @@ def pre_create_context( def post_create_context(self, response: gcd_context.Context) -> gcd_context.Context: """Post-rpc interceptor for create_context - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_context_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Contexts server but before - it is returned to user code. + it is returned to user code. This `post_create_context` interceptor runs + before the `post_create_context_with_metadata` interceptor. """ return response + def post_create_context_with_metadata( + self, + response: gcd_context.Context, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_context.Context, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_context + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Contexts server but before it is returned to user code. + + We recommend only using this `post_create_context_with_metadata` + interceptor in new development instead of the `post_create_context` interceptor. + When both interceptors are used, this `post_create_context_with_metadata` interceptor runs after the + `post_create_context` interceptor. The (possibly modified) response returned by + `post_create_context` will be passed to + `post_create_context_with_metadata`. + """ + return response, metadata + def pre_delete_all_contexts( self, request: context.DeleteAllContextsRequest, @@ -182,12 +205,35 @@ def pre_get_context( def post_get_context(self, response: context.Context) -> context.Context: """Post-rpc interceptor for get_context - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_context_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Contexts server but before - it is returned to user code. + it is returned to user code. This `post_get_context` interceptor runs + before the `post_get_context_with_metadata` interceptor. """ return response + def post_get_context_with_metadata( + self, + response: context.Context, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[context.Context, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_context + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Contexts server but before it is returned to user code. + + We recommend only using this `post_get_context_with_metadata` + interceptor in new development instead of the `post_get_context` interceptor. + When both interceptors are used, this `post_get_context_with_metadata` interceptor runs after the + `post_get_context` interceptor. The (possibly modified) response returned by + `post_get_context` will be passed to + `post_get_context_with_metadata`. + """ + return response, metadata + def pre_list_contexts( self, request: context.ListContextsRequest, @@ -205,12 +251,35 @@ def post_list_contexts( ) -> context.ListContextsResponse: """Post-rpc interceptor for list_contexts - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_contexts_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Contexts server but before - it is returned to user code. + it is returned to user code. This `post_list_contexts` interceptor runs + before the `post_list_contexts_with_metadata` interceptor. """ return response + def post_list_contexts_with_metadata( + self, + response: context.ListContextsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[context.ListContextsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_contexts + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Contexts server but before it is returned to user code. + + We recommend only using this `post_list_contexts_with_metadata` + interceptor in new development instead of the `post_list_contexts` interceptor. + When both interceptors are used, this `post_list_contexts_with_metadata` interceptor runs after the + `post_list_contexts` interceptor. The (possibly modified) response returned by + `post_list_contexts` will be passed to + `post_list_contexts_with_metadata`. + """ + return response, metadata + def pre_update_context( self, request: gcd_context.UpdateContextRequest, @@ -228,12 +297,35 @@ def pre_update_context( def post_update_context(self, response: gcd_context.Context) -> gcd_context.Context: """Post-rpc interceptor for update_context - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_context_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Contexts server but before - it is returned to user code. + it is returned to user code. This `post_update_context` interceptor runs + before the `post_update_context_with_metadata` interceptor. """ return response + def post_update_context_with_metadata( + self, + response: gcd_context.Context, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_context.Context, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_context + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Contexts server but before it is returned to user code. + + We recommend only using this `post_update_context_with_metadata` + interceptor in new development instead of the `post_update_context` interceptor. + When both interceptors are used, this `post_update_context_with_metadata` interceptor runs after the + `post_update_context` interceptor. The (possibly modified) response returned by + `post_update_context` will be passed to + `post_update_context_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -591,6 +683,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_context(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_context_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -973,6 +1069,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_context(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_context_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1118,6 +1218,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_contexts(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_contexts_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1288,6 +1392,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_context(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_context_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_datasets/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_datasets/client.py index 27c1cf586101..a4d0a6b69731 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_datasets/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_datasets/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -498,6 +500,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1411,16 +1440,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1466,16 +1499,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1576,16 +1613,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1631,16 +1672,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_datasets/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_datasets/transports/rest.py index db0063361e1f..149ee3070eca 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_datasets/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_datasets/transports/rest.py @@ -139,12 +139,35 @@ def post_create_conversation_dataset( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_conversation_dataset - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_dataset_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationDatasets server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation_dataset` interceptor runs + before the `post_create_conversation_dataset_with_metadata` interceptor. """ return response + def post_create_conversation_dataset_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_conversation_dataset + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationDatasets server but before it is returned to user code. + + We recommend only using this `post_create_conversation_dataset_with_metadata` + interceptor in new development instead of the `post_create_conversation_dataset` interceptor. + When both interceptors are used, this `post_create_conversation_dataset_with_metadata` interceptor runs after the + `post_create_conversation_dataset` interceptor. The (possibly modified) response returned by + `post_create_conversation_dataset` will be passed to + `post_create_conversation_dataset_with_metadata`. + """ + return response, metadata + def pre_delete_conversation_dataset( self, request: conversation_dataset.DeleteConversationDatasetRequest, @@ -165,12 +188,35 @@ def post_delete_conversation_dataset( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_conversation_dataset - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_conversation_dataset_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationDatasets server but before - it is returned to user code. + it is returned to user code. This `post_delete_conversation_dataset` interceptor runs + before the `post_delete_conversation_dataset_with_metadata` interceptor. """ return response + def post_delete_conversation_dataset_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_conversation_dataset + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationDatasets server but before it is returned to user code. + + We recommend only using this `post_delete_conversation_dataset_with_metadata` + interceptor in new development instead of the `post_delete_conversation_dataset` interceptor. + When both interceptors are used, this `post_delete_conversation_dataset_with_metadata` interceptor runs after the + `post_delete_conversation_dataset` interceptor. The (possibly modified) response returned by + `post_delete_conversation_dataset` will be passed to + `post_delete_conversation_dataset_with_metadata`. + """ + return response, metadata + def pre_get_conversation_dataset( self, request: conversation_dataset.GetConversationDatasetRequest, @@ -191,12 +237,38 @@ def post_get_conversation_dataset( ) -> conversation_dataset.ConversationDataset: """Post-rpc interceptor for get_conversation_dataset - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_dataset_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationDatasets server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation_dataset` interceptor runs + before the `post_get_conversation_dataset_with_metadata` interceptor. """ return response + def post_get_conversation_dataset_with_metadata( + self, + response: conversation_dataset.ConversationDataset, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_dataset.ConversationDataset, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_conversation_dataset + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationDatasets server but before it is returned to user code. + + We recommend only using this `post_get_conversation_dataset_with_metadata` + interceptor in new development instead of the `post_get_conversation_dataset` interceptor. + When both interceptors are used, this `post_get_conversation_dataset_with_metadata` interceptor runs after the + `post_get_conversation_dataset` interceptor. The (possibly modified) response returned by + `post_get_conversation_dataset` will be passed to + `post_get_conversation_dataset_with_metadata`. + """ + return response, metadata + def pre_import_conversation_data( self, request: conversation_dataset.ImportConversationDataRequest, @@ -217,12 +289,35 @@ def post_import_conversation_data( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_conversation_data - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_conversation_data_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationDatasets server but before - it is returned to user code. + it is returned to user code. This `post_import_conversation_data` interceptor runs + before the `post_import_conversation_data_with_metadata` interceptor. """ return response + def post_import_conversation_data_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_conversation_data + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationDatasets server but before it is returned to user code. + + We recommend only using this `post_import_conversation_data_with_metadata` + interceptor in new development instead of the `post_import_conversation_data` interceptor. + When both interceptors are used, this `post_import_conversation_data_with_metadata` interceptor runs after the + `post_import_conversation_data` interceptor. The (possibly modified) response returned by + `post_import_conversation_data` will be passed to + `post_import_conversation_data_with_metadata`. + """ + return response, metadata + def pre_list_conversation_datasets( self, request: conversation_dataset.ListConversationDatasetsRequest, @@ -243,12 +338,38 @@ def post_list_conversation_datasets( ) -> conversation_dataset.ListConversationDatasetsResponse: """Post-rpc interceptor for list_conversation_datasets - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversation_datasets_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationDatasets server but before - it is returned to user code. + it is returned to user code. This `post_list_conversation_datasets` interceptor runs + before the `post_list_conversation_datasets_with_metadata` interceptor. """ return response + def post_list_conversation_datasets_with_metadata( + self, + response: conversation_dataset.ListConversationDatasetsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_dataset.ListConversationDatasetsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_conversation_datasets + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationDatasets server but before it is returned to user code. + + We recommend only using this `post_list_conversation_datasets_with_metadata` + interceptor in new development instead of the `post_list_conversation_datasets` interceptor. + When both interceptors are used, this `post_list_conversation_datasets_with_metadata` interceptor runs after the + `post_list_conversation_datasets` interceptor. The (possibly modified) response returned by + `post_list_conversation_datasets` will be passed to + `post_list_conversation_datasets_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -650,6 +771,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation_dataset(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_conversation_dataset_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -796,6 +921,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_conversation_dataset(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_conversation_dataset_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -949,6 +1078,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation_dataset(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_dataset_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1104,6 +1237,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_conversation_data(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_conversation_data_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1251,6 +1388,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversation_datasets(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversation_datasets_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_models/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_models/client.py index 071de039a4c5..b285e815f00b 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_models/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_models/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -560,6 +562,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1963,16 +1992,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2018,16 +2051,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2128,16 +2165,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2183,16 +2224,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_models/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_models/transports/rest.py index 15e4ae8e846b..aba1babb9a60 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_models/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_models/transports/rest.py @@ -171,12 +171,35 @@ def post_create_conversation_model( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_conversation_model - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_model_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationModels server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation_model` interceptor runs + before the `post_create_conversation_model_with_metadata` interceptor. """ return response + def post_create_conversation_model_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_conversation_model + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationModels server but before it is returned to user code. + + We recommend only using this `post_create_conversation_model_with_metadata` + interceptor in new development instead of the `post_create_conversation_model` interceptor. + When both interceptors are used, this `post_create_conversation_model_with_metadata` interceptor runs after the + `post_create_conversation_model` interceptor. The (possibly modified) response returned by + `post_create_conversation_model` will be passed to + `post_create_conversation_model_with_metadata`. + """ + return response, metadata + def pre_create_conversation_model_evaluation( self, request: conversation_model.CreateConversationModelEvaluationRequest, @@ -197,12 +220,35 @@ def post_create_conversation_model_evaluation( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_conversation_model_evaluation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_model_evaluation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationModels server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation_model_evaluation` interceptor runs + before the `post_create_conversation_model_evaluation_with_metadata` interceptor. """ return response + def post_create_conversation_model_evaluation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_conversation_model_evaluation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationModels server but before it is returned to user code. + + We recommend only using this `post_create_conversation_model_evaluation_with_metadata` + interceptor in new development instead of the `post_create_conversation_model_evaluation` interceptor. + When both interceptors are used, this `post_create_conversation_model_evaluation_with_metadata` interceptor runs after the + `post_create_conversation_model_evaluation` interceptor. The (possibly modified) response returned by + `post_create_conversation_model_evaluation` will be passed to + `post_create_conversation_model_evaluation_with_metadata`. + """ + return response, metadata + def pre_delete_conversation_model( self, request: conversation_model.DeleteConversationModelRequest, @@ -223,12 +269,35 @@ def post_delete_conversation_model( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_conversation_model - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_conversation_model_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationModels server but before - it is returned to user code. + it is returned to user code. This `post_delete_conversation_model` interceptor runs + before the `post_delete_conversation_model_with_metadata` interceptor. """ return response + def post_delete_conversation_model_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_conversation_model + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationModels server but before it is returned to user code. + + We recommend only using this `post_delete_conversation_model_with_metadata` + interceptor in new development instead of the `post_delete_conversation_model` interceptor. + When both interceptors are used, this `post_delete_conversation_model_with_metadata` interceptor runs after the + `post_delete_conversation_model` interceptor. The (possibly modified) response returned by + `post_delete_conversation_model` will be passed to + `post_delete_conversation_model_with_metadata`. + """ + return response, metadata + def pre_deploy_conversation_model( self, request: conversation_model.DeployConversationModelRequest, @@ -249,12 +318,35 @@ def post_deploy_conversation_model( ) -> operations_pb2.Operation: """Post-rpc interceptor for deploy_conversation_model - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_deploy_conversation_model_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationModels server but before - it is returned to user code. + it is returned to user code. This `post_deploy_conversation_model` interceptor runs + before the `post_deploy_conversation_model_with_metadata` interceptor. """ return response + def post_deploy_conversation_model_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for deploy_conversation_model + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationModels server but before it is returned to user code. + + We recommend only using this `post_deploy_conversation_model_with_metadata` + interceptor in new development instead of the `post_deploy_conversation_model` interceptor. + When both interceptors are used, this `post_deploy_conversation_model_with_metadata` interceptor runs after the + `post_deploy_conversation_model` interceptor. The (possibly modified) response returned by + `post_deploy_conversation_model` will be passed to + `post_deploy_conversation_model_with_metadata`. + """ + return response, metadata + def pre_get_conversation_model( self, request: conversation_model.GetConversationModelRequest, @@ -275,12 +367,37 @@ def post_get_conversation_model( ) -> conversation_model.ConversationModel: """Post-rpc interceptor for get_conversation_model - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_model_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationModels server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation_model` interceptor runs + before the `post_get_conversation_model_with_metadata` interceptor. """ return response + def post_get_conversation_model_with_metadata( + self, + response: conversation_model.ConversationModel, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_model.ConversationModel, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_conversation_model + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationModels server but before it is returned to user code. + + We recommend only using this `post_get_conversation_model_with_metadata` + interceptor in new development instead of the `post_get_conversation_model` interceptor. + When both interceptors are used, this `post_get_conversation_model_with_metadata` interceptor runs after the + `post_get_conversation_model` interceptor. The (possibly modified) response returned by + `post_get_conversation_model` will be passed to + `post_get_conversation_model_with_metadata`. + """ + return response, metadata + def pre_get_conversation_model_evaluation( self, request: conversation_model.GetConversationModelEvaluationRequest, @@ -301,12 +418,38 @@ def post_get_conversation_model_evaluation( ) -> conversation_model.ConversationModelEvaluation: """Post-rpc interceptor for get_conversation_model_evaluation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_model_evaluation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationModels server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation_model_evaluation` interceptor runs + before the `post_get_conversation_model_evaluation_with_metadata` interceptor. """ return response + def post_get_conversation_model_evaluation_with_metadata( + self, + response: conversation_model.ConversationModelEvaluation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_model.ConversationModelEvaluation, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_conversation_model_evaluation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationModels server but before it is returned to user code. + + We recommend only using this `post_get_conversation_model_evaluation_with_metadata` + interceptor in new development instead of the `post_get_conversation_model_evaluation` interceptor. + When both interceptors are used, this `post_get_conversation_model_evaluation_with_metadata` interceptor runs after the + `post_get_conversation_model_evaluation` interceptor. The (possibly modified) response returned by + `post_get_conversation_model_evaluation` will be passed to + `post_get_conversation_model_evaluation_with_metadata`. + """ + return response, metadata + def pre_list_conversation_model_evaluations( self, request: conversation_model.ListConversationModelEvaluationsRequest, @@ -327,12 +470,38 @@ def post_list_conversation_model_evaluations( ) -> conversation_model.ListConversationModelEvaluationsResponse: """Post-rpc interceptor for list_conversation_model_evaluations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversation_model_evaluations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationModels server but before - it is returned to user code. + it is returned to user code. This `post_list_conversation_model_evaluations` interceptor runs + before the `post_list_conversation_model_evaluations_with_metadata` interceptor. """ return response + def post_list_conversation_model_evaluations_with_metadata( + self, + response: conversation_model.ListConversationModelEvaluationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_model.ListConversationModelEvaluationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_conversation_model_evaluations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationModels server but before it is returned to user code. + + We recommend only using this `post_list_conversation_model_evaluations_with_metadata` + interceptor in new development instead of the `post_list_conversation_model_evaluations` interceptor. + When both interceptors are used, this `post_list_conversation_model_evaluations_with_metadata` interceptor runs after the + `post_list_conversation_model_evaluations` interceptor. The (possibly modified) response returned by + `post_list_conversation_model_evaluations` will be passed to + `post_list_conversation_model_evaluations_with_metadata`. + """ + return response, metadata + def pre_list_conversation_models( self, request: conversation_model.ListConversationModelsRequest, @@ -353,12 +522,38 @@ def post_list_conversation_models( ) -> conversation_model.ListConversationModelsResponse: """Post-rpc interceptor for list_conversation_models - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversation_models_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationModels server but before - it is returned to user code. + it is returned to user code. This `post_list_conversation_models` interceptor runs + before the `post_list_conversation_models_with_metadata` interceptor. """ return response + def post_list_conversation_models_with_metadata( + self, + response: conversation_model.ListConversationModelsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_model.ListConversationModelsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_conversation_models + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationModels server but before it is returned to user code. + + We recommend only using this `post_list_conversation_models_with_metadata` + interceptor in new development instead of the `post_list_conversation_models` interceptor. + When both interceptors are used, this `post_list_conversation_models_with_metadata` interceptor runs after the + `post_list_conversation_models` interceptor. The (possibly modified) response returned by + `post_list_conversation_models` will be passed to + `post_list_conversation_models_with_metadata`. + """ + return response, metadata + def pre_undeploy_conversation_model( self, request: conversation_model.UndeployConversationModelRequest, @@ -379,12 +574,35 @@ def post_undeploy_conversation_model( ) -> operations_pb2.Operation: """Post-rpc interceptor for undeploy_conversation_model - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_undeploy_conversation_model_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationModels server but before - it is returned to user code. + it is returned to user code. This `post_undeploy_conversation_model` interceptor runs + before the `post_undeploy_conversation_model_with_metadata` interceptor. """ return response + def post_undeploy_conversation_model_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for undeploy_conversation_model + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationModels server but before it is returned to user code. + + We recommend only using this `post_undeploy_conversation_model_with_metadata` + interceptor in new development instead of the `post_undeploy_conversation_model` interceptor. + When both interceptors are used, this `post_undeploy_conversation_model_with_metadata` interceptor runs after the + `post_undeploy_conversation_model` interceptor. The (possibly modified) response returned by + `post_undeploy_conversation_model` will be passed to + `post_undeploy_conversation_model_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -784,6 +1002,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation_model(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_conversation_model_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -941,6 +1163,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation_model_evaluation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_create_conversation_model_evaluation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1088,6 +1317,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_conversation_model(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_conversation_model_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1241,6 +1474,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_deploy_conversation_model(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_deploy_conversation_model_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1387,6 +1624,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation_model(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_model_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1538,6 +1779,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation_model_evaluation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_get_conversation_model_evaluation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1694,6 +1942,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversation_model_evaluations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_list_conversation_model_evaluations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1844,6 +2099,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversation_models(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversation_models_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2000,6 +2259,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_undeploy_conversation_model(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_undeploy_conversation_model_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_profiles/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_profiles/client.py index 93f4d954e3d2..c1a5a1e749f8 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_profiles/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_profiles/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -640,6 +642,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1854,16 +1883,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1909,16 +1942,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2019,16 +2056,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2074,16 +2115,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_profiles/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_profiles/transports/rest.py index a467afdb1c2c..b6dbabd47a4a 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_profiles/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversation_profiles/transports/rest.py @@ -152,12 +152,35 @@ def post_clear_suggestion_feature_config( ) -> operations_pb2.Operation: """Post-rpc interceptor for clear_suggestion_feature_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_clear_suggestion_feature_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_clear_suggestion_feature_config` interceptor runs + before the `post_clear_suggestion_feature_config_with_metadata` interceptor. """ return response + def post_clear_suggestion_feature_config_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for clear_suggestion_feature_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_clear_suggestion_feature_config_with_metadata` + interceptor in new development instead of the `post_clear_suggestion_feature_config` interceptor. + When both interceptors are used, this `post_clear_suggestion_feature_config_with_metadata` interceptor runs after the + `post_clear_suggestion_feature_config` interceptor. The (possibly modified) response returned by + `post_clear_suggestion_feature_config` will be passed to + `post_clear_suggestion_feature_config_with_metadata`. + """ + return response, metadata + def pre_create_conversation_profile( self, request: gcd_conversation_profile.CreateConversationProfileRequest, @@ -178,12 +201,38 @@ def post_create_conversation_profile( ) -> gcd_conversation_profile.ConversationProfile: """Post-rpc interceptor for create_conversation_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation_profile` interceptor runs + before the `post_create_conversation_profile_with_metadata` interceptor. """ return response + def post_create_conversation_profile_with_metadata( + self, + response: gcd_conversation_profile.ConversationProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_conversation_profile.ConversationProfile, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for create_conversation_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_create_conversation_profile_with_metadata` + interceptor in new development instead of the `post_create_conversation_profile` interceptor. + When both interceptors are used, this `post_create_conversation_profile_with_metadata` interceptor runs after the + `post_create_conversation_profile` interceptor. The (possibly modified) response returned by + `post_create_conversation_profile` will be passed to + `post_create_conversation_profile_with_metadata`. + """ + return response, metadata + def pre_delete_conversation_profile( self, request: conversation_profile.DeleteConversationProfileRequest, @@ -219,12 +268,38 @@ def post_get_conversation_profile( ) -> conversation_profile.ConversationProfile: """Post-rpc interceptor for get_conversation_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation_profile` interceptor runs + before the `post_get_conversation_profile_with_metadata` interceptor. """ return response + def post_get_conversation_profile_with_metadata( + self, + response: conversation_profile.ConversationProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_profile.ConversationProfile, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_conversation_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_get_conversation_profile_with_metadata` + interceptor in new development instead of the `post_get_conversation_profile` interceptor. + When both interceptors are used, this `post_get_conversation_profile_with_metadata` interceptor runs after the + `post_get_conversation_profile` interceptor. The (possibly modified) response returned by + `post_get_conversation_profile` will be passed to + `post_get_conversation_profile_with_metadata`. + """ + return response, metadata + def pre_list_conversation_profiles( self, request: conversation_profile.ListConversationProfilesRequest, @@ -245,12 +320,38 @@ def post_list_conversation_profiles( ) -> conversation_profile.ListConversationProfilesResponse: """Post-rpc interceptor for list_conversation_profiles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversation_profiles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_list_conversation_profiles` interceptor runs + before the `post_list_conversation_profiles_with_metadata` interceptor. """ return response + def post_list_conversation_profiles_with_metadata( + self, + response: conversation_profile.ListConversationProfilesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_profile.ListConversationProfilesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_conversation_profiles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_list_conversation_profiles_with_metadata` + interceptor in new development instead of the `post_list_conversation_profiles` interceptor. + When both interceptors are used, this `post_list_conversation_profiles_with_metadata` interceptor runs after the + `post_list_conversation_profiles` interceptor. The (possibly modified) response returned by + `post_list_conversation_profiles` will be passed to + `post_list_conversation_profiles_with_metadata`. + """ + return response, metadata + def pre_set_suggestion_feature_config( self, request: gcd_conversation_profile.SetSuggestionFeatureConfigRequest, @@ -271,12 +372,35 @@ def post_set_suggestion_feature_config( ) -> operations_pb2.Operation: """Post-rpc interceptor for set_suggestion_feature_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_set_suggestion_feature_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_set_suggestion_feature_config` interceptor runs + before the `post_set_suggestion_feature_config_with_metadata` interceptor. """ return response + def post_set_suggestion_feature_config_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for set_suggestion_feature_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_set_suggestion_feature_config_with_metadata` + interceptor in new development instead of the `post_set_suggestion_feature_config` interceptor. + When both interceptors are used, this `post_set_suggestion_feature_config_with_metadata` interceptor runs after the + `post_set_suggestion_feature_config` interceptor. The (possibly modified) response returned by + `post_set_suggestion_feature_config` will be passed to + `post_set_suggestion_feature_config_with_metadata`. + """ + return response, metadata + def pre_update_conversation_profile( self, request: gcd_conversation_profile.UpdateConversationProfileRequest, @@ -297,12 +421,38 @@ def post_update_conversation_profile( ) -> gcd_conversation_profile.ConversationProfile: """Post-rpc interceptor for update_conversation_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_conversation_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_update_conversation_profile` interceptor runs + before the `post_update_conversation_profile_with_metadata` interceptor. """ return response + def post_update_conversation_profile_with_metadata( + self, + response: gcd_conversation_profile.ConversationProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_conversation_profile.ConversationProfile, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_conversation_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_update_conversation_profile_with_metadata` + interceptor in new development instead of the `post_update_conversation_profile` interceptor. + When both interceptors are used, this `post_update_conversation_profile_with_metadata` interceptor runs after the + `post_update_conversation_profile` interceptor. The (possibly modified) response returned by + `post_update_conversation_profile` will be passed to + `post_update_conversation_profile_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -704,6 +854,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_clear_suggestion_feature_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_clear_suggestion_feature_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -857,6 +1014,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_conversation_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1121,6 +1282,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1270,6 +1435,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversation_profiles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversation_profiles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1426,6 +1595,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_set_suggestion_feature_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_set_suggestion_feature_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1579,6 +1755,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_conversation_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_conversation_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversations/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversations/client.py index 17fa73983973..843fadc65221 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversations/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversations/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -718,6 +720,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1985,16 +2014,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2040,16 +2073,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2150,16 +2187,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2205,16 +2246,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversations/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversations/transports/rest.py index dedf7d20919f..bc7711dc5ef4 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversations/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/conversations/transports/rest.py @@ -169,12 +169,35 @@ def post_complete_conversation( ) -> conversation.Conversation: """Post-rpc interceptor for complete_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_complete_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_complete_conversation` interceptor runs + before the `post_complete_conversation_with_metadata` interceptor. """ return response + def post_complete_conversation_with_metadata( + self, + response: conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for complete_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_complete_conversation_with_metadata` + interceptor in new development instead of the `post_complete_conversation` interceptor. + When both interceptors are used, this `post_complete_conversation_with_metadata` interceptor runs after the + `post_complete_conversation` interceptor. The (possibly modified) response returned by + `post_complete_conversation` will be passed to + `post_complete_conversation_with_metadata`. + """ + return response, metadata + def pre_create_conversation( self, request: gcd_conversation.CreateConversationRequest, @@ -195,12 +218,35 @@ def post_create_conversation( ) -> gcd_conversation.Conversation: """Post-rpc interceptor for create_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation` interceptor runs + before the `post_create_conversation_with_metadata` interceptor. """ return response + def post_create_conversation_with_metadata( + self, + response: gcd_conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_create_conversation_with_metadata` + interceptor in new development instead of the `post_create_conversation` interceptor. + When both interceptors are used, this `post_create_conversation_with_metadata` interceptor runs after the + `post_create_conversation` interceptor. The (possibly modified) response returned by + `post_create_conversation` will be passed to + `post_create_conversation_with_metadata`. + """ + return response, metadata + def pre_generate_stateless_suggestion( self, request: conversation.GenerateStatelessSuggestionRequest, @@ -221,12 +267,38 @@ def post_generate_stateless_suggestion( ) -> conversation.GenerateStatelessSuggestionResponse: """Post-rpc interceptor for generate_stateless_suggestion - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_generate_stateless_suggestion_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_generate_stateless_suggestion` interceptor runs + before the `post_generate_stateless_suggestion_with_metadata` interceptor. """ return response + def post_generate_stateless_suggestion_with_metadata( + self, + response: conversation.GenerateStatelessSuggestionResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.GenerateStatelessSuggestionResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for generate_stateless_suggestion + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_generate_stateless_suggestion_with_metadata` + interceptor in new development instead of the `post_generate_stateless_suggestion` interceptor. + When both interceptors are used, this `post_generate_stateless_suggestion_with_metadata` interceptor runs after the + `post_generate_stateless_suggestion` interceptor. The (possibly modified) response returned by + `post_generate_stateless_suggestion` will be passed to + `post_generate_stateless_suggestion_with_metadata`. + """ + return response, metadata + def pre_generate_stateless_summary( self, request: conversation.GenerateStatelessSummaryRequest, @@ -247,12 +319,38 @@ def post_generate_stateless_summary( ) -> conversation.GenerateStatelessSummaryResponse: """Post-rpc interceptor for generate_stateless_summary - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_generate_stateless_summary_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_generate_stateless_summary` interceptor runs + before the `post_generate_stateless_summary_with_metadata` interceptor. """ return response + def post_generate_stateless_summary_with_metadata( + self, + response: conversation.GenerateStatelessSummaryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.GenerateStatelessSummaryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for generate_stateless_summary + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_generate_stateless_summary_with_metadata` + interceptor in new development instead of the `post_generate_stateless_summary` interceptor. + When both interceptors are used, this `post_generate_stateless_summary_with_metadata` interceptor runs after the + `post_generate_stateless_summary` interceptor. The (possibly modified) response returned by + `post_generate_stateless_summary` will be passed to + `post_generate_stateless_summary_with_metadata`. + """ + return response, metadata + def pre_get_conversation( self, request: conversation.GetConversationRequest, @@ -272,12 +370,35 @@ def post_get_conversation( ) -> conversation.Conversation: """Post-rpc interceptor for get_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation` interceptor runs + before the `post_get_conversation_with_metadata` interceptor. """ return response + def post_get_conversation_with_metadata( + self, + response: conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_get_conversation_with_metadata` + interceptor in new development instead of the `post_get_conversation` interceptor. + When both interceptors are used, this `post_get_conversation_with_metadata` interceptor runs after the + `post_get_conversation` interceptor. The (possibly modified) response returned by + `post_get_conversation` will be passed to + `post_get_conversation_with_metadata`. + """ + return response, metadata + def pre_list_conversations( self, request: conversation.ListConversationsRequest, @@ -297,12 +418,37 @@ def post_list_conversations( ) -> conversation.ListConversationsResponse: """Post-rpc interceptor for list_conversations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_list_conversations` interceptor runs + before the `post_list_conversations_with_metadata` interceptor. """ return response + def post_list_conversations_with_metadata( + self, + response: conversation.ListConversationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.ListConversationsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_conversations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_list_conversations_with_metadata` + interceptor in new development instead of the `post_list_conversations` interceptor. + When both interceptors are used, this `post_list_conversations_with_metadata` interceptor runs after the + `post_list_conversations` interceptor. The (possibly modified) response returned by + `post_list_conversations` will be passed to + `post_list_conversations_with_metadata`. + """ + return response, metadata + def pre_list_messages( self, request: conversation.ListMessagesRequest, @@ -322,12 +468,37 @@ def post_list_messages( ) -> conversation.ListMessagesResponse: """Post-rpc interceptor for list_messages - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_messages_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_list_messages` interceptor runs + before the `post_list_messages_with_metadata` interceptor. """ return response + def post_list_messages_with_metadata( + self, + response: conversation.ListMessagesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.ListMessagesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_messages + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_list_messages_with_metadata` + interceptor in new development instead of the `post_list_messages` interceptor. + When both interceptors are used, this `post_list_messages_with_metadata` interceptor runs after the + `post_list_messages` interceptor. The (possibly modified) response returned by + `post_list_messages` will be passed to + `post_list_messages_with_metadata`. + """ + return response, metadata + def pre_search_knowledge( self, request: conversation.SearchKnowledgeRequest, @@ -347,12 +518,37 @@ def post_search_knowledge( ) -> conversation.SearchKnowledgeResponse: """Post-rpc interceptor for search_knowledge - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_knowledge_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_search_knowledge` interceptor runs + before the `post_search_knowledge_with_metadata` interceptor. """ return response + def post_search_knowledge_with_metadata( + self, + response: conversation.SearchKnowledgeResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.SearchKnowledgeResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for search_knowledge + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_search_knowledge_with_metadata` + interceptor in new development instead of the `post_search_knowledge` interceptor. + When both interceptors are used, this `post_search_knowledge_with_metadata` interceptor runs after the + `post_search_knowledge` interceptor. The (possibly modified) response returned by + `post_search_knowledge` will be passed to + `post_search_knowledge_with_metadata`. + """ + return response, metadata + def pre_suggest_conversation_summary( self, request: gcd_conversation.SuggestConversationSummaryRequest, @@ -373,12 +569,38 @@ def post_suggest_conversation_summary( ) -> gcd_conversation.SuggestConversationSummaryResponse: """Post-rpc interceptor for suggest_conversation_summary - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_conversation_summary_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_suggest_conversation_summary` interceptor runs + before the `post_suggest_conversation_summary_with_metadata` interceptor. """ return response + def post_suggest_conversation_summary_with_metadata( + self, + response: gcd_conversation.SuggestConversationSummaryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_conversation.SuggestConversationSummaryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for suggest_conversation_summary + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_suggest_conversation_summary_with_metadata` + interceptor in new development instead of the `post_suggest_conversation_summary` interceptor. + When both interceptors are used, this `post_suggest_conversation_summary_with_metadata` interceptor runs after the + `post_suggest_conversation_summary` interceptor. The (possibly modified) response returned by + `post_suggest_conversation_summary` will be passed to + `post_suggest_conversation_summary_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -723,6 +945,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_complete_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_complete_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -879,6 +1105,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1034,6 +1264,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_generate_stateless_suggestion(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_generate_stateless_suggestion_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1193,6 +1430,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_generate_stateless_summary(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_generate_stateless_summary_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1345,6 +1586,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1490,6 +1735,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1635,6 +1884,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_messages(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_messages_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1788,6 +2041,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_knowledge(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_knowledge_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1945,6 +2202,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_conversation_summary(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_conversation_summary_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/documents/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/documents/client.py index b8aa3313dbd6..36e2e64129ea 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/documents/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/documents/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -492,6 +494,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1806,16 +1835,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1861,16 +1894,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1971,16 +2008,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2026,16 +2067,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/documents/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/documents/transports/rest.py index 62f13c0eb9a0..e9a920d36de3 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/documents/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/documents/transports/rest.py @@ -160,12 +160,35 @@ def post_create_document( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_create_document` interceptor runs + before the `post_create_document_with_metadata` interceptor. """ return response + def post_create_document_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_create_document_with_metadata` + interceptor in new development instead of the `post_create_document` interceptor. + When both interceptors are used, this `post_create_document_with_metadata` interceptor runs after the + `post_create_document` interceptor. The (possibly modified) response returned by + `post_create_document` will be passed to + `post_create_document_with_metadata`. + """ + return response, metadata + def pre_delete_document( self, request: document.DeleteDocumentRequest, @@ -183,12 +206,35 @@ def post_delete_document( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_delete_document` interceptor runs + before the `post_delete_document_with_metadata` interceptor. """ return response + def post_delete_document_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_delete_document_with_metadata` + interceptor in new development instead of the `post_delete_document` interceptor. + When both interceptors are used, this `post_delete_document_with_metadata` interceptor runs after the + `post_delete_document` interceptor. The (possibly modified) response returned by + `post_delete_document` will be passed to + `post_delete_document_with_metadata`. + """ + return response, metadata + def pre_export_document( self, request: document.ExportDocumentRequest, @@ -206,12 +252,35 @@ def post_export_document( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_export_document` interceptor runs + before the `post_export_document_with_metadata` interceptor. """ return response + def post_export_document_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_export_document_with_metadata` + interceptor in new development instead of the `post_export_document` interceptor. + When both interceptors are used, this `post_export_document_with_metadata` interceptor runs after the + `post_export_document` interceptor. The (possibly modified) response returned by + `post_export_document` will be passed to + `post_export_document_with_metadata`. + """ + return response, metadata + def pre_get_document( self, request: document.GetDocumentRequest, @@ -227,12 +296,35 @@ def pre_get_document( def post_get_document(self, response: document.Document) -> document.Document: """Post-rpc interceptor for get_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_get_document` interceptor runs + before the `post_get_document_with_metadata` interceptor. """ return response + def post_get_document_with_metadata( + self, + response: document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_get_document_with_metadata` + interceptor in new development instead of the `post_get_document` interceptor. + When both interceptors are used, this `post_get_document_with_metadata` interceptor runs after the + `post_get_document` interceptor. The (possibly modified) response returned by + `post_get_document` will be passed to + `post_get_document_with_metadata`. + """ + return response, metadata + def pre_import_documents( self, request: document.ImportDocumentsRequest, @@ -252,12 +344,35 @@ def post_import_documents( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_import_documents` interceptor runs + before the `post_import_documents_with_metadata` interceptor. """ return response + def post_import_documents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_import_documents_with_metadata` + interceptor in new development instead of the `post_import_documents` interceptor. + When both interceptors are used, this `post_import_documents_with_metadata` interceptor runs after the + `post_import_documents` interceptor. The (possibly modified) response returned by + `post_import_documents` will be passed to + `post_import_documents_with_metadata`. + """ + return response, metadata + def pre_list_documents( self, request: document.ListDocumentsRequest, @@ -275,12 +390,35 @@ def post_list_documents( ) -> document.ListDocumentsResponse: """Post-rpc interceptor for list_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_list_documents` interceptor runs + before the `post_list_documents_with_metadata` interceptor. """ return response + def post_list_documents_with_metadata( + self, + response: document.ListDocumentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[document.ListDocumentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_list_documents_with_metadata` + interceptor in new development instead of the `post_list_documents` interceptor. + When both interceptors are used, this `post_list_documents_with_metadata` interceptor runs after the + `post_list_documents` interceptor. The (possibly modified) response returned by + `post_list_documents` will be passed to + `post_list_documents_with_metadata`. + """ + return response, metadata + def pre_reload_document( self, request: document.ReloadDocumentRequest, @@ -298,12 +436,35 @@ def post_reload_document( ) -> operations_pb2.Operation: """Post-rpc interceptor for reload_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_reload_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_reload_document` interceptor runs + before the `post_reload_document_with_metadata` interceptor. """ return response + def post_reload_document_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for reload_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_reload_document_with_metadata` + interceptor in new development instead of the `post_reload_document` interceptor. + When both interceptors are used, this `post_reload_document_with_metadata` interceptor runs after the + `post_reload_document` interceptor. The (possibly modified) response returned by + `post_reload_document` will be passed to + `post_reload_document_with_metadata`. + """ + return response, metadata + def pre_update_document( self, request: gcd_document.UpdateDocumentRequest, @@ -323,12 +484,35 @@ def post_update_document( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_update_document` interceptor runs + before the `post_update_document_with_metadata` interceptor. """ return response + def post_update_document_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_update_document_with_metadata` + interceptor in new development instead of the `post_update_document` interceptor. + When both interceptors are used, this `post_update_document_with_metadata` interceptor runs after the + `post_update_document` interceptor. The (possibly modified) response returned by + `post_update_document` will be passed to + `post_update_document_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -730,6 +914,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -876,6 +1064,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1030,6 +1222,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1182,6 +1378,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1336,6 +1536,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1483,6 +1687,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1637,6 +1845,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_reload_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_reload_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1791,6 +2003,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/encryption_spec_service/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/encryption_spec_service/client.py index 108046c38a84..9a836756f187 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/encryption_spec_service/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/encryption_spec_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -491,6 +493,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -995,16 +1024,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1050,16 +1083,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1160,16 +1197,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1215,16 +1256,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/encryption_spec_service/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/encryption_spec_service/transports/rest.py index 7f490c22127e..335f9136fbcc 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/encryption_spec_service/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/encryption_spec_service/transports/rest.py @@ -113,12 +113,35 @@ def post_get_encryption_spec( ) -> encryption_spec.EncryptionSpec: """Post-rpc interceptor for get_encryption_spec - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_encryption_spec_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EncryptionSpecService server but before - it is returned to user code. + it is returned to user code. This `post_get_encryption_spec` interceptor runs + before the `post_get_encryption_spec_with_metadata` interceptor. """ return response + def post_get_encryption_spec_with_metadata( + self, + response: encryption_spec.EncryptionSpec, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[encryption_spec.EncryptionSpec, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_encryption_spec + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EncryptionSpecService server but before it is returned to user code. + + We recommend only using this `post_get_encryption_spec_with_metadata` + interceptor in new development instead of the `post_get_encryption_spec` interceptor. + When both interceptors are used, this `post_get_encryption_spec_with_metadata` interceptor runs after the + `post_get_encryption_spec` interceptor. The (possibly modified) response returned by + `post_get_encryption_spec` will be passed to + `post_get_encryption_spec_with_metadata`. + """ + return response, metadata + def pre_initialize_encryption_spec( self, request: gcd_encryption_spec.InitializeEncryptionSpecRequest, @@ -139,12 +162,35 @@ def post_initialize_encryption_spec( ) -> operations_pb2.Operation: """Post-rpc interceptor for initialize_encryption_spec - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_initialize_encryption_spec_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EncryptionSpecService server but before - it is returned to user code. + it is returned to user code. This `post_initialize_encryption_spec` interceptor runs + before the `post_initialize_encryption_spec_with_metadata` interceptor. """ return response + def post_initialize_encryption_spec_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for initialize_encryption_spec + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EncryptionSpecService server but before it is returned to user code. + + We recommend only using this `post_initialize_encryption_spec_with_metadata` + interceptor in new development instead of the `post_initialize_encryption_spec` interceptor. + When both interceptors are used, this `post_initialize_encryption_spec_with_metadata` interceptor runs after the + `post_initialize_encryption_spec` interceptor. The (possibly modified) response returned by + `post_initialize_encryption_spec` will be passed to + `post_initialize_encryption_spec_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -541,6 +587,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_encryption_spec(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_encryption_spec_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -693,6 +743,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_initialize_encryption_spec(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_initialize_encryption_spec_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/entity_types/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/entity_types/client.py index ae8a23635e11..d71f1bb7c6b3 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/entity_types/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/entity_types/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -489,6 +491,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2168,16 +2197,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2223,16 +2256,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2333,16 +2370,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2388,16 +2429,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/entity_types/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/entity_types/transports/rest.py index b8a46a27b693..5a01d029e32d 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/entity_types/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/entity_types/transports/rest.py @@ -173,12 +173,35 @@ def post_batch_create_entities( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_create_entities - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_create_entities_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_create_entities` interceptor runs + before the `post_batch_create_entities_with_metadata` interceptor. """ return response + def post_batch_create_entities_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_create_entities + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_create_entities_with_metadata` + interceptor in new development instead of the `post_batch_create_entities` interceptor. + When both interceptors are used, this `post_batch_create_entities_with_metadata` interceptor runs after the + `post_batch_create_entities` interceptor. The (possibly modified) response returned by + `post_batch_create_entities` will be passed to + `post_batch_create_entities_with_metadata`. + """ + return response, metadata + def pre_batch_delete_entities( self, request: entity_type.BatchDeleteEntitiesRequest, @@ -198,12 +221,35 @@ def post_batch_delete_entities( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_delete_entities - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_delete_entities_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_delete_entities` interceptor runs + before the `post_batch_delete_entities_with_metadata` interceptor. """ return response + def post_batch_delete_entities_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_delete_entities + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_delete_entities_with_metadata` + interceptor in new development instead of the `post_batch_delete_entities` interceptor. + When both interceptors are used, this `post_batch_delete_entities_with_metadata` interceptor runs after the + `post_batch_delete_entities` interceptor. The (possibly modified) response returned by + `post_batch_delete_entities` will be passed to + `post_batch_delete_entities_with_metadata`. + """ + return response, metadata + def pre_batch_delete_entity_types( self, request: entity_type.BatchDeleteEntityTypesRequest, @@ -224,12 +270,35 @@ def post_batch_delete_entity_types( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_delete_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_delete_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_delete_entity_types` interceptor runs + before the `post_batch_delete_entity_types_with_metadata` interceptor. """ return response + def post_batch_delete_entity_types_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_delete_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_delete_entity_types_with_metadata` + interceptor in new development instead of the `post_batch_delete_entity_types` interceptor. + When both interceptors are used, this `post_batch_delete_entity_types_with_metadata` interceptor runs after the + `post_batch_delete_entity_types` interceptor. The (possibly modified) response returned by + `post_batch_delete_entity_types` will be passed to + `post_batch_delete_entity_types_with_metadata`. + """ + return response, metadata + def pre_batch_update_entities( self, request: entity_type.BatchUpdateEntitiesRequest, @@ -249,12 +318,35 @@ def post_batch_update_entities( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_update_entities - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_update_entities_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_update_entities` interceptor runs + before the `post_batch_update_entities_with_metadata` interceptor. """ return response + def post_batch_update_entities_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_update_entities + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_update_entities_with_metadata` + interceptor in new development instead of the `post_batch_update_entities` interceptor. + When both interceptors are used, this `post_batch_update_entities_with_metadata` interceptor runs after the + `post_batch_update_entities` interceptor. The (possibly modified) response returned by + `post_batch_update_entities` will be passed to + `post_batch_update_entities_with_metadata`. + """ + return response, metadata + def pre_batch_update_entity_types( self, request: entity_type.BatchUpdateEntityTypesRequest, @@ -275,12 +367,35 @@ def post_batch_update_entity_types( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_update_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_update_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_update_entity_types` interceptor runs + before the `post_batch_update_entity_types_with_metadata` interceptor. """ return response + def post_batch_update_entity_types_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_update_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_update_entity_types_with_metadata` + interceptor in new development instead of the `post_batch_update_entity_types` interceptor. + When both interceptors are used, this `post_batch_update_entity_types_with_metadata` interceptor runs after the + `post_batch_update_entity_types` interceptor. The (possibly modified) response returned by + `post_batch_update_entity_types` will be passed to + `post_batch_update_entity_types_with_metadata`. + """ + return response, metadata + def pre_create_entity_type( self, request: gcd_entity_type.CreateEntityTypeRequest, @@ -300,12 +415,35 @@ def post_create_entity_type( ) -> gcd_entity_type.EntityType: """Post-rpc interceptor for create_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_create_entity_type` interceptor runs + before the `post_create_entity_type_with_metadata` interceptor. """ return response + def post_create_entity_type_with_metadata( + self, + response: gcd_entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_create_entity_type_with_metadata` + interceptor in new development instead of the `post_create_entity_type` interceptor. + When both interceptors are used, this `post_create_entity_type_with_metadata` interceptor runs after the + `post_create_entity_type` interceptor. The (possibly modified) response returned by + `post_create_entity_type` will be passed to + `post_create_entity_type_with_metadata`. + """ + return response, metadata + def pre_delete_entity_type( self, request: entity_type.DeleteEntityTypeRequest, @@ -339,12 +477,35 @@ def post_get_entity_type( ) -> entity_type.EntityType: """Post-rpc interceptor for get_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_get_entity_type` interceptor runs + before the `post_get_entity_type_with_metadata` interceptor. """ return response + def post_get_entity_type_with_metadata( + self, + response: entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_get_entity_type_with_metadata` + interceptor in new development instead of the `post_get_entity_type` interceptor. + When both interceptors are used, this `post_get_entity_type_with_metadata` interceptor runs after the + `post_get_entity_type` interceptor. The (possibly modified) response returned by + `post_get_entity_type` will be passed to + `post_get_entity_type_with_metadata`. + """ + return response, metadata + def pre_list_entity_types( self, request: entity_type.ListEntityTypesRequest, @@ -364,12 +525,37 @@ def post_list_entity_types( ) -> entity_type.ListEntityTypesResponse: """Post-rpc interceptor for list_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_list_entity_types` interceptor runs + before the `post_list_entity_types_with_metadata` interceptor. """ return response + def post_list_entity_types_with_metadata( + self, + response: entity_type.ListEntityTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + entity_type.ListEntityTypesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_list_entity_types_with_metadata` + interceptor in new development instead of the `post_list_entity_types` interceptor. + When both interceptors are used, this `post_list_entity_types_with_metadata` interceptor runs after the + `post_list_entity_types` interceptor. The (possibly modified) response returned by + `post_list_entity_types` will be passed to + `post_list_entity_types_with_metadata`. + """ + return response, metadata + def pre_update_entity_type( self, request: gcd_entity_type.UpdateEntityTypeRequest, @@ -389,12 +575,35 @@ def post_update_entity_type( ) -> gcd_entity_type.EntityType: """Post-rpc interceptor for update_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_update_entity_type` interceptor runs + before the `post_update_entity_type_with_metadata` interceptor. """ return response + def post_update_entity_type_with_metadata( + self, + response: gcd_entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_update_entity_type_with_metadata` + interceptor in new development instead of the `post_update_entity_type` interceptor. + When both interceptors are used, this `post_update_entity_type_with_metadata` interceptor runs after the + `post_update_entity_type` interceptor. The (possibly modified) response returned by + `post_update_entity_type` will be passed to + `post_update_entity_type_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -792,6 +1001,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_create_entities(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_entities_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -942,6 +1155,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_delete_entities(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_delete_entities_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1092,6 +1309,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_delete_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_delete_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1242,6 +1463,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_update_entities(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_entities_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1392,6 +1617,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_update_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1556,6 +1785,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1823,6 +2056,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1968,6 +2205,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2134,6 +2375,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/environments/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/environments/client.py index 34436aa091e8..fc1afc062e4e 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/environments/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/environments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -519,6 +521,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1388,16 +1417,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1443,16 +1476,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1553,16 +1590,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1608,16 +1649,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/environments/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/environments/transports/rest.py index d87f8cb20668..09d53cc4e30a 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/environments/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/environments/transports/rest.py @@ -140,12 +140,35 @@ def post_create_environment( ) -> environment.Environment: """Post-rpc interceptor for create_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_create_environment` interceptor runs + before the `post_create_environment_with_metadata` interceptor. """ return response + def post_create_environment_with_metadata( + self, + response: environment.Environment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.Environment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_create_environment_with_metadata` + interceptor in new development instead of the `post_create_environment` interceptor. + When both interceptors are used, this `post_create_environment_with_metadata` interceptor runs after the + `post_create_environment` interceptor. The (possibly modified) response returned by + `post_create_environment` will be passed to + `post_create_environment_with_metadata`. + """ + return response, metadata + def pre_delete_environment( self, request: environment.DeleteEnvironmentRequest, @@ -179,12 +202,35 @@ def post_get_environment( ) -> environment.Environment: """Post-rpc interceptor for get_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_get_environment` interceptor runs + before the `post_get_environment_with_metadata` interceptor. """ return response + def post_get_environment_with_metadata( + self, + response: environment.Environment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.Environment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_get_environment_with_metadata` + interceptor in new development instead of the `post_get_environment` interceptor. + When both interceptors are used, this `post_get_environment_with_metadata` interceptor runs after the + `post_get_environment` interceptor. The (possibly modified) response returned by + `post_get_environment` will be passed to + `post_get_environment_with_metadata`. + """ + return response, metadata + def pre_get_environment_history( self, request: environment.GetEnvironmentHistoryRequest, @@ -205,12 +251,35 @@ def post_get_environment_history( ) -> environment.EnvironmentHistory: """Post-rpc interceptor for get_environment_history - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_environment_history_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_get_environment_history` interceptor runs + before the `post_get_environment_history_with_metadata` interceptor. """ return response + def post_get_environment_history_with_metadata( + self, + response: environment.EnvironmentHistory, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.EnvironmentHistory, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_environment_history + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_get_environment_history_with_metadata` + interceptor in new development instead of the `post_get_environment_history` interceptor. + When both interceptors are used, this `post_get_environment_history_with_metadata` interceptor runs after the + `post_get_environment_history` interceptor. The (possibly modified) response returned by + `post_get_environment_history` will be passed to + `post_get_environment_history_with_metadata`. + """ + return response, metadata + def pre_list_environments( self, request: environment.ListEnvironmentsRequest, @@ -230,12 +299,37 @@ def post_list_environments( ) -> environment.ListEnvironmentsResponse: """Post-rpc interceptor for list_environments - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_environments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_list_environments` interceptor runs + before the `post_list_environments_with_metadata` interceptor. """ return response + def post_list_environments_with_metadata( + self, + response: environment.ListEnvironmentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + environment.ListEnvironmentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_environments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_list_environments_with_metadata` + interceptor in new development instead of the `post_list_environments` interceptor. + When both interceptors are used, this `post_list_environments_with_metadata` interceptor runs after the + `post_list_environments` interceptor. The (possibly modified) response returned by + `post_list_environments` will be passed to + `post_list_environments_with_metadata`. + """ + return response, metadata + def pre_update_environment( self, request: environment.UpdateEnvironmentRequest, @@ -255,12 +349,35 @@ def post_update_environment( ) -> environment.Environment: """Post-rpc interceptor for update_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_update_environment` interceptor runs + before the `post_update_environment_with_metadata` interceptor. """ return response + def post_update_environment_with_metadata( + self, + response: environment.Environment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.Environment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_update_environment_with_metadata` + interceptor in new development instead of the `post_update_environment` interceptor. + When both interceptors are used, this `post_update_environment_with_metadata` interceptor runs after the + `post_update_environment` interceptor. The (possibly modified) response returned by + `post_update_environment` will be passed to + `post_update_environment_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -617,6 +734,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -886,6 +1007,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1031,6 +1156,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_environment_history(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_environment_history_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1176,6 +1305,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_environments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_environments_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1346,6 +1479,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/fulfillments/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/fulfillments/client.py index 29de5d0c1fbc..41ccdbdca941 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/fulfillments/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/fulfillments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -481,6 +483,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -976,16 +1005,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1031,16 +1064,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1141,16 +1178,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1196,16 +1237,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/fulfillments/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/fulfillments/transports/rest.py index 7abd8284ec17..d28539e0a683 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/fulfillments/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/fulfillments/transports/rest.py @@ -112,12 +112,35 @@ def post_get_fulfillment( ) -> fulfillment.Fulfillment: """Post-rpc interceptor for get_fulfillment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_fulfillment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Fulfillments server but before - it is returned to user code. + it is returned to user code. This `post_get_fulfillment` interceptor runs + before the `post_get_fulfillment_with_metadata` interceptor. """ return response + def post_get_fulfillment_with_metadata( + self, + response: fulfillment.Fulfillment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[fulfillment.Fulfillment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_fulfillment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Fulfillments server but before it is returned to user code. + + We recommend only using this `post_get_fulfillment_with_metadata` + interceptor in new development instead of the `post_get_fulfillment` interceptor. + When both interceptors are used, this `post_get_fulfillment_with_metadata` interceptor runs after the + `post_get_fulfillment` interceptor. The (possibly modified) response returned by + `post_get_fulfillment` will be passed to + `post_get_fulfillment_with_metadata`. + """ + return response, metadata + def pre_update_fulfillment( self, request: gcd_fulfillment.UpdateFulfillmentRequest, @@ -138,12 +161,35 @@ def post_update_fulfillment( ) -> gcd_fulfillment.Fulfillment: """Post-rpc interceptor for update_fulfillment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_fulfillment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Fulfillments server but before - it is returned to user code. + it is returned to user code. This `post_update_fulfillment` interceptor runs + before the `post_update_fulfillment_with_metadata` interceptor. """ return response + def post_update_fulfillment_with_metadata( + self, + response: gcd_fulfillment.Fulfillment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_fulfillment.Fulfillment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_fulfillment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Fulfillments server but before it is returned to user code. + + We recommend only using this `post_update_fulfillment_with_metadata` + interceptor in new development instead of the `post_update_fulfillment` interceptor. + When both interceptors are used, this `post_update_fulfillment_with_metadata` interceptor runs after the + `post_update_fulfillment` interceptor. The (possibly modified) response returned by + `post_update_fulfillment` will be passed to + `post_update_fulfillment_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -485,6 +531,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_fulfillment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_fulfillment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -646,6 +696,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_fulfillment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_fulfillment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/generators/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/generators/client.py index 9adf9f1e6af2..17101756b4ff 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/generators/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/generators/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -493,6 +495,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1305,16 +1334,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1360,16 +1393,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1470,16 +1507,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1525,16 +1566,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/generators/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/generators/transports/rest.py index 61d47b8c4752..87046d863dc6 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/generators/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/generators/transports/rest.py @@ -133,12 +133,35 @@ def post_create_generator( ) -> gcd_generator.Generator: """Post-rpc interceptor for create_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_create_generator` interceptor runs + before the `post_create_generator_with_metadata` interceptor. """ return response + def post_create_generator_with_metadata( + self, + response: gcd_generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_create_generator_with_metadata` + interceptor in new development instead of the `post_create_generator` interceptor. + When both interceptors are used, this `post_create_generator_with_metadata` interceptor runs after the + `post_create_generator` interceptor. The (possibly modified) response returned by + `post_create_generator` will be passed to + `post_create_generator_with_metadata`. + """ + return response, metadata + def pre_delete_generator( self, request: generator.DeleteGeneratorRequest, @@ -168,12 +191,35 @@ def pre_get_generator( def post_get_generator(self, response: generator.Generator) -> generator.Generator: """Post-rpc interceptor for get_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_get_generator` interceptor runs + before the `post_get_generator_with_metadata` interceptor. """ return response + def post_get_generator_with_metadata( + self, + response: generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_get_generator_with_metadata` + interceptor in new development instead of the `post_get_generator` interceptor. + When both interceptors are used, this `post_get_generator_with_metadata` interceptor runs after the + `post_get_generator` interceptor. The (possibly modified) response returned by + `post_get_generator` will be passed to + `post_get_generator_with_metadata`. + """ + return response, metadata + def pre_list_generators( self, request: generator.ListGeneratorsRequest, @@ -193,12 +239,37 @@ def post_list_generators( ) -> generator.ListGeneratorsResponse: """Post-rpc interceptor for list_generators - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_generators_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_list_generators` interceptor runs + before the `post_list_generators_with_metadata` interceptor. """ return response + def post_list_generators_with_metadata( + self, + response: generator.ListGeneratorsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generator.ListGeneratorsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_generators + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_list_generators_with_metadata` + interceptor in new development instead of the `post_list_generators` interceptor. + When both interceptors are used, this `post_list_generators_with_metadata` interceptor runs after the + `post_list_generators` interceptor. The (possibly modified) response returned by + `post_list_generators` will be passed to + `post_list_generators_with_metadata`. + """ + return response, metadata + def pre_update_generator( self, request: gcd_generator.UpdateGeneratorRequest, @@ -218,12 +289,35 @@ def post_update_generator( ) -> gcd_generator.Generator: """Post-rpc interceptor for update_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_update_generator` interceptor runs + before the `post_update_generator_with_metadata` interceptor. """ return response + def post_update_generator_with_metadata( + self, + response: gcd_generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_update_generator_with_metadata` + interceptor in new development instead of the `post_update_generator` interceptor. + When both interceptors are used, this `post_update_generator_with_metadata` interceptor runs after the + `post_update_generator` interceptor. The (possibly modified) response returned by + `post_update_generator` will be passed to + `post_update_generator_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -563,6 +657,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -815,6 +913,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -957,6 +1059,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_generators(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_generators_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1107,6 +1213,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/intents/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/intents/client.py index c1f9782b7085..496ab8060a67 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/intents/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/intents/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -509,6 +511,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1728,16 +1757,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1783,16 +1816,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1893,16 +1930,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1948,16 +1989,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/intents/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/intents/transports/rest.py index ae88e6021ba1..18990b8b3724 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/intents/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/intents/transports/rest.py @@ -149,12 +149,35 @@ def post_batch_delete_intents( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_delete_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_delete_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_batch_delete_intents` interceptor runs + before the `post_batch_delete_intents_with_metadata` interceptor. """ return response + def post_batch_delete_intents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_delete_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_batch_delete_intents_with_metadata` + interceptor in new development instead of the `post_batch_delete_intents` interceptor. + When both interceptors are used, this `post_batch_delete_intents_with_metadata` interceptor runs after the + `post_batch_delete_intents` interceptor. The (possibly modified) response returned by + `post_batch_delete_intents` will be passed to + `post_batch_delete_intents_with_metadata`. + """ + return response, metadata + def pre_batch_update_intents( self, request: intent.BatchUpdateIntentsRequest, @@ -174,12 +197,35 @@ def post_batch_update_intents( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_update_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_update_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_batch_update_intents` interceptor runs + before the `post_batch_update_intents_with_metadata` interceptor. """ return response + def post_batch_update_intents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_update_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_batch_update_intents_with_metadata` + interceptor in new development instead of the `post_batch_update_intents` interceptor. + When both interceptors are used, this `post_batch_update_intents_with_metadata` interceptor runs after the + `post_batch_update_intents` interceptor. The (possibly modified) response returned by + `post_batch_update_intents` will be passed to + `post_batch_update_intents_with_metadata`. + """ + return response, metadata + def pre_create_intent( self, request: gcd_intent.CreateIntentRequest, @@ -195,12 +241,35 @@ def pre_create_intent( def post_create_intent(self, response: gcd_intent.Intent) -> gcd_intent.Intent: """Post-rpc interceptor for create_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_create_intent` interceptor runs + before the `post_create_intent_with_metadata` interceptor. """ return response + def post_create_intent_with_metadata( + self, + response: gcd_intent.Intent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_create_intent_with_metadata` + interceptor in new development instead of the `post_create_intent` interceptor. + When both interceptors are used, this `post_create_intent_with_metadata` interceptor runs after the + `post_create_intent` interceptor. The (possibly modified) response returned by + `post_create_intent` will be passed to + `post_create_intent_with_metadata`. + """ + return response, metadata + def pre_delete_intent( self, request: intent.DeleteIntentRequest, @@ -228,12 +297,33 @@ def pre_get_intent( def post_get_intent(self, response: intent.Intent) -> intent.Intent: """Post-rpc interceptor for get_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_get_intent` interceptor runs + before the `post_get_intent_with_metadata` interceptor. """ return response + def post_get_intent_with_metadata( + self, response: intent.Intent, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_get_intent_with_metadata` + interceptor in new development instead of the `post_get_intent` interceptor. + When both interceptors are used, this `post_get_intent_with_metadata` interceptor runs after the + `post_get_intent` interceptor. The (possibly modified) response returned by + `post_get_intent` will be passed to + `post_get_intent_with_metadata`. + """ + return response, metadata + def pre_list_intents( self, request: intent.ListIntentsRequest, @@ -251,12 +341,35 @@ def post_list_intents( ) -> intent.ListIntentsResponse: """Post-rpc interceptor for list_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_list_intents` interceptor runs + before the `post_list_intents_with_metadata` interceptor. """ return response + def post_list_intents_with_metadata( + self, + response: intent.ListIntentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[intent.ListIntentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_list_intents_with_metadata` + interceptor in new development instead of the `post_list_intents` interceptor. + When both interceptors are used, this `post_list_intents_with_metadata` interceptor runs after the + `post_list_intents` interceptor. The (possibly modified) response returned by + `post_list_intents` will be passed to + `post_list_intents_with_metadata`. + """ + return response, metadata + def pre_update_intent( self, request: gcd_intent.UpdateIntentRequest, @@ -272,12 +385,35 @@ def pre_update_intent( def post_update_intent(self, response: gcd_intent.Intent) -> gcd_intent.Intent: """Post-rpc interceptor for update_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_update_intent` interceptor runs + before the `post_update_intent_with_metadata` interceptor. """ return response + def post_update_intent_with_metadata( + self, + response: gcd_intent.Intent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_update_intent_with_metadata` + interceptor in new development instead of the `post_update_intent` interceptor. + When both interceptors are used, this `post_update_intent_with_metadata` interceptor runs after the + `post_update_intent` interceptor. The (possibly modified) response returned by + `post_update_intent` will be passed to + `post_update_intent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -674,6 +810,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_delete_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_delete_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -823,6 +963,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_update_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -983,6 +1127,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1244,6 +1392,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1389,6 +1541,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1549,6 +1705,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/knowledge_bases/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/knowledge_bases/client.py index b99e22250a11..9923f3a811e2 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/knowledge_bases/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/knowledge_bases/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -488,6 +490,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1340,16 +1369,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1395,16 +1428,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1505,16 +1542,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1560,16 +1601,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/knowledge_bases/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/knowledge_bases/transports/rest.py index a7f8d8cfe37b..f49e0b3db45b 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/knowledge_bases/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/knowledge_bases/transports/rest.py @@ -134,12 +134,37 @@ def post_create_knowledge_base( ) -> gcd_knowledge_base.KnowledgeBase: """Post-rpc interceptor for create_knowledge_base - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_knowledge_base_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the KnowledgeBases server but before - it is returned to user code. + it is returned to user code. This `post_create_knowledge_base` interceptor runs + before the `post_create_knowledge_base_with_metadata` interceptor. """ return response + def post_create_knowledge_base_with_metadata( + self, + response: gcd_knowledge_base.KnowledgeBase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_knowledge_base.KnowledgeBase, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_knowledge_base + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the KnowledgeBases server but before it is returned to user code. + + We recommend only using this `post_create_knowledge_base_with_metadata` + interceptor in new development instead of the `post_create_knowledge_base` interceptor. + When both interceptors are used, this `post_create_knowledge_base_with_metadata` interceptor runs after the + `post_create_knowledge_base` interceptor. The (possibly modified) response returned by + `post_create_knowledge_base` will be passed to + `post_create_knowledge_base_with_metadata`. + """ + return response, metadata + def pre_delete_knowledge_base( self, request: knowledge_base.DeleteKnowledgeBaseRequest, @@ -174,12 +199,35 @@ def post_get_knowledge_base( ) -> knowledge_base.KnowledgeBase: """Post-rpc interceptor for get_knowledge_base - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_knowledge_base_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the KnowledgeBases server but before - it is returned to user code. + it is returned to user code. This `post_get_knowledge_base` interceptor runs + before the `post_get_knowledge_base_with_metadata` interceptor. """ return response + def post_get_knowledge_base_with_metadata( + self, + response: knowledge_base.KnowledgeBase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[knowledge_base.KnowledgeBase, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_knowledge_base + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the KnowledgeBases server but before it is returned to user code. + + We recommend only using this `post_get_knowledge_base_with_metadata` + interceptor in new development instead of the `post_get_knowledge_base` interceptor. + When both interceptors are used, this `post_get_knowledge_base_with_metadata` interceptor runs after the + `post_get_knowledge_base` interceptor. The (possibly modified) response returned by + `post_get_knowledge_base` will be passed to + `post_get_knowledge_base_with_metadata`. + """ + return response, metadata + def pre_list_knowledge_bases( self, request: knowledge_base.ListKnowledgeBasesRequest, @@ -200,12 +248,38 @@ def post_list_knowledge_bases( ) -> knowledge_base.ListKnowledgeBasesResponse: """Post-rpc interceptor for list_knowledge_bases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_knowledge_bases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the KnowledgeBases server but before - it is returned to user code. + it is returned to user code. This `post_list_knowledge_bases` interceptor runs + before the `post_list_knowledge_bases_with_metadata` interceptor. """ return response + def post_list_knowledge_bases_with_metadata( + self, + response: knowledge_base.ListKnowledgeBasesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + knowledge_base.ListKnowledgeBasesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_knowledge_bases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the KnowledgeBases server but before it is returned to user code. + + We recommend only using this `post_list_knowledge_bases_with_metadata` + interceptor in new development instead of the `post_list_knowledge_bases` interceptor. + When both interceptors are used, this `post_list_knowledge_bases_with_metadata` interceptor runs after the + `post_list_knowledge_bases` interceptor. The (possibly modified) response returned by + `post_list_knowledge_bases` will be passed to + `post_list_knowledge_bases_with_metadata`. + """ + return response, metadata + def pre_update_knowledge_base( self, request: gcd_knowledge_base.UpdateKnowledgeBaseRequest, @@ -226,12 +300,37 @@ def post_update_knowledge_base( ) -> gcd_knowledge_base.KnowledgeBase: """Post-rpc interceptor for update_knowledge_base - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_knowledge_base_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the KnowledgeBases server but before - it is returned to user code. + it is returned to user code. This `post_update_knowledge_base` interceptor runs + before the `post_update_knowledge_base_with_metadata` interceptor. """ return response + def post_update_knowledge_base_with_metadata( + self, + response: gcd_knowledge_base.KnowledgeBase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_knowledge_base.KnowledgeBase, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_knowledge_base + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the KnowledgeBases server but before it is returned to user code. + + We recommend only using this `post_update_knowledge_base_with_metadata` + interceptor in new development instead of the `post_update_knowledge_base` interceptor. + When both interceptors are used, this `post_update_knowledge_base_with_metadata` interceptor runs after the + `post_update_knowledge_base` interceptor. The (possibly modified) response returned by + `post_update_knowledge_base` will be passed to + `post_update_knowledge_base_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -582,6 +681,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_knowledge_base(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_knowledge_base_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -849,6 +952,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_knowledge_base(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_knowledge_base_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -994,6 +1101,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_knowledge_bases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_knowledge_bases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1158,6 +1269,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_knowledge_base(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_knowledge_base_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/client.py index e18bada3741f..2addabbda1a7 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -618,6 +620,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2037,16 +2066,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2092,16 +2125,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2202,16 +2239,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2257,16 +2298,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/transports/rest.py index 08618be1bd56..9bba4ea1b5ad 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/participants/transports/rest.py @@ -168,12 +168,37 @@ def post_analyze_content( ) -> gcd_participant.AnalyzeContentResponse: """Post-rpc interceptor for analyze_content - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_analyze_content_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_analyze_content` interceptor runs + before the `post_analyze_content_with_metadata` interceptor. """ return response + def post_analyze_content_with_metadata( + self, + response: gcd_participant.AnalyzeContentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_participant.AnalyzeContentResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for analyze_content + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_analyze_content_with_metadata` + interceptor in new development instead of the `post_analyze_content` interceptor. + When both interceptors are used, this `post_analyze_content_with_metadata` interceptor runs after the + `post_analyze_content` interceptor. The (possibly modified) response returned by + `post_analyze_content` will be passed to + `post_analyze_content_with_metadata`. + """ + return response, metadata + def pre_create_participant( self, request: gcd_participant.CreateParticipantRequest, @@ -194,12 +219,35 @@ def post_create_participant( ) -> gcd_participant.Participant: """Post-rpc interceptor for create_participant - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_participant_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_create_participant` interceptor runs + before the `post_create_participant_with_metadata` interceptor. """ return response + def post_create_participant_with_metadata( + self, + response: gcd_participant.Participant, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_participant.Participant, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_participant + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_create_participant_with_metadata` + interceptor in new development instead of the `post_create_participant` interceptor. + When both interceptors are used, this `post_create_participant_with_metadata` interceptor runs after the + `post_create_participant` interceptor. The (possibly modified) response returned by + `post_create_participant` will be passed to + `post_create_participant_with_metadata`. + """ + return response, metadata + def pre_get_participant( self, request: participant.GetParticipantRequest, @@ -219,12 +267,35 @@ def post_get_participant( ) -> participant.Participant: """Post-rpc interceptor for get_participant - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_participant_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_get_participant` interceptor runs + before the `post_get_participant_with_metadata` interceptor. """ return response + def post_get_participant_with_metadata( + self, + response: participant.Participant, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[participant.Participant, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_participant + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_get_participant_with_metadata` + interceptor in new development instead of the `post_get_participant` interceptor. + When both interceptors are used, this `post_get_participant_with_metadata` interceptor runs after the + `post_get_participant` interceptor. The (possibly modified) response returned by + `post_get_participant` will be passed to + `post_get_participant_with_metadata`. + """ + return response, metadata + def pre_list_participants( self, request: participant.ListParticipantsRequest, @@ -244,12 +315,37 @@ def post_list_participants( ) -> participant.ListParticipantsResponse: """Post-rpc interceptor for list_participants - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_participants_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_list_participants` interceptor runs + before the `post_list_participants_with_metadata` interceptor. """ return response + def post_list_participants_with_metadata( + self, + response: participant.ListParticipantsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.ListParticipantsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_participants + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_list_participants_with_metadata` + interceptor in new development instead of the `post_list_participants` interceptor. + When both interceptors are used, this `post_list_participants_with_metadata` interceptor runs after the + `post_list_participants` interceptor. The (possibly modified) response returned by + `post_list_participants` will be passed to + `post_list_participants_with_metadata`. + """ + return response, metadata + def pre_suggest_articles( self, request: participant.SuggestArticlesRequest, @@ -269,12 +365,37 @@ def post_suggest_articles( ) -> participant.SuggestArticlesResponse: """Post-rpc interceptor for suggest_articles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_articles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_suggest_articles` interceptor runs + before the `post_suggest_articles_with_metadata` interceptor. """ return response + def post_suggest_articles_with_metadata( + self, + response: participant.SuggestArticlesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.SuggestArticlesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for suggest_articles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_suggest_articles_with_metadata` + interceptor in new development instead of the `post_suggest_articles` interceptor. + When both interceptors are used, this `post_suggest_articles_with_metadata` interceptor runs after the + `post_suggest_articles` interceptor. The (possibly modified) response returned by + `post_suggest_articles` will be passed to + `post_suggest_articles_with_metadata`. + """ + return response, metadata + def pre_suggest_faq_answers( self, request: participant.SuggestFaqAnswersRequest, @@ -294,12 +415,37 @@ def post_suggest_faq_answers( ) -> participant.SuggestFaqAnswersResponse: """Post-rpc interceptor for suggest_faq_answers - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_faq_answers_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_suggest_faq_answers` interceptor runs + before the `post_suggest_faq_answers_with_metadata` interceptor. """ return response + def post_suggest_faq_answers_with_metadata( + self, + response: participant.SuggestFaqAnswersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.SuggestFaqAnswersResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for suggest_faq_answers + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_suggest_faq_answers_with_metadata` + interceptor in new development instead of the `post_suggest_faq_answers` interceptor. + When both interceptors are used, this `post_suggest_faq_answers_with_metadata` interceptor runs after the + `post_suggest_faq_answers` interceptor. The (possibly modified) response returned by + `post_suggest_faq_answers` will be passed to + `post_suggest_faq_answers_with_metadata`. + """ + return response, metadata + def pre_suggest_knowledge_assist( self, request: participant.SuggestKnowledgeAssistRequest, @@ -320,12 +466,38 @@ def post_suggest_knowledge_assist( ) -> participant.SuggestKnowledgeAssistResponse: """Post-rpc interceptor for suggest_knowledge_assist - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_knowledge_assist_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_suggest_knowledge_assist` interceptor runs + before the `post_suggest_knowledge_assist_with_metadata` interceptor. """ return response + def post_suggest_knowledge_assist_with_metadata( + self, + response: participant.SuggestKnowledgeAssistResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.SuggestKnowledgeAssistResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for suggest_knowledge_assist + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_suggest_knowledge_assist_with_metadata` + interceptor in new development instead of the `post_suggest_knowledge_assist` interceptor. + When both interceptors are used, this `post_suggest_knowledge_assist_with_metadata` interceptor runs after the + `post_suggest_knowledge_assist` interceptor. The (possibly modified) response returned by + `post_suggest_knowledge_assist` will be passed to + `post_suggest_knowledge_assist_with_metadata`. + """ + return response, metadata + def pre_suggest_smart_replies( self, request: participant.SuggestSmartRepliesRequest, @@ -345,12 +517,37 @@ def post_suggest_smart_replies( ) -> participant.SuggestSmartRepliesResponse: """Post-rpc interceptor for suggest_smart_replies - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_smart_replies_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_suggest_smart_replies` interceptor runs + before the `post_suggest_smart_replies_with_metadata` interceptor. """ return response + def post_suggest_smart_replies_with_metadata( + self, + response: participant.SuggestSmartRepliesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.SuggestSmartRepliesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for suggest_smart_replies + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_suggest_smart_replies_with_metadata` + interceptor in new development instead of the `post_suggest_smart_replies` interceptor. + When both interceptors are used, this `post_suggest_smart_replies_with_metadata` interceptor runs after the + `post_suggest_smart_replies` interceptor. The (possibly modified) response returned by + `post_suggest_smart_replies` will be passed to + `post_suggest_smart_replies_with_metadata`. + """ + return response, metadata + def pre_update_participant( self, request: gcd_participant.UpdateParticipantRequest, @@ -371,12 +568,35 @@ def post_update_participant( ) -> gcd_participant.Participant: """Post-rpc interceptor for update_participant - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_participant_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_update_participant` interceptor runs + before the `post_update_participant_with_metadata` interceptor. """ return response + def post_update_participant_with_metadata( + self, + response: gcd_participant.Participant, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_participant.Participant, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_participant + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_update_participant_with_metadata` + interceptor in new development instead of the `post_update_participant` interceptor. + When both interceptors are used, this `post_update_participant_with_metadata` interceptor runs after the + `post_update_participant` interceptor. The (possibly modified) response returned by + `post_update_participant` will be passed to + `post_update_participant_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -714,6 +934,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_analyze_content(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_analyze_content_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -867,6 +1091,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_participant(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_participant_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1010,6 +1238,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_participant(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_participant_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1155,6 +1387,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_participants(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_participants_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1327,6 +1563,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_articles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_articles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1480,6 +1720,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_faq_answers(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_faq_answers_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1633,6 +1877,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_knowledge_assist(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_knowledge_assist_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1786,6 +2034,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_smart_replies(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_smart_replies_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1939,6 +2191,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_participant(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_participant_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/session_entity_types/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/session_entity_types/client.py index 397fa8434e00..830d8722efd2 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/session_entity_types/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/session_entity_types/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -494,6 +496,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1404,16 +1433,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1459,16 +1492,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1569,16 +1606,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1624,16 +1665,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/session_entity_types/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/session_entity_types/transports/rest.py index 0304c6a29855..ad6d7fc71693 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/session_entity_types/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/session_entity_types/transports/rest.py @@ -136,12 +136,38 @@ def post_create_session_entity_type( ) -> gcd_session_entity_type.SessionEntityType: """Post-rpc interceptor for create_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_create_session_entity_type` interceptor runs + before the `post_create_session_entity_type_with_metadata` interceptor. """ return response + def post_create_session_entity_type_with_metadata( + self, + response: gcd_session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_session_entity_type.SessionEntityType, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for create_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_create_session_entity_type_with_metadata` + interceptor in new development instead of the `post_create_session_entity_type` interceptor. + When both interceptors are used, this `post_create_session_entity_type_with_metadata` interceptor runs after the + `post_create_session_entity_type` interceptor. The (possibly modified) response returned by + `post_create_session_entity_type` will be passed to + `post_create_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_delete_session_entity_type( self, request: session_entity_type.DeleteSessionEntityTypeRequest, @@ -177,12 +203,37 @@ def post_get_session_entity_type( ) -> session_entity_type.SessionEntityType: """Post-rpc interceptor for get_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_get_session_entity_type` interceptor runs + before the `post_get_session_entity_type_with_metadata` interceptor. """ return response + def post_get_session_entity_type_with_metadata( + self, + response: session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_entity_type.SessionEntityType, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_get_session_entity_type_with_metadata` + interceptor in new development instead of the `post_get_session_entity_type` interceptor. + When both interceptors are used, this `post_get_session_entity_type_with_metadata` interceptor runs after the + `post_get_session_entity_type` interceptor. The (possibly modified) response returned by + `post_get_session_entity_type` will be passed to + `post_get_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_list_session_entity_types( self, request: session_entity_type.ListSessionEntityTypesRequest, @@ -203,12 +254,38 @@ def post_list_session_entity_types( ) -> session_entity_type.ListSessionEntityTypesResponse: """Post-rpc interceptor for list_session_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_session_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_list_session_entity_types` interceptor runs + before the `post_list_session_entity_types_with_metadata` interceptor. """ return response + def post_list_session_entity_types_with_metadata( + self, + response: session_entity_type.ListSessionEntityTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_entity_type.ListSessionEntityTypesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_session_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_list_session_entity_types_with_metadata` + interceptor in new development instead of the `post_list_session_entity_types` interceptor. + When both interceptors are used, this `post_list_session_entity_types_with_metadata` interceptor runs after the + `post_list_session_entity_types` interceptor. The (possibly modified) response returned by + `post_list_session_entity_types` will be passed to + `post_list_session_entity_types_with_metadata`. + """ + return response, metadata + def pre_update_session_entity_type( self, request: gcd_session_entity_type.UpdateSessionEntityTypeRequest, @@ -229,12 +306,38 @@ def post_update_session_entity_type( ) -> gcd_session_entity_type.SessionEntityType: """Post-rpc interceptor for update_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_update_session_entity_type` interceptor runs + before the `post_update_session_entity_type_with_metadata` interceptor. """ return response + def post_update_session_entity_type_with_metadata( + self, + response: gcd_session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_session_entity_type.SessionEntityType, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_update_session_entity_type_with_metadata` + interceptor in new development instead of the `post_update_session_entity_type` interceptor. + When both interceptors are used, this `post_update_session_entity_type_with_metadata` interceptor runs after the + `post_update_session_entity_type` interceptor. The (possibly modified) response returned by + `post_update_session_entity_type` will be passed to + `post_update_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -586,6 +689,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -857,6 +964,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1007,6 +1118,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_session_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_session_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1174,6 +1289,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/sessions/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/sessions/client.py index 46d575903adb..06238cfe529c 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/sessions/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/sessions/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -573,6 +575,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1140,16 +1169,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1195,16 +1228,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1305,16 +1342,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1360,16 +1401,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/sessions/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/sessions/transports/rest.py index 8ff4d4772a99..56bfd9187037 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/sessions/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/sessions/transports/rest.py @@ -104,12 +104,37 @@ def post_detect_intent( ) -> gcd_session.DetectIntentResponse: """Post-rpc interceptor for detect_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_detect_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_detect_intent` interceptor runs + before the `post_detect_intent_with_metadata` interceptor. """ return response + def post_detect_intent_with_metadata( + self, + response: gcd_session.DetectIntentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_session.DetectIntentResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for detect_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_detect_intent_with_metadata` + interceptor in new development instead of the `post_detect_intent` interceptor. + When both interceptors are used, this `post_detect_intent_with_metadata` interceptor runs after the + `post_detect_intent` interceptor. The (possibly modified) response returned by + `post_detect_intent` will be passed to + `post_detect_intent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -448,6 +473,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_detect_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_detect_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/versions/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/versions/client.py index abf88d652e3f..5dff2cf4ad03 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/versions/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/versions/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -485,6 +487,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1361,16 +1390,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1416,16 +1449,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1526,16 +1563,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1581,16 +1622,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/versions/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/versions/transports/rest.py index 2d6e0d717708..55b72ac3cd3f 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/versions/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2/services/versions/transports/rest.py @@ -131,12 +131,35 @@ def pre_create_version( def post_create_version(self, response: gcd_version.Version) -> gcd_version.Version: """Post-rpc interceptor for create_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_create_version` interceptor runs + before the `post_create_version_with_metadata` interceptor. """ return response + def post_create_version_with_metadata( + self, + response: gcd_version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_create_version_with_metadata` + interceptor in new development instead of the `post_create_version` interceptor. + When both interceptors are used, this `post_create_version_with_metadata` interceptor runs after the + `post_create_version` interceptor. The (possibly modified) response returned by + `post_create_version` will be passed to + `post_create_version_with_metadata`. + """ + return response, metadata + def pre_delete_version( self, request: version.DeleteVersionRequest, @@ -164,12 +187,35 @@ def pre_get_version( def post_get_version(self, response: version.Version) -> version.Version: """Post-rpc interceptor for get_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_get_version` interceptor runs + before the `post_get_version_with_metadata` interceptor. """ return response + def post_get_version_with_metadata( + self, + response: version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_get_version_with_metadata` + interceptor in new development instead of the `post_get_version` interceptor. + When both interceptors are used, this `post_get_version_with_metadata` interceptor runs after the + `post_get_version` interceptor. The (possibly modified) response returned by + `post_get_version` will be passed to + `post_get_version_with_metadata`. + """ + return response, metadata + def pre_list_versions( self, request: version.ListVersionsRequest, @@ -187,12 +233,35 @@ def post_list_versions( ) -> version.ListVersionsResponse: """Post-rpc interceptor for list_versions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_versions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_list_versions` interceptor runs + before the `post_list_versions_with_metadata` interceptor. """ return response + def post_list_versions_with_metadata( + self, + response: version.ListVersionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[version.ListVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_versions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_list_versions_with_metadata` + interceptor in new development instead of the `post_list_versions` interceptor. + When both interceptors are used, this `post_list_versions_with_metadata` interceptor runs after the + `post_list_versions` interceptor. The (possibly modified) response returned by + `post_list_versions` will be passed to + `post_list_versions_with_metadata`. + """ + return response, metadata + def pre_update_version( self, request: gcd_version.UpdateVersionRequest, @@ -210,12 +279,35 @@ def pre_update_version( def post_update_version(self, response: gcd_version.Version) -> gcd_version.Version: """Post-rpc interceptor for update_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_update_version` interceptor runs + before the `post_update_version_with_metadata` interceptor. """ return response + def post_update_version_with_metadata( + self, + response: gcd_version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_update_version_with_metadata` + interceptor in new development instead of the `post_update_version` interceptor. + When both interceptors are used, this `post_update_version_with_metadata` interceptor runs after the + `post_update_version` interceptor. The (possibly modified) response returned by + `post_update_version` will be passed to + `post_update_version_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -573,6 +665,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -846,6 +942,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -991,6 +1091,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_versions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_versions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1161,6 +1265,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/gapic_version.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/gapic_version.py index 75872a31e259..558c8aab67c5 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/gapic_version.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "2.38.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/agents/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/agents/client.py index 29501e1892cd..fad16181b77b 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/agents/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/agents/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -486,6 +488,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1820,16 +1849,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1875,16 +1908,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1985,16 +2022,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2040,16 +2081,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/agents/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/agents/transports/rest.py index 86631cf4c344..a1eab16f64f9 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/agents/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/agents/transports/rest.py @@ -176,12 +176,35 @@ def post_export_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_export_agent` interceptor runs + before the `post_export_agent_with_metadata` interceptor. """ return response + def post_export_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_export_agent_with_metadata` + interceptor in new development instead of the `post_export_agent` interceptor. + When both interceptors are used, this `post_export_agent_with_metadata` interceptor runs after the + `post_export_agent` interceptor. The (possibly modified) response returned by + `post_export_agent` will be passed to + `post_export_agent_with_metadata`. + """ + return response, metadata + def pre_get_agent( self, request: agent.GetAgentRequest, @@ -197,12 +220,33 @@ def pre_get_agent( def post_get_agent(self, response: agent.Agent) -> agent.Agent: """Post-rpc interceptor for get_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_agent` interceptor runs + before the `post_get_agent_with_metadata` interceptor. """ return response + def post_get_agent_with_metadata( + self, response: agent.Agent, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_agent_with_metadata` + interceptor in new development instead of the `post_get_agent` interceptor. + When both interceptors are used, this `post_get_agent_with_metadata` interceptor runs after the + `post_get_agent` interceptor. The (possibly modified) response returned by + `post_get_agent` will be passed to + `post_get_agent_with_metadata`. + """ + return response, metadata + def pre_get_validation_result( self, request: agent.GetValidationResultRequest, @@ -222,12 +266,37 @@ def post_get_validation_result( ) -> validation_result.ValidationResult: """Post-rpc interceptor for get_validation_result - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_validation_result_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_get_validation_result` interceptor runs + before the `post_get_validation_result_with_metadata` interceptor. """ return response + def post_get_validation_result_with_metadata( + self, + response: validation_result.ValidationResult, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + validation_result.ValidationResult, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_validation_result + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_get_validation_result_with_metadata` + interceptor in new development instead of the `post_get_validation_result` interceptor. + When both interceptors are used, this `post_get_validation_result_with_metadata` interceptor runs after the + `post_get_validation_result` interceptor. The (possibly modified) response returned by + `post_get_validation_result` will be passed to + `post_get_validation_result_with_metadata`. + """ + return response, metadata + def pre_import_agent( self, request: agent.ImportAgentRequest, @@ -245,12 +314,35 @@ def post_import_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_import_agent` interceptor runs + before the `post_import_agent_with_metadata` interceptor. """ return response + def post_import_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_import_agent_with_metadata` + interceptor in new development instead of the `post_import_agent` interceptor. + When both interceptors are used, this `post_import_agent_with_metadata` interceptor runs after the + `post_import_agent` interceptor. The (possibly modified) response returned by + `post_import_agent` will be passed to + `post_import_agent_with_metadata`. + """ + return response, metadata + def pre_restore_agent( self, request: agent.RestoreAgentRequest, @@ -268,12 +360,35 @@ def post_restore_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for restore_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_restore_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_restore_agent` interceptor runs + before the `post_restore_agent_with_metadata` interceptor. """ return response + def post_restore_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for restore_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_restore_agent_with_metadata` + interceptor in new development instead of the `post_restore_agent` interceptor. + When both interceptors are used, this `post_restore_agent_with_metadata` interceptor runs after the + `post_restore_agent` interceptor. The (possibly modified) response returned by + `post_restore_agent` will be passed to + `post_restore_agent_with_metadata`. + """ + return response, metadata + def pre_search_agents( self, request: agent.SearchAgentsRequest, @@ -291,12 +406,35 @@ def post_search_agents( ) -> agent.SearchAgentsResponse: """Post-rpc interceptor for search_agents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_agents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_search_agents` interceptor runs + before the `post_search_agents_with_metadata` interceptor. """ return response + def post_search_agents_with_metadata( + self, + response: agent.SearchAgentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[agent.SearchAgentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search_agents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_search_agents_with_metadata` + interceptor in new development instead of the `post_search_agents` interceptor. + When both interceptors are used, this `post_search_agents_with_metadata` interceptor runs after the + `post_search_agents` interceptor. The (possibly modified) response returned by + `post_search_agents` will be passed to + `post_search_agents_with_metadata`. + """ + return response, metadata + def pre_set_agent( self, request: gcd_agent.SetAgentRequest, @@ -312,12 +450,35 @@ def pre_set_agent( def post_set_agent(self, response: gcd_agent.Agent) -> gcd_agent.Agent: """Post-rpc interceptor for set_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_set_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_set_agent` interceptor runs + before the `post_set_agent_with_metadata` interceptor. """ return response + def post_set_agent_with_metadata( + self, + response: gcd_agent.Agent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_agent.Agent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for set_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_set_agent_with_metadata` + interceptor in new development instead of the `post_set_agent` interceptor. + When both interceptors are used, this `post_set_agent_with_metadata` interceptor runs after the + `post_set_agent` interceptor. The (possibly modified) response returned by + `post_set_agent` will be passed to + `post_set_agent_with_metadata`. + """ + return response, metadata + def pre_train_agent( self, request: agent.TrainAgentRequest, @@ -335,12 +496,35 @@ def post_train_agent( ) -> operations_pb2.Operation: """Post-rpc interceptor for train_agent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_train_agent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Agents server but before - it is returned to user code. + it is returned to user code. This `post_train_agent` interceptor runs + before the `post_train_agent_with_metadata` interceptor. """ return response + def post_train_agent_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for train_agent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Agents server but before it is returned to user code. + + We recommend only using this `post_train_agent_with_metadata` + interceptor in new development instead of the `post_train_agent` interceptor. + When both interceptors are used, this `post_train_agent_with_metadata` interceptor runs after the + `post_train_agent` interceptor. The (possibly modified) response returned by + `post_train_agent` will be passed to + `post_train_agent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -843,6 +1027,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -996,6 +1184,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1141,6 +1333,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_validation_result(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_validation_result_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1291,6 +1487,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1441,6 +1641,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_restore_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_restore_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1586,6 +1790,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_agents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_agents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1745,6 +1953,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_set_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_set_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1893,6 +2105,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_train_agent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_train_agent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/client.py index a0e39a9c03c6..5625311bd68c 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -547,6 +549,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1189,16 +1218,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1244,16 +1277,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1354,16 +1391,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1409,16 +1450,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/transports/rest.py index b18d5c593c80..35d32caaf516 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/answer_records/transports/rest.py @@ -120,12 +120,35 @@ def post_get_answer_record( ) -> answer_record.AnswerRecord: """Post-rpc interceptor for get_answer_record - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_answer_record_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AnswerRecords server but before - it is returned to user code. + it is returned to user code. This `post_get_answer_record` interceptor runs + before the `post_get_answer_record_with_metadata` interceptor. """ return response + def post_get_answer_record_with_metadata( + self, + response: answer_record.AnswerRecord, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[answer_record.AnswerRecord, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_answer_record + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AnswerRecords server but before it is returned to user code. + + We recommend only using this `post_get_answer_record_with_metadata` + interceptor in new development instead of the `post_get_answer_record` interceptor. + When both interceptors are used, this `post_get_answer_record_with_metadata` interceptor runs after the + `post_get_answer_record` interceptor. The (possibly modified) response returned by + `post_get_answer_record` will be passed to + `post_get_answer_record_with_metadata`. + """ + return response, metadata + def pre_list_answer_records( self, request: answer_record.ListAnswerRecordsRequest, @@ -145,12 +168,37 @@ def post_list_answer_records( ) -> answer_record.ListAnswerRecordsResponse: """Post-rpc interceptor for list_answer_records - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_answer_records_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AnswerRecords server but before - it is returned to user code. + it is returned to user code. This `post_list_answer_records` interceptor runs + before the `post_list_answer_records_with_metadata` interceptor. """ return response + def post_list_answer_records_with_metadata( + self, + response: answer_record.ListAnswerRecordsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + answer_record.ListAnswerRecordsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_answer_records + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AnswerRecords server but before it is returned to user code. + + We recommend only using this `post_list_answer_records_with_metadata` + interceptor in new development instead of the `post_list_answer_records` interceptor. + When both interceptors are used, this `post_list_answer_records_with_metadata` interceptor runs after the + `post_list_answer_records` interceptor. The (possibly modified) response returned by + `post_list_answer_records` will be passed to + `post_list_answer_records_with_metadata`. + """ + return response, metadata + def pre_update_answer_record( self, request: gcd_answer_record.UpdateAnswerRecordRequest, @@ -171,12 +219,35 @@ def post_update_answer_record( ) -> gcd_answer_record.AnswerRecord: """Post-rpc interceptor for update_answer_record - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_answer_record_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AnswerRecords server but before - it is returned to user code. + it is returned to user code. This `post_update_answer_record` interceptor runs + before the `post_update_answer_record_with_metadata` interceptor. """ return response + def post_update_answer_record_with_metadata( + self, + response: gcd_answer_record.AnswerRecord, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_answer_record.AnswerRecord, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_answer_record + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AnswerRecords server but before it is returned to user code. + + We recommend only using this `post_update_answer_record_with_metadata` + interceptor in new development instead of the `post_update_answer_record` interceptor. + When both interceptors are used, this `post_update_answer_record_with_metadata` interceptor runs after the + `post_update_answer_record` interceptor. The (possibly modified) response returned by + `post_update_answer_record` will be passed to + `post_update_answer_record_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -539,6 +610,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_answer_record(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_answer_record_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -684,6 +759,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_answer_records(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_answer_records_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -866,6 +945,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_answer_record(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_answer_record_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/contexts/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/contexts/client.py index 7bdd79509b8c..df4e1ee90123 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/contexts/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/contexts/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -490,6 +492,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1482,16 +1511,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1537,16 +1570,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1647,16 +1684,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1702,16 +1743,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/contexts/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/contexts/transports/rest.py index ca1a92be3248..0083647adee2 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/contexts/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/contexts/transports/rest.py @@ -135,12 +135,35 @@ def pre_create_context( def post_create_context(self, response: gcd_context.Context) -> gcd_context.Context: """Post-rpc interceptor for create_context - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_context_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Contexts server but before - it is returned to user code. + it is returned to user code. This `post_create_context` interceptor runs + before the `post_create_context_with_metadata` interceptor. """ return response + def post_create_context_with_metadata( + self, + response: gcd_context.Context, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_context.Context, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_context + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Contexts server but before it is returned to user code. + + We recommend only using this `post_create_context_with_metadata` + interceptor in new development instead of the `post_create_context` interceptor. + When both interceptors are used, this `post_create_context_with_metadata` interceptor runs after the + `post_create_context` interceptor. The (possibly modified) response returned by + `post_create_context` will be passed to + `post_create_context_with_metadata`. + """ + return response, metadata + def pre_delete_all_contexts( self, request: context.DeleteAllContextsRequest, @@ -182,12 +205,35 @@ def pre_get_context( def post_get_context(self, response: context.Context) -> context.Context: """Post-rpc interceptor for get_context - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_context_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Contexts server but before - it is returned to user code. + it is returned to user code. This `post_get_context` interceptor runs + before the `post_get_context_with_metadata` interceptor. """ return response + def post_get_context_with_metadata( + self, + response: context.Context, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[context.Context, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_context + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Contexts server but before it is returned to user code. + + We recommend only using this `post_get_context_with_metadata` + interceptor in new development instead of the `post_get_context` interceptor. + When both interceptors are used, this `post_get_context_with_metadata` interceptor runs after the + `post_get_context` interceptor. The (possibly modified) response returned by + `post_get_context` will be passed to + `post_get_context_with_metadata`. + """ + return response, metadata + def pre_list_contexts( self, request: context.ListContextsRequest, @@ -205,12 +251,35 @@ def post_list_contexts( ) -> context.ListContextsResponse: """Post-rpc interceptor for list_contexts - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_contexts_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Contexts server but before - it is returned to user code. + it is returned to user code. This `post_list_contexts` interceptor runs + before the `post_list_contexts_with_metadata` interceptor. """ return response + def post_list_contexts_with_metadata( + self, + response: context.ListContextsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[context.ListContextsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_contexts + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Contexts server but before it is returned to user code. + + We recommend only using this `post_list_contexts_with_metadata` + interceptor in new development instead of the `post_list_contexts` interceptor. + When both interceptors are used, this `post_list_contexts_with_metadata` interceptor runs after the + `post_list_contexts` interceptor. The (possibly modified) response returned by + `post_list_contexts` will be passed to + `post_list_contexts_with_metadata`. + """ + return response, metadata + def pre_update_context( self, request: gcd_context.UpdateContextRequest, @@ -228,12 +297,35 @@ def pre_update_context( def post_update_context(self, response: gcd_context.Context) -> gcd_context.Context: """Post-rpc interceptor for update_context - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_context_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Contexts server but before - it is returned to user code. + it is returned to user code. This `post_update_context` interceptor runs + before the `post_update_context_with_metadata` interceptor. """ return response + def post_update_context_with_metadata( + self, + response: gcd_context.Context, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_context.Context, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_context + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Contexts server but before it is returned to user code. + + We recommend only using this `post_update_context_with_metadata` + interceptor in new development instead of the `post_update_context` interceptor. + When both interceptors are used, this `post_update_context_with_metadata` interceptor runs after the + `post_update_context` interceptor. The (possibly modified) response returned by + `post_update_context` will be passed to + `post_update_context_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -592,6 +684,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_context(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_context_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -974,6 +1070,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_context(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_context_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1119,6 +1219,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_contexts(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_contexts_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1289,6 +1393,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_context(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_context_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/client.py index 5dd5e881b7e3..74546aea7c5c 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -640,6 +642,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1850,16 +1879,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1905,16 +1938,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2015,16 +2052,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2070,16 +2111,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/transports/rest.py index c6c0e21d77b5..24dac5fd3c0e 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversation_profiles/transports/rest.py @@ -152,12 +152,35 @@ def post_clear_suggestion_feature_config( ) -> operations_pb2.Operation: """Post-rpc interceptor for clear_suggestion_feature_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_clear_suggestion_feature_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_clear_suggestion_feature_config` interceptor runs + before the `post_clear_suggestion_feature_config_with_metadata` interceptor. """ return response + def post_clear_suggestion_feature_config_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for clear_suggestion_feature_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_clear_suggestion_feature_config_with_metadata` + interceptor in new development instead of the `post_clear_suggestion_feature_config` interceptor. + When both interceptors are used, this `post_clear_suggestion_feature_config_with_metadata` interceptor runs after the + `post_clear_suggestion_feature_config` interceptor. The (possibly modified) response returned by + `post_clear_suggestion_feature_config` will be passed to + `post_clear_suggestion_feature_config_with_metadata`. + """ + return response, metadata + def pre_create_conversation_profile( self, request: gcd_conversation_profile.CreateConversationProfileRequest, @@ -178,12 +201,38 @@ def post_create_conversation_profile( ) -> gcd_conversation_profile.ConversationProfile: """Post-rpc interceptor for create_conversation_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation_profile` interceptor runs + before the `post_create_conversation_profile_with_metadata` interceptor. """ return response + def post_create_conversation_profile_with_metadata( + self, + response: gcd_conversation_profile.ConversationProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_conversation_profile.ConversationProfile, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for create_conversation_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_create_conversation_profile_with_metadata` + interceptor in new development instead of the `post_create_conversation_profile` interceptor. + When both interceptors are used, this `post_create_conversation_profile_with_metadata` interceptor runs after the + `post_create_conversation_profile` interceptor. The (possibly modified) response returned by + `post_create_conversation_profile` will be passed to + `post_create_conversation_profile_with_metadata`. + """ + return response, metadata + def pre_delete_conversation_profile( self, request: conversation_profile.DeleteConversationProfileRequest, @@ -219,12 +268,38 @@ def post_get_conversation_profile( ) -> conversation_profile.ConversationProfile: """Post-rpc interceptor for get_conversation_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation_profile` interceptor runs + before the `post_get_conversation_profile_with_metadata` interceptor. """ return response + def post_get_conversation_profile_with_metadata( + self, + response: conversation_profile.ConversationProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_profile.ConversationProfile, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_conversation_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_get_conversation_profile_with_metadata` + interceptor in new development instead of the `post_get_conversation_profile` interceptor. + When both interceptors are used, this `post_get_conversation_profile_with_metadata` interceptor runs after the + `post_get_conversation_profile` interceptor. The (possibly modified) response returned by + `post_get_conversation_profile` will be passed to + `post_get_conversation_profile_with_metadata`. + """ + return response, metadata + def pre_list_conversation_profiles( self, request: conversation_profile.ListConversationProfilesRequest, @@ -245,12 +320,38 @@ def post_list_conversation_profiles( ) -> conversation_profile.ListConversationProfilesResponse: """Post-rpc interceptor for list_conversation_profiles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversation_profiles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_list_conversation_profiles` interceptor runs + before the `post_list_conversation_profiles_with_metadata` interceptor. """ return response + def post_list_conversation_profiles_with_metadata( + self, + response: conversation_profile.ListConversationProfilesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation_profile.ListConversationProfilesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_conversation_profiles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_list_conversation_profiles_with_metadata` + interceptor in new development instead of the `post_list_conversation_profiles` interceptor. + When both interceptors are used, this `post_list_conversation_profiles_with_metadata` interceptor runs after the + `post_list_conversation_profiles` interceptor. The (possibly modified) response returned by + `post_list_conversation_profiles` will be passed to + `post_list_conversation_profiles_with_metadata`. + """ + return response, metadata + def pre_set_suggestion_feature_config( self, request: gcd_conversation_profile.SetSuggestionFeatureConfigRequest, @@ -271,12 +372,35 @@ def post_set_suggestion_feature_config( ) -> operations_pb2.Operation: """Post-rpc interceptor for set_suggestion_feature_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_set_suggestion_feature_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_set_suggestion_feature_config` interceptor runs + before the `post_set_suggestion_feature_config_with_metadata` interceptor. """ return response + def post_set_suggestion_feature_config_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for set_suggestion_feature_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_set_suggestion_feature_config_with_metadata` + interceptor in new development instead of the `post_set_suggestion_feature_config` interceptor. + When both interceptors are used, this `post_set_suggestion_feature_config_with_metadata` interceptor runs after the + `post_set_suggestion_feature_config` interceptor. The (possibly modified) response returned by + `post_set_suggestion_feature_config` will be passed to + `post_set_suggestion_feature_config_with_metadata`. + """ + return response, metadata + def pre_update_conversation_profile( self, request: gcd_conversation_profile.UpdateConversationProfileRequest, @@ -297,12 +421,38 @@ def post_update_conversation_profile( ) -> gcd_conversation_profile.ConversationProfile: """Post-rpc interceptor for update_conversation_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_conversation_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationProfiles server but before - it is returned to user code. + it is returned to user code. This `post_update_conversation_profile` interceptor runs + before the `post_update_conversation_profile_with_metadata` interceptor. """ return response + def post_update_conversation_profile_with_metadata( + self, + response: gcd_conversation_profile.ConversationProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_conversation_profile.ConversationProfile, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_conversation_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationProfiles server but before it is returned to user code. + + We recommend only using this `post_update_conversation_profile_with_metadata` + interceptor in new development instead of the `post_update_conversation_profile` interceptor. + When both interceptors are used, this `post_update_conversation_profile_with_metadata` interceptor runs after the + `post_update_conversation_profile` interceptor. The (possibly modified) response returned by + `post_update_conversation_profile` will be passed to + `post_update_conversation_profile_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -704,6 +854,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_clear_suggestion_feature_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_clear_suggestion_feature_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -857,6 +1014,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_conversation_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1121,6 +1282,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1270,6 +1435,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversation_profiles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversation_profiles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1426,6 +1595,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_set_suggestion_feature_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_set_suggestion_feature_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1579,6 +1755,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_conversation_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_conversation_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py index 7e08953cd0c6..e3b0de682e6f 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -718,6 +720,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2105,16 +2134,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2160,16 +2193,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2270,16 +2307,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2325,16 +2366,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/transports/rest.py index 57d77e1525a6..a851819e55cd 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/conversations/transports/rest.py @@ -176,12 +176,38 @@ def post_batch_create_messages( ) -> conversation.BatchCreateMessagesResponse: """Post-rpc interceptor for batch_create_messages - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_create_messages_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_batch_create_messages` interceptor runs + before the `post_batch_create_messages_with_metadata` interceptor. """ return response + def post_batch_create_messages_with_metadata( + self, + response: conversation.BatchCreateMessagesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.BatchCreateMessagesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_create_messages + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_batch_create_messages_with_metadata` + interceptor in new development instead of the `post_batch_create_messages` interceptor. + When both interceptors are used, this `post_batch_create_messages_with_metadata` interceptor runs after the + `post_batch_create_messages` interceptor. The (possibly modified) response returned by + `post_batch_create_messages` will be passed to + `post_batch_create_messages_with_metadata`. + """ + return response, metadata + def pre_complete_conversation( self, request: conversation.CompleteConversationRequest, @@ -202,12 +228,35 @@ def post_complete_conversation( ) -> conversation.Conversation: """Post-rpc interceptor for complete_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_complete_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_complete_conversation` interceptor runs + before the `post_complete_conversation_with_metadata` interceptor. """ return response + def post_complete_conversation_with_metadata( + self, + response: conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for complete_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_complete_conversation_with_metadata` + interceptor in new development instead of the `post_complete_conversation` interceptor. + When both interceptors are used, this `post_complete_conversation_with_metadata` interceptor runs after the + `post_complete_conversation` interceptor. The (possibly modified) response returned by + `post_complete_conversation` will be passed to + `post_complete_conversation_with_metadata`. + """ + return response, metadata + def pre_create_conversation( self, request: gcd_conversation.CreateConversationRequest, @@ -228,12 +277,35 @@ def post_create_conversation( ) -> gcd_conversation.Conversation: """Post-rpc interceptor for create_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation` interceptor runs + before the `post_create_conversation_with_metadata` interceptor. """ return response + def post_create_conversation_with_metadata( + self, + response: gcd_conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_create_conversation_with_metadata` + interceptor in new development instead of the `post_create_conversation` interceptor. + When both interceptors are used, this `post_create_conversation_with_metadata` interceptor runs after the + `post_create_conversation` interceptor. The (possibly modified) response returned by + `post_create_conversation` will be passed to + `post_create_conversation_with_metadata`. + """ + return response, metadata + def pre_generate_stateless_suggestion( self, request: conversation.GenerateStatelessSuggestionRequest, @@ -254,12 +326,38 @@ def post_generate_stateless_suggestion( ) -> conversation.GenerateStatelessSuggestionResponse: """Post-rpc interceptor for generate_stateless_suggestion - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_generate_stateless_suggestion_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_generate_stateless_suggestion` interceptor runs + before the `post_generate_stateless_suggestion_with_metadata` interceptor. """ return response + def post_generate_stateless_suggestion_with_metadata( + self, + response: conversation.GenerateStatelessSuggestionResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.GenerateStatelessSuggestionResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for generate_stateless_suggestion + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_generate_stateless_suggestion_with_metadata` + interceptor in new development instead of the `post_generate_stateless_suggestion` interceptor. + When both interceptors are used, this `post_generate_stateless_suggestion_with_metadata` interceptor runs after the + `post_generate_stateless_suggestion` interceptor. The (possibly modified) response returned by + `post_generate_stateless_suggestion` will be passed to + `post_generate_stateless_suggestion_with_metadata`. + """ + return response, metadata + def pre_generate_stateless_summary( self, request: conversation.GenerateStatelessSummaryRequest, @@ -280,12 +378,38 @@ def post_generate_stateless_summary( ) -> conversation.GenerateStatelessSummaryResponse: """Post-rpc interceptor for generate_stateless_summary - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_generate_stateless_summary_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_generate_stateless_summary` interceptor runs + before the `post_generate_stateless_summary_with_metadata` interceptor. """ return response + def post_generate_stateless_summary_with_metadata( + self, + response: conversation.GenerateStatelessSummaryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.GenerateStatelessSummaryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for generate_stateless_summary + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_generate_stateless_summary_with_metadata` + interceptor in new development instead of the `post_generate_stateless_summary` interceptor. + When both interceptors are used, this `post_generate_stateless_summary_with_metadata` interceptor runs after the + `post_generate_stateless_summary` interceptor. The (possibly modified) response returned by + `post_generate_stateless_summary` will be passed to + `post_generate_stateless_summary_with_metadata`. + """ + return response, metadata + def pre_get_conversation( self, request: conversation.GetConversationRequest, @@ -305,12 +429,35 @@ def post_get_conversation( ) -> conversation.Conversation: """Post-rpc interceptor for get_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation` interceptor runs + before the `post_get_conversation_with_metadata` interceptor. """ return response + def post_get_conversation_with_metadata( + self, + response: conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_get_conversation_with_metadata` + interceptor in new development instead of the `post_get_conversation` interceptor. + When both interceptors are used, this `post_get_conversation_with_metadata` interceptor runs after the + `post_get_conversation` interceptor. The (possibly modified) response returned by + `post_get_conversation` will be passed to + `post_get_conversation_with_metadata`. + """ + return response, metadata + def pre_list_conversations( self, request: conversation.ListConversationsRequest, @@ -330,12 +477,37 @@ def post_list_conversations( ) -> conversation.ListConversationsResponse: """Post-rpc interceptor for list_conversations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_list_conversations` interceptor runs + before the `post_list_conversations_with_metadata` interceptor. """ return response + def post_list_conversations_with_metadata( + self, + response: conversation.ListConversationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.ListConversationsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_conversations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_list_conversations_with_metadata` + interceptor in new development instead of the `post_list_conversations` interceptor. + When both interceptors are used, this `post_list_conversations_with_metadata` interceptor runs after the + `post_list_conversations` interceptor. The (possibly modified) response returned by + `post_list_conversations` will be passed to + `post_list_conversations_with_metadata`. + """ + return response, metadata + def pre_list_messages( self, request: conversation.ListMessagesRequest, @@ -355,12 +527,37 @@ def post_list_messages( ) -> conversation.ListMessagesResponse: """Post-rpc interceptor for list_messages - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_messages_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_list_messages` interceptor runs + before the `post_list_messages_with_metadata` interceptor. """ return response + def post_list_messages_with_metadata( + self, + response: conversation.ListMessagesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.ListMessagesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_messages + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_list_messages_with_metadata` + interceptor in new development instead of the `post_list_messages` interceptor. + When both interceptors are used, this `post_list_messages_with_metadata` interceptor runs after the + `post_list_messages` interceptor. The (possibly modified) response returned by + `post_list_messages` will be passed to + `post_list_messages_with_metadata`. + """ + return response, metadata + def pre_search_knowledge( self, request: conversation.SearchKnowledgeRequest, @@ -380,12 +577,37 @@ def post_search_knowledge( ) -> conversation.SearchKnowledgeResponse: """Post-rpc interceptor for search_knowledge - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_knowledge_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_search_knowledge` interceptor runs + before the `post_search_knowledge_with_metadata` interceptor. """ return response + def post_search_knowledge_with_metadata( + self, + response: conversation.SearchKnowledgeResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversation.SearchKnowledgeResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for search_knowledge + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_search_knowledge_with_metadata` + interceptor in new development instead of the `post_search_knowledge` interceptor. + When both interceptors are used, this `post_search_knowledge_with_metadata` interceptor runs after the + `post_search_knowledge` interceptor. The (possibly modified) response returned by + `post_search_knowledge` will be passed to + `post_search_knowledge_with_metadata`. + """ + return response, metadata + def pre_suggest_conversation_summary( self, request: gcd_conversation.SuggestConversationSummaryRequest, @@ -406,12 +628,38 @@ def post_suggest_conversation_summary( ) -> gcd_conversation.SuggestConversationSummaryResponse: """Post-rpc interceptor for suggest_conversation_summary - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_conversation_summary_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Conversations server but before - it is returned to user code. + it is returned to user code. This `post_suggest_conversation_summary` interceptor runs + before the `post_suggest_conversation_summary_with_metadata` interceptor. """ return response + def post_suggest_conversation_summary_with_metadata( + self, + response: gcd_conversation.SuggestConversationSummaryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_conversation.SuggestConversationSummaryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for suggest_conversation_summary + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Conversations server but before it is returned to user code. + + We recommend only using this `post_suggest_conversation_summary_with_metadata` + interceptor in new development instead of the `post_suggest_conversation_summary` interceptor. + When both interceptors are used, this `post_suggest_conversation_summary_with_metadata` interceptor runs after the + `post_suggest_conversation_summary` interceptor. The (possibly modified) response returned by + `post_suggest_conversation_summary` will be passed to + `post_suggest_conversation_summary_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -751,6 +999,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_create_messages(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_messages_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -909,6 +1161,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_complete_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_complete_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1065,6 +1321,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1220,6 +1480,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_generate_stateless_suggestion(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_generate_stateless_suggestion_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1379,6 +1646,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_generate_stateless_summary(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_generate_stateless_summary_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1531,6 +1802,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1676,6 +1951,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1821,6 +2100,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_messages(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_messages_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1974,6 +2257,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_knowledge(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_knowledge_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2131,6 +2418,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_conversation_summary(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_conversation_summary_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/documents/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/documents/client.py index c37540d23773..8d8c29189e8e 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/documents/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/documents/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -493,6 +495,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1711,16 +1740,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1766,16 +1799,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1876,16 +1913,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1931,16 +1972,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/documents/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/documents/transports/rest.py index 7c7cdb5197dc..6c3d375e0237 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/documents/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/documents/transports/rest.py @@ -152,12 +152,35 @@ def post_create_document( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_create_document` interceptor runs + before the `post_create_document_with_metadata` interceptor. """ return response + def post_create_document_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_create_document_with_metadata` + interceptor in new development instead of the `post_create_document` interceptor. + When both interceptors are used, this `post_create_document_with_metadata` interceptor runs after the + `post_create_document` interceptor. The (possibly modified) response returned by + `post_create_document` will be passed to + `post_create_document_with_metadata`. + """ + return response, metadata + def pre_delete_document( self, request: document.DeleteDocumentRequest, @@ -175,12 +198,35 @@ def post_delete_document( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_delete_document` interceptor runs + before the `post_delete_document_with_metadata` interceptor. """ return response + def post_delete_document_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_delete_document_with_metadata` + interceptor in new development instead of the `post_delete_document` interceptor. + When both interceptors are used, this `post_delete_document_with_metadata` interceptor runs after the + `post_delete_document` interceptor. The (possibly modified) response returned by + `post_delete_document` will be passed to + `post_delete_document_with_metadata`. + """ + return response, metadata + def pre_get_document( self, request: document.GetDocumentRequest, @@ -196,12 +242,35 @@ def pre_get_document( def post_get_document(self, response: document.Document) -> document.Document: """Post-rpc interceptor for get_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_get_document` interceptor runs + before the `post_get_document_with_metadata` interceptor. """ return response + def post_get_document_with_metadata( + self, + response: document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_get_document_with_metadata` + interceptor in new development instead of the `post_get_document` interceptor. + When both interceptors are used, this `post_get_document_with_metadata` interceptor runs after the + `post_get_document` interceptor. The (possibly modified) response returned by + `post_get_document` will be passed to + `post_get_document_with_metadata`. + """ + return response, metadata + def pre_import_documents( self, request: document.ImportDocumentsRequest, @@ -221,12 +290,35 @@ def post_import_documents( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_import_documents` interceptor runs + before the `post_import_documents_with_metadata` interceptor. """ return response + def post_import_documents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_import_documents_with_metadata` + interceptor in new development instead of the `post_import_documents` interceptor. + When both interceptors are used, this `post_import_documents_with_metadata` interceptor runs after the + `post_import_documents` interceptor. The (possibly modified) response returned by + `post_import_documents` will be passed to + `post_import_documents_with_metadata`. + """ + return response, metadata + def pre_list_documents( self, request: document.ListDocumentsRequest, @@ -244,12 +336,35 @@ def post_list_documents( ) -> document.ListDocumentsResponse: """Post-rpc interceptor for list_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_list_documents` interceptor runs + before the `post_list_documents_with_metadata` interceptor. """ return response + def post_list_documents_with_metadata( + self, + response: document.ListDocumentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[document.ListDocumentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_list_documents_with_metadata` + interceptor in new development instead of the `post_list_documents` interceptor. + When both interceptors are used, this `post_list_documents_with_metadata` interceptor runs after the + `post_list_documents` interceptor. The (possibly modified) response returned by + `post_list_documents` will be passed to + `post_list_documents_with_metadata`. + """ + return response, metadata + def pre_reload_document( self, request: document.ReloadDocumentRequest, @@ -267,12 +382,35 @@ def post_reload_document( ) -> operations_pb2.Operation: """Post-rpc interceptor for reload_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_reload_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_reload_document` interceptor runs + before the `post_reload_document_with_metadata` interceptor. """ return response + def post_reload_document_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for reload_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_reload_document_with_metadata` + interceptor in new development instead of the `post_reload_document` interceptor. + When both interceptors are used, this `post_reload_document_with_metadata` interceptor runs after the + `post_reload_document` interceptor. The (possibly modified) response returned by + `post_reload_document` will be passed to + `post_reload_document_with_metadata`. + """ + return response, metadata + def pre_update_document( self, request: gcd_document.UpdateDocumentRequest, @@ -292,12 +430,35 @@ def post_update_document( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Documents server but before - it is returned to user code. + it is returned to user code. This `post_update_document` interceptor runs + before the `post_update_document_with_metadata` interceptor. """ return response + def post_update_document_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Documents server but before it is returned to user code. + + We recommend only using this `post_update_document_with_metadata` + interceptor in new development instead of the `post_update_document` interceptor. + When both interceptors are used, this `post_update_document_with_metadata` interceptor runs after the + `post_update_document` interceptor. The (possibly modified) response returned by + `post_update_document` will be passed to + `post_update_document_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -699,6 +860,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -845,6 +1010,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -997,6 +1166,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1151,6 +1324,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1298,6 +1475,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1452,6 +1633,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_reload_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_reload_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1606,6 +1791,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/encryption_spec_service/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/encryption_spec_service/client.py index 981a248b573b..16b4a55203ed 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/encryption_spec_service/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/encryption_spec_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -491,6 +493,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -995,16 +1024,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1050,16 +1083,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1160,16 +1197,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1215,16 +1256,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/encryption_spec_service/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/encryption_spec_service/transports/rest.py index f0c753f22b1f..17e2ee852239 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/encryption_spec_service/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/encryption_spec_service/transports/rest.py @@ -113,12 +113,35 @@ def post_get_encryption_spec( ) -> encryption_spec.EncryptionSpec: """Post-rpc interceptor for get_encryption_spec - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_encryption_spec_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EncryptionSpecService server but before - it is returned to user code. + it is returned to user code. This `post_get_encryption_spec` interceptor runs + before the `post_get_encryption_spec_with_metadata` interceptor. """ return response + def post_get_encryption_spec_with_metadata( + self, + response: encryption_spec.EncryptionSpec, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[encryption_spec.EncryptionSpec, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_encryption_spec + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EncryptionSpecService server but before it is returned to user code. + + We recommend only using this `post_get_encryption_spec_with_metadata` + interceptor in new development instead of the `post_get_encryption_spec` interceptor. + When both interceptors are used, this `post_get_encryption_spec_with_metadata` interceptor runs after the + `post_get_encryption_spec` interceptor. The (possibly modified) response returned by + `post_get_encryption_spec` will be passed to + `post_get_encryption_spec_with_metadata`. + """ + return response, metadata + def pre_initialize_encryption_spec( self, request: gcd_encryption_spec.InitializeEncryptionSpecRequest, @@ -139,12 +162,35 @@ def post_initialize_encryption_spec( ) -> operations_pb2.Operation: """Post-rpc interceptor for initialize_encryption_spec - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_initialize_encryption_spec_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EncryptionSpecService server but before - it is returned to user code. + it is returned to user code. This `post_initialize_encryption_spec` interceptor runs + before the `post_initialize_encryption_spec_with_metadata` interceptor. """ return response + def post_initialize_encryption_spec_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for initialize_encryption_spec + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EncryptionSpecService server but before it is returned to user code. + + We recommend only using this `post_initialize_encryption_spec_with_metadata` + interceptor in new development instead of the `post_initialize_encryption_spec` interceptor. + When both interceptors are used, this `post_initialize_encryption_spec_with_metadata` interceptor runs after the + `post_initialize_encryption_spec` interceptor. The (possibly modified) response returned by + `post_initialize_encryption_spec` will be passed to + `post_initialize_encryption_spec_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -541,6 +587,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_encryption_spec(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_encryption_spec_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -693,6 +743,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_initialize_encryption_spec(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_initialize_encryption_spec_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/entity_types/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/entity_types/client.py index 10d4e67c7fe7..8b190fc6a7f0 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/entity_types/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/entity_types/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -490,6 +492,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2198,16 +2227,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2253,16 +2286,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2363,16 +2400,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2418,16 +2459,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/entity_types/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/entity_types/transports/rest.py index c1ce60c97a4b..6219cb03c659 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/entity_types/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/entity_types/transports/rest.py @@ -173,12 +173,35 @@ def post_batch_create_entities( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_create_entities - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_create_entities_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_create_entities` interceptor runs + before the `post_batch_create_entities_with_metadata` interceptor. """ return response + def post_batch_create_entities_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_create_entities + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_create_entities_with_metadata` + interceptor in new development instead of the `post_batch_create_entities` interceptor. + When both interceptors are used, this `post_batch_create_entities_with_metadata` interceptor runs after the + `post_batch_create_entities` interceptor. The (possibly modified) response returned by + `post_batch_create_entities` will be passed to + `post_batch_create_entities_with_metadata`. + """ + return response, metadata + def pre_batch_delete_entities( self, request: entity_type.BatchDeleteEntitiesRequest, @@ -198,12 +221,35 @@ def post_batch_delete_entities( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_delete_entities - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_delete_entities_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_delete_entities` interceptor runs + before the `post_batch_delete_entities_with_metadata` interceptor. """ return response + def post_batch_delete_entities_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_delete_entities + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_delete_entities_with_metadata` + interceptor in new development instead of the `post_batch_delete_entities` interceptor. + When both interceptors are used, this `post_batch_delete_entities_with_metadata` interceptor runs after the + `post_batch_delete_entities` interceptor. The (possibly modified) response returned by + `post_batch_delete_entities` will be passed to + `post_batch_delete_entities_with_metadata`. + """ + return response, metadata + def pre_batch_delete_entity_types( self, request: entity_type.BatchDeleteEntityTypesRequest, @@ -224,12 +270,35 @@ def post_batch_delete_entity_types( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_delete_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_delete_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_delete_entity_types` interceptor runs + before the `post_batch_delete_entity_types_with_metadata` interceptor. """ return response + def post_batch_delete_entity_types_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_delete_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_delete_entity_types_with_metadata` + interceptor in new development instead of the `post_batch_delete_entity_types` interceptor. + When both interceptors are used, this `post_batch_delete_entity_types_with_metadata` interceptor runs after the + `post_batch_delete_entity_types` interceptor. The (possibly modified) response returned by + `post_batch_delete_entity_types` will be passed to + `post_batch_delete_entity_types_with_metadata`. + """ + return response, metadata + def pre_batch_update_entities( self, request: entity_type.BatchUpdateEntitiesRequest, @@ -249,12 +318,35 @@ def post_batch_update_entities( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_update_entities - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_update_entities_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_update_entities` interceptor runs + before the `post_batch_update_entities_with_metadata` interceptor. """ return response + def post_batch_update_entities_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_update_entities + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_update_entities_with_metadata` + interceptor in new development instead of the `post_batch_update_entities` interceptor. + When both interceptors are used, this `post_batch_update_entities_with_metadata` interceptor runs after the + `post_batch_update_entities` interceptor. The (possibly modified) response returned by + `post_batch_update_entities` will be passed to + `post_batch_update_entities_with_metadata`. + """ + return response, metadata + def pre_batch_update_entity_types( self, request: entity_type.BatchUpdateEntityTypesRequest, @@ -275,12 +367,35 @@ def post_batch_update_entity_types( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_update_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_update_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_batch_update_entity_types` interceptor runs + before the `post_batch_update_entity_types_with_metadata` interceptor. """ return response + def post_batch_update_entity_types_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_update_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_batch_update_entity_types_with_metadata` + interceptor in new development instead of the `post_batch_update_entity_types` interceptor. + When both interceptors are used, this `post_batch_update_entity_types_with_metadata` interceptor runs after the + `post_batch_update_entity_types` interceptor. The (possibly modified) response returned by + `post_batch_update_entity_types` will be passed to + `post_batch_update_entity_types_with_metadata`. + """ + return response, metadata + def pre_create_entity_type( self, request: gcd_entity_type.CreateEntityTypeRequest, @@ -300,12 +415,35 @@ def post_create_entity_type( ) -> gcd_entity_type.EntityType: """Post-rpc interceptor for create_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_create_entity_type` interceptor runs + before the `post_create_entity_type_with_metadata` interceptor. """ return response + def post_create_entity_type_with_metadata( + self, + response: gcd_entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_create_entity_type_with_metadata` + interceptor in new development instead of the `post_create_entity_type` interceptor. + When both interceptors are used, this `post_create_entity_type_with_metadata` interceptor runs after the + `post_create_entity_type` interceptor. The (possibly modified) response returned by + `post_create_entity_type` will be passed to + `post_create_entity_type_with_metadata`. + """ + return response, metadata + def pre_delete_entity_type( self, request: entity_type.DeleteEntityTypeRequest, @@ -339,12 +477,35 @@ def post_get_entity_type( ) -> entity_type.EntityType: """Post-rpc interceptor for get_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_get_entity_type` interceptor runs + before the `post_get_entity_type_with_metadata` interceptor. """ return response + def post_get_entity_type_with_metadata( + self, + response: entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_get_entity_type_with_metadata` + interceptor in new development instead of the `post_get_entity_type` interceptor. + When both interceptors are used, this `post_get_entity_type_with_metadata` interceptor runs after the + `post_get_entity_type` interceptor. The (possibly modified) response returned by + `post_get_entity_type` will be passed to + `post_get_entity_type_with_metadata`. + """ + return response, metadata + def pre_list_entity_types( self, request: entity_type.ListEntityTypesRequest, @@ -364,12 +525,37 @@ def post_list_entity_types( ) -> entity_type.ListEntityTypesResponse: """Post-rpc interceptor for list_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_list_entity_types` interceptor runs + before the `post_list_entity_types_with_metadata` interceptor. """ return response + def post_list_entity_types_with_metadata( + self, + response: entity_type.ListEntityTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + entity_type.ListEntityTypesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_list_entity_types_with_metadata` + interceptor in new development instead of the `post_list_entity_types` interceptor. + When both interceptors are used, this `post_list_entity_types_with_metadata` interceptor runs after the + `post_list_entity_types` interceptor. The (possibly modified) response returned by + `post_list_entity_types` will be passed to + `post_list_entity_types_with_metadata`. + """ + return response, metadata + def pre_update_entity_type( self, request: gcd_entity_type.UpdateEntityTypeRequest, @@ -389,12 +575,35 @@ def post_update_entity_type( ) -> gcd_entity_type.EntityType: """Post-rpc interceptor for update_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_update_entity_type` interceptor runs + before the `post_update_entity_type_with_metadata` interceptor. """ return response + def post_update_entity_type_with_metadata( + self, + response: gcd_entity_type.EntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_entity_type.EntityType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EntityTypes server but before it is returned to user code. + + We recommend only using this `post_update_entity_type_with_metadata` + interceptor in new development instead of the `post_update_entity_type` interceptor. + When both interceptors are used, this `post_update_entity_type_with_metadata` interceptor runs after the + `post_update_entity_type` interceptor. The (possibly modified) response returned by + `post_update_entity_type` will be passed to + `post_update_entity_type_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -792,6 +1001,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_create_entities(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_entities_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -942,6 +1155,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_delete_entities(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_delete_entities_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1092,6 +1309,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_delete_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_delete_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1242,6 +1463,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_update_entities(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_entities_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1392,6 +1617,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_update_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1556,6 +1785,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1823,6 +2056,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1968,6 +2205,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2134,6 +2375,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/environments/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/environments/client.py index 88995506e78c..5c6c08465b0d 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/environments/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/environments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -519,6 +521,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1387,16 +1416,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1442,16 +1475,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1552,16 +1589,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1607,16 +1648,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/environments/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/environments/transports/rest.py index b58901b74cfe..3e940e2479af 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/environments/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/environments/transports/rest.py @@ -140,12 +140,35 @@ def post_create_environment( ) -> environment.Environment: """Post-rpc interceptor for create_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_create_environment` interceptor runs + before the `post_create_environment_with_metadata` interceptor. """ return response + def post_create_environment_with_metadata( + self, + response: environment.Environment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.Environment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_create_environment_with_metadata` + interceptor in new development instead of the `post_create_environment` interceptor. + When both interceptors are used, this `post_create_environment_with_metadata` interceptor runs after the + `post_create_environment` interceptor. The (possibly modified) response returned by + `post_create_environment` will be passed to + `post_create_environment_with_metadata`. + """ + return response, metadata + def pre_delete_environment( self, request: environment.DeleteEnvironmentRequest, @@ -179,12 +202,35 @@ def post_get_environment( ) -> environment.Environment: """Post-rpc interceptor for get_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_get_environment` interceptor runs + before the `post_get_environment_with_metadata` interceptor. """ return response + def post_get_environment_with_metadata( + self, + response: environment.Environment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.Environment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_get_environment_with_metadata` + interceptor in new development instead of the `post_get_environment` interceptor. + When both interceptors are used, this `post_get_environment_with_metadata` interceptor runs after the + `post_get_environment` interceptor. The (possibly modified) response returned by + `post_get_environment` will be passed to + `post_get_environment_with_metadata`. + """ + return response, metadata + def pre_get_environment_history( self, request: environment.GetEnvironmentHistoryRequest, @@ -205,12 +251,35 @@ def post_get_environment_history( ) -> environment.EnvironmentHistory: """Post-rpc interceptor for get_environment_history - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_environment_history_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_get_environment_history` interceptor runs + before the `post_get_environment_history_with_metadata` interceptor. """ return response + def post_get_environment_history_with_metadata( + self, + response: environment.EnvironmentHistory, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.EnvironmentHistory, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_environment_history + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_get_environment_history_with_metadata` + interceptor in new development instead of the `post_get_environment_history` interceptor. + When both interceptors are used, this `post_get_environment_history_with_metadata` interceptor runs after the + `post_get_environment_history` interceptor. The (possibly modified) response returned by + `post_get_environment_history` will be passed to + `post_get_environment_history_with_metadata`. + """ + return response, metadata + def pre_list_environments( self, request: environment.ListEnvironmentsRequest, @@ -230,12 +299,37 @@ def post_list_environments( ) -> environment.ListEnvironmentsResponse: """Post-rpc interceptor for list_environments - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_environments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_list_environments` interceptor runs + before the `post_list_environments_with_metadata` interceptor. """ return response + def post_list_environments_with_metadata( + self, + response: environment.ListEnvironmentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + environment.ListEnvironmentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_environments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_list_environments_with_metadata` + interceptor in new development instead of the `post_list_environments` interceptor. + When both interceptors are used, this `post_list_environments_with_metadata` interceptor runs after the + `post_list_environments` interceptor. The (possibly modified) response returned by + `post_list_environments` will be passed to + `post_list_environments_with_metadata`. + """ + return response, metadata + def pre_update_environment( self, request: environment.UpdateEnvironmentRequest, @@ -255,12 +349,35 @@ def post_update_environment( ) -> environment.Environment: """Post-rpc interceptor for update_environment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_environment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Environments server but before - it is returned to user code. + it is returned to user code. This `post_update_environment` interceptor runs + before the `post_update_environment_with_metadata` interceptor. """ return response + def post_update_environment_with_metadata( + self, + response: environment.Environment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[environment.Environment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_environment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Environments server but before it is returned to user code. + + We recommend only using this `post_update_environment_with_metadata` + interceptor in new development instead of the `post_update_environment` interceptor. + When both interceptors are used, this `post_update_environment_with_metadata` interceptor runs after the + `post_update_environment` interceptor. The (possibly modified) response returned by + `post_update_environment` will be passed to + `post_update_environment_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -617,6 +734,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -886,6 +1007,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1031,6 +1156,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_environment_history(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_environment_history_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1176,6 +1305,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_environments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_environments_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1346,6 +1479,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_environment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_environment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/fulfillments/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/fulfillments/client.py index 526df65ae19c..766e3f76114e 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/fulfillments/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/fulfillments/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -481,6 +483,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -979,16 +1008,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1034,16 +1067,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1144,16 +1181,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1199,16 +1240,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/fulfillments/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/fulfillments/transports/rest.py index 5e743e3283f7..a49e8bc6847e 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/fulfillments/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/fulfillments/transports/rest.py @@ -112,12 +112,35 @@ def post_get_fulfillment( ) -> fulfillment.Fulfillment: """Post-rpc interceptor for get_fulfillment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_fulfillment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Fulfillments server but before - it is returned to user code. + it is returned to user code. This `post_get_fulfillment` interceptor runs + before the `post_get_fulfillment_with_metadata` interceptor. """ return response + def post_get_fulfillment_with_metadata( + self, + response: fulfillment.Fulfillment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[fulfillment.Fulfillment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_fulfillment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Fulfillments server but before it is returned to user code. + + We recommend only using this `post_get_fulfillment_with_metadata` + interceptor in new development instead of the `post_get_fulfillment` interceptor. + When both interceptors are used, this `post_get_fulfillment_with_metadata` interceptor runs after the + `post_get_fulfillment` interceptor. The (possibly modified) response returned by + `post_get_fulfillment` will be passed to + `post_get_fulfillment_with_metadata`. + """ + return response, metadata + def pre_update_fulfillment( self, request: gcd_fulfillment.UpdateFulfillmentRequest, @@ -138,12 +161,35 @@ def post_update_fulfillment( ) -> gcd_fulfillment.Fulfillment: """Post-rpc interceptor for update_fulfillment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_fulfillment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Fulfillments server but before - it is returned to user code. + it is returned to user code. This `post_update_fulfillment` interceptor runs + before the `post_update_fulfillment_with_metadata` interceptor. """ return response + def post_update_fulfillment_with_metadata( + self, + response: gcd_fulfillment.Fulfillment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_fulfillment.Fulfillment, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_fulfillment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Fulfillments server but before it is returned to user code. + + We recommend only using this `post_update_fulfillment_with_metadata` + interceptor in new development instead of the `post_update_fulfillment` interceptor. + When both interceptors are used, this `post_update_fulfillment_with_metadata` interceptor runs after the + `post_update_fulfillment` interceptor. The (possibly modified) response returned by + `post_update_fulfillment` will be passed to + `post_update_fulfillment_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -485,6 +531,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_fulfillment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_fulfillment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -646,6 +696,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_fulfillment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_fulfillment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/client.py index bf0a5d28b245..0de8fdb1b605 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -493,6 +495,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1305,16 +1334,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1360,16 +1393,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1470,16 +1507,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1525,16 +1566,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/transports/rest.py index f3cfe2ab4bc9..96ffb3c4cf30 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/generators/transports/rest.py @@ -133,12 +133,35 @@ def post_create_generator( ) -> gcd_generator.Generator: """Post-rpc interceptor for create_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_create_generator` interceptor runs + before the `post_create_generator_with_metadata` interceptor. """ return response + def post_create_generator_with_metadata( + self, + response: gcd_generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_create_generator_with_metadata` + interceptor in new development instead of the `post_create_generator` interceptor. + When both interceptors are used, this `post_create_generator_with_metadata` interceptor runs after the + `post_create_generator` interceptor. The (possibly modified) response returned by + `post_create_generator` will be passed to + `post_create_generator_with_metadata`. + """ + return response, metadata + def pre_delete_generator( self, request: generator.DeleteGeneratorRequest, @@ -168,12 +191,35 @@ def pre_get_generator( def post_get_generator(self, response: generator.Generator) -> generator.Generator: """Post-rpc interceptor for get_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_get_generator` interceptor runs + before the `post_get_generator_with_metadata` interceptor. """ return response + def post_get_generator_with_metadata( + self, + response: generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_get_generator_with_metadata` + interceptor in new development instead of the `post_get_generator` interceptor. + When both interceptors are used, this `post_get_generator_with_metadata` interceptor runs after the + `post_get_generator` interceptor. The (possibly modified) response returned by + `post_get_generator` will be passed to + `post_get_generator_with_metadata`. + """ + return response, metadata + def pre_list_generators( self, request: generator.ListGeneratorsRequest, @@ -193,12 +239,37 @@ def post_list_generators( ) -> generator.ListGeneratorsResponse: """Post-rpc interceptor for list_generators - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_generators_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_list_generators` interceptor runs + before the `post_list_generators_with_metadata` interceptor. """ return response + def post_list_generators_with_metadata( + self, + response: generator.ListGeneratorsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + generator.ListGeneratorsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_generators + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_list_generators_with_metadata` + interceptor in new development instead of the `post_list_generators` interceptor. + When both interceptors are used, this `post_list_generators_with_metadata` interceptor runs after the + `post_list_generators` interceptor. The (possibly modified) response returned by + `post_list_generators` will be passed to + `post_list_generators_with_metadata`. + """ + return response, metadata + def pre_update_generator( self, request: gcd_generator.UpdateGeneratorRequest, @@ -218,12 +289,35 @@ def post_update_generator( ) -> gcd_generator.Generator: """Post-rpc interceptor for update_generator - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_generator_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Generators server but before - it is returned to user code. + it is returned to user code. This `post_update_generator` interceptor runs + before the `post_update_generator_with_metadata` interceptor. """ return response + def post_update_generator_with_metadata( + self, + response: gcd_generator.Generator, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_generator.Generator, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_generator + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Generators server but before it is returned to user code. + + We recommend only using this `post_update_generator_with_metadata` + interceptor in new development instead of the `post_update_generator` interceptor. + When both interceptors are used, this `post_update_generator_with_metadata` interceptor runs after the + `post_update_generator` interceptor. The (possibly modified) response returned by + `post_update_generator` will be passed to + `post_update_generator_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -563,6 +657,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -815,6 +913,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -957,6 +1059,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_generators(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_generators_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1107,6 +1213,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_generator(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_generator_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/intents/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/intents/client.py index accac19fc383..2e202fc0dd4b 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/intents/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/intents/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -511,6 +513,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1746,16 +1775,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1801,16 +1834,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1911,16 +1948,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1966,16 +2007,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/intents/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/intents/transports/rest.py index 716185442b92..d9a887c50ff1 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/intents/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/intents/transports/rest.py @@ -149,12 +149,35 @@ def post_batch_delete_intents( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_delete_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_delete_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_batch_delete_intents` interceptor runs + before the `post_batch_delete_intents_with_metadata` interceptor. """ return response + def post_batch_delete_intents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_delete_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_batch_delete_intents_with_metadata` + interceptor in new development instead of the `post_batch_delete_intents` interceptor. + When both interceptors are used, this `post_batch_delete_intents_with_metadata` interceptor runs after the + `post_batch_delete_intents` interceptor. The (possibly modified) response returned by + `post_batch_delete_intents` will be passed to + `post_batch_delete_intents_with_metadata`. + """ + return response, metadata + def pre_batch_update_intents( self, request: intent.BatchUpdateIntentsRequest, @@ -174,12 +197,35 @@ def post_batch_update_intents( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_update_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_update_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_batch_update_intents` interceptor runs + before the `post_batch_update_intents_with_metadata` interceptor. """ return response + def post_batch_update_intents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_update_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_batch_update_intents_with_metadata` + interceptor in new development instead of the `post_batch_update_intents` interceptor. + When both interceptors are used, this `post_batch_update_intents_with_metadata` interceptor runs after the + `post_batch_update_intents` interceptor. The (possibly modified) response returned by + `post_batch_update_intents` will be passed to + `post_batch_update_intents_with_metadata`. + """ + return response, metadata + def pre_create_intent( self, request: gcd_intent.CreateIntentRequest, @@ -195,12 +241,35 @@ def pre_create_intent( def post_create_intent(self, response: gcd_intent.Intent) -> gcd_intent.Intent: """Post-rpc interceptor for create_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_create_intent` interceptor runs + before the `post_create_intent_with_metadata` interceptor. """ return response + def post_create_intent_with_metadata( + self, + response: gcd_intent.Intent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_create_intent_with_metadata` + interceptor in new development instead of the `post_create_intent` interceptor. + When both interceptors are used, this `post_create_intent_with_metadata` interceptor runs after the + `post_create_intent` interceptor. The (possibly modified) response returned by + `post_create_intent` will be passed to + `post_create_intent_with_metadata`. + """ + return response, metadata + def pre_delete_intent( self, request: intent.DeleteIntentRequest, @@ -228,12 +297,33 @@ def pre_get_intent( def post_get_intent(self, response: intent.Intent) -> intent.Intent: """Post-rpc interceptor for get_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_get_intent` interceptor runs + before the `post_get_intent_with_metadata` interceptor. """ return response + def post_get_intent_with_metadata( + self, response: intent.Intent, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_get_intent_with_metadata` + interceptor in new development instead of the `post_get_intent` interceptor. + When both interceptors are used, this `post_get_intent_with_metadata` interceptor runs after the + `post_get_intent` interceptor. The (possibly modified) response returned by + `post_get_intent` will be passed to + `post_get_intent_with_metadata`. + """ + return response, metadata + def pre_list_intents( self, request: intent.ListIntentsRequest, @@ -251,12 +341,35 @@ def post_list_intents( ) -> intent.ListIntentsResponse: """Post-rpc interceptor for list_intents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_intents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_list_intents` interceptor runs + before the `post_list_intents_with_metadata` interceptor. """ return response + def post_list_intents_with_metadata( + self, + response: intent.ListIntentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[intent.ListIntentsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_intents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_list_intents_with_metadata` + interceptor in new development instead of the `post_list_intents` interceptor. + When both interceptors are used, this `post_list_intents_with_metadata` interceptor runs after the + `post_list_intents` interceptor. The (possibly modified) response returned by + `post_list_intents` will be passed to + `post_list_intents_with_metadata`. + """ + return response, metadata + def pre_update_intent( self, request: gcd_intent.UpdateIntentRequest, @@ -272,12 +385,35 @@ def pre_update_intent( def post_update_intent(self, response: gcd_intent.Intent) -> gcd_intent.Intent: """Post-rpc interceptor for update_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Intents server but before - it is returned to user code. + it is returned to user code. This `post_update_intent` interceptor runs + before the `post_update_intent_with_metadata` interceptor. """ return response + def post_update_intent_with_metadata( + self, + response: gcd_intent.Intent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_intent.Intent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Intents server but before it is returned to user code. + + We recommend only using this `post_update_intent_with_metadata` + interceptor in new development instead of the `post_update_intent` interceptor. + When both interceptors are used, this `post_update_intent_with_metadata` interceptor runs after the + `post_update_intent` interceptor. The (possibly modified) response returned by + `post_update_intent` will be passed to + `post_update_intent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -675,6 +811,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_delete_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_delete_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -825,6 +965,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_update_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_update_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -985,6 +1129,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1246,6 +1394,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1391,6 +1543,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_intents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_intents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1551,6 +1707,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/knowledge_bases/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/knowledge_bases/client.py index 673bd67725e7..b625490871d4 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/knowledge_bases/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/knowledge_bases/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -488,6 +490,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1354,16 +1383,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1409,16 +1442,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1519,16 +1556,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1574,16 +1615,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/knowledge_bases/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/knowledge_bases/transports/rest.py index e83acc480f5f..a0342f21d19c 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/knowledge_bases/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/knowledge_bases/transports/rest.py @@ -134,12 +134,37 @@ def post_create_knowledge_base( ) -> gcd_knowledge_base.KnowledgeBase: """Post-rpc interceptor for create_knowledge_base - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_knowledge_base_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the KnowledgeBases server but before - it is returned to user code. + it is returned to user code. This `post_create_knowledge_base` interceptor runs + before the `post_create_knowledge_base_with_metadata` interceptor. """ return response + def post_create_knowledge_base_with_metadata( + self, + response: gcd_knowledge_base.KnowledgeBase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_knowledge_base.KnowledgeBase, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_knowledge_base + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the KnowledgeBases server but before it is returned to user code. + + We recommend only using this `post_create_knowledge_base_with_metadata` + interceptor in new development instead of the `post_create_knowledge_base` interceptor. + When both interceptors are used, this `post_create_knowledge_base_with_metadata` interceptor runs after the + `post_create_knowledge_base` interceptor. The (possibly modified) response returned by + `post_create_knowledge_base` will be passed to + `post_create_knowledge_base_with_metadata`. + """ + return response, metadata + def pre_delete_knowledge_base( self, request: knowledge_base.DeleteKnowledgeBaseRequest, @@ -174,12 +199,35 @@ def post_get_knowledge_base( ) -> knowledge_base.KnowledgeBase: """Post-rpc interceptor for get_knowledge_base - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_knowledge_base_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the KnowledgeBases server but before - it is returned to user code. + it is returned to user code. This `post_get_knowledge_base` interceptor runs + before the `post_get_knowledge_base_with_metadata` interceptor. """ return response + def post_get_knowledge_base_with_metadata( + self, + response: knowledge_base.KnowledgeBase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[knowledge_base.KnowledgeBase, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_knowledge_base + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the KnowledgeBases server but before it is returned to user code. + + We recommend only using this `post_get_knowledge_base_with_metadata` + interceptor in new development instead of the `post_get_knowledge_base` interceptor. + When both interceptors are used, this `post_get_knowledge_base_with_metadata` interceptor runs after the + `post_get_knowledge_base` interceptor. The (possibly modified) response returned by + `post_get_knowledge_base` will be passed to + `post_get_knowledge_base_with_metadata`. + """ + return response, metadata + def pre_list_knowledge_bases( self, request: knowledge_base.ListKnowledgeBasesRequest, @@ -200,12 +248,38 @@ def post_list_knowledge_bases( ) -> knowledge_base.ListKnowledgeBasesResponse: """Post-rpc interceptor for list_knowledge_bases - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_knowledge_bases_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the KnowledgeBases server but before - it is returned to user code. + it is returned to user code. This `post_list_knowledge_bases` interceptor runs + before the `post_list_knowledge_bases_with_metadata` interceptor. """ return response + def post_list_knowledge_bases_with_metadata( + self, + response: knowledge_base.ListKnowledgeBasesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + knowledge_base.ListKnowledgeBasesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_knowledge_bases + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the KnowledgeBases server but before it is returned to user code. + + We recommend only using this `post_list_knowledge_bases_with_metadata` + interceptor in new development instead of the `post_list_knowledge_bases` interceptor. + When both interceptors are used, this `post_list_knowledge_bases_with_metadata` interceptor runs after the + `post_list_knowledge_bases` interceptor. The (possibly modified) response returned by + `post_list_knowledge_bases` will be passed to + `post_list_knowledge_bases_with_metadata`. + """ + return response, metadata + def pre_update_knowledge_base( self, request: gcd_knowledge_base.UpdateKnowledgeBaseRequest, @@ -226,12 +300,37 @@ def post_update_knowledge_base( ) -> gcd_knowledge_base.KnowledgeBase: """Post-rpc interceptor for update_knowledge_base - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_knowledge_base_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the KnowledgeBases server but before - it is returned to user code. + it is returned to user code. This `post_update_knowledge_base` interceptor runs + before the `post_update_knowledge_base_with_metadata` interceptor. """ return response + def post_update_knowledge_base_with_metadata( + self, + response: gcd_knowledge_base.KnowledgeBase, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_knowledge_base.KnowledgeBase, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_knowledge_base + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the KnowledgeBases server but before it is returned to user code. + + We recommend only using this `post_update_knowledge_base_with_metadata` + interceptor in new development instead of the `post_update_knowledge_base` interceptor. + When both interceptors are used, this `post_update_knowledge_base_with_metadata` interceptor runs after the + `post_update_knowledge_base` interceptor. The (possibly modified) response returned by + `post_update_knowledge_base` will be passed to + `post_update_knowledge_base_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -582,6 +681,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_knowledge_base(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_knowledge_base_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -849,6 +952,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_knowledge_base(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_knowledge_base_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -994,6 +1101,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_knowledge_bases(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_knowledge_bases_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1158,6 +1269,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_knowledge_base(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_knowledge_base_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py index 861e727822b8..a78b5a0a7eaf 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -640,6 +642,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2296,16 +2325,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2351,16 +2384,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -2461,16 +2498,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -2516,16 +2557,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest.py index fba5d657fc34..dbefab310176 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/participants/transports/rest.py @@ -184,12 +184,37 @@ def post_analyze_content( ) -> gcd_participant.AnalyzeContentResponse: """Post-rpc interceptor for analyze_content - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_analyze_content_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_analyze_content` interceptor runs + before the `post_analyze_content_with_metadata` interceptor. """ return response + def post_analyze_content_with_metadata( + self, + response: gcd_participant.AnalyzeContentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_participant.AnalyzeContentResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for analyze_content + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_analyze_content_with_metadata` + interceptor in new development instead of the `post_analyze_content` interceptor. + When both interceptors are used, this `post_analyze_content_with_metadata` interceptor runs after the + `post_analyze_content` interceptor. The (possibly modified) response returned by + `post_analyze_content` will be passed to + `post_analyze_content_with_metadata`. + """ + return response, metadata + def pre_compile_suggestion( self, request: participant.CompileSuggestionRequest, @@ -209,12 +234,37 @@ def post_compile_suggestion( ) -> participant.CompileSuggestionResponse: """Post-rpc interceptor for compile_suggestion - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_compile_suggestion_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_compile_suggestion` interceptor runs + before the `post_compile_suggestion_with_metadata` interceptor. """ return response + def post_compile_suggestion_with_metadata( + self, + response: participant.CompileSuggestionResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.CompileSuggestionResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for compile_suggestion + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_compile_suggestion_with_metadata` + interceptor in new development instead of the `post_compile_suggestion` interceptor. + When both interceptors are used, this `post_compile_suggestion_with_metadata` interceptor runs after the + `post_compile_suggestion` interceptor. The (possibly modified) response returned by + `post_compile_suggestion` will be passed to + `post_compile_suggestion_with_metadata`. + """ + return response, metadata + def pre_create_participant( self, request: gcd_participant.CreateParticipantRequest, @@ -235,12 +285,35 @@ def post_create_participant( ) -> gcd_participant.Participant: """Post-rpc interceptor for create_participant - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_participant_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_create_participant` interceptor runs + before the `post_create_participant_with_metadata` interceptor. """ return response + def post_create_participant_with_metadata( + self, + response: gcd_participant.Participant, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_participant.Participant, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_participant + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_create_participant_with_metadata` + interceptor in new development instead of the `post_create_participant` interceptor. + When both interceptors are used, this `post_create_participant_with_metadata` interceptor runs after the + `post_create_participant` interceptor. The (possibly modified) response returned by + `post_create_participant` will be passed to + `post_create_participant_with_metadata`. + """ + return response, metadata + def pre_get_participant( self, request: participant.GetParticipantRequest, @@ -260,12 +333,35 @@ def post_get_participant( ) -> participant.Participant: """Post-rpc interceptor for get_participant - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_participant_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_get_participant` interceptor runs + before the `post_get_participant_with_metadata` interceptor. """ return response + def post_get_participant_with_metadata( + self, + response: participant.Participant, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[participant.Participant, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_participant + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_get_participant_with_metadata` + interceptor in new development instead of the `post_get_participant` interceptor. + When both interceptors are used, this `post_get_participant_with_metadata` interceptor runs after the + `post_get_participant` interceptor. The (possibly modified) response returned by + `post_get_participant` will be passed to + `post_get_participant_with_metadata`. + """ + return response, metadata + def pre_list_participants( self, request: participant.ListParticipantsRequest, @@ -285,12 +381,37 @@ def post_list_participants( ) -> participant.ListParticipantsResponse: """Post-rpc interceptor for list_participants - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_participants_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_list_participants` interceptor runs + before the `post_list_participants_with_metadata` interceptor. """ return response + def post_list_participants_with_metadata( + self, + response: participant.ListParticipantsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.ListParticipantsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_participants + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_list_participants_with_metadata` + interceptor in new development instead of the `post_list_participants` interceptor. + When both interceptors are used, this `post_list_participants_with_metadata` interceptor runs after the + `post_list_participants` interceptor. The (possibly modified) response returned by + `post_list_participants` will be passed to + `post_list_participants_with_metadata`. + """ + return response, metadata + def pre_list_suggestions( self, request: participant.ListSuggestionsRequest, @@ -310,12 +431,37 @@ def post_list_suggestions( ) -> participant.ListSuggestionsResponse: """Post-rpc interceptor for list_suggestions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_suggestions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_list_suggestions` interceptor runs + before the `post_list_suggestions_with_metadata` interceptor. """ return response + def post_list_suggestions_with_metadata( + self, + response: participant.ListSuggestionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.ListSuggestionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_suggestions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_list_suggestions_with_metadata` + interceptor in new development instead of the `post_list_suggestions` interceptor. + When both interceptors are used, this `post_list_suggestions_with_metadata` interceptor runs after the + `post_list_suggestions` interceptor. The (possibly modified) response returned by + `post_list_suggestions` will be passed to + `post_list_suggestions_with_metadata`. + """ + return response, metadata + def pre_suggest_articles( self, request: participant.SuggestArticlesRequest, @@ -335,12 +481,37 @@ def post_suggest_articles( ) -> participant.SuggestArticlesResponse: """Post-rpc interceptor for suggest_articles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_articles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_suggest_articles` interceptor runs + before the `post_suggest_articles_with_metadata` interceptor. """ return response + def post_suggest_articles_with_metadata( + self, + response: participant.SuggestArticlesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.SuggestArticlesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for suggest_articles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_suggest_articles_with_metadata` + interceptor in new development instead of the `post_suggest_articles` interceptor. + When both interceptors are used, this `post_suggest_articles_with_metadata` interceptor runs after the + `post_suggest_articles` interceptor. The (possibly modified) response returned by + `post_suggest_articles` will be passed to + `post_suggest_articles_with_metadata`. + """ + return response, metadata + def pre_suggest_faq_answers( self, request: participant.SuggestFaqAnswersRequest, @@ -360,12 +531,37 @@ def post_suggest_faq_answers( ) -> participant.SuggestFaqAnswersResponse: """Post-rpc interceptor for suggest_faq_answers - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_faq_answers_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_suggest_faq_answers` interceptor runs + before the `post_suggest_faq_answers_with_metadata` interceptor. """ return response + def post_suggest_faq_answers_with_metadata( + self, + response: participant.SuggestFaqAnswersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.SuggestFaqAnswersResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for suggest_faq_answers + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_suggest_faq_answers_with_metadata` + interceptor in new development instead of the `post_suggest_faq_answers` interceptor. + When both interceptors are used, this `post_suggest_faq_answers_with_metadata` interceptor runs after the + `post_suggest_faq_answers` interceptor. The (possibly modified) response returned by + `post_suggest_faq_answers` will be passed to + `post_suggest_faq_answers_with_metadata`. + """ + return response, metadata + def pre_suggest_knowledge_assist( self, request: participant.SuggestKnowledgeAssistRequest, @@ -386,12 +582,38 @@ def post_suggest_knowledge_assist( ) -> participant.SuggestKnowledgeAssistResponse: """Post-rpc interceptor for suggest_knowledge_assist - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_knowledge_assist_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_suggest_knowledge_assist` interceptor runs + before the `post_suggest_knowledge_assist_with_metadata` interceptor. """ return response + def post_suggest_knowledge_assist_with_metadata( + self, + response: participant.SuggestKnowledgeAssistResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.SuggestKnowledgeAssistResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for suggest_knowledge_assist + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_suggest_knowledge_assist_with_metadata` + interceptor in new development instead of the `post_suggest_knowledge_assist` interceptor. + When both interceptors are used, this `post_suggest_knowledge_assist_with_metadata` interceptor runs after the + `post_suggest_knowledge_assist` interceptor. The (possibly modified) response returned by + `post_suggest_knowledge_assist` will be passed to + `post_suggest_knowledge_assist_with_metadata`. + """ + return response, metadata + def pre_suggest_smart_replies( self, request: participant.SuggestSmartRepliesRequest, @@ -411,12 +633,37 @@ def post_suggest_smart_replies( ) -> participant.SuggestSmartRepliesResponse: """Post-rpc interceptor for suggest_smart_replies - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_suggest_smart_replies_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_suggest_smart_replies` interceptor runs + before the `post_suggest_smart_replies_with_metadata` interceptor. """ return response + def post_suggest_smart_replies_with_metadata( + self, + response: participant.SuggestSmartRepliesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + participant.SuggestSmartRepliesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for suggest_smart_replies + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_suggest_smart_replies_with_metadata` + interceptor in new development instead of the `post_suggest_smart_replies` interceptor. + When both interceptors are used, this `post_suggest_smart_replies_with_metadata` interceptor runs after the + `post_suggest_smart_replies` interceptor. The (possibly modified) response returned by + `post_suggest_smart_replies` will be passed to + `post_suggest_smart_replies_with_metadata`. + """ + return response, metadata + def pre_update_participant( self, request: gcd_participant.UpdateParticipantRequest, @@ -437,12 +684,35 @@ def post_update_participant( ) -> gcd_participant.Participant: """Post-rpc interceptor for update_participant - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_participant_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Participants server but before - it is returned to user code. + it is returned to user code. This `post_update_participant` interceptor runs + before the `post_update_participant_with_metadata` interceptor. """ return response + def post_update_participant_with_metadata( + self, + response: gcd_participant.Participant, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_participant.Participant, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_participant + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Participants server but before it is returned to user code. + + We recommend only using this `post_update_participant_with_metadata` + interceptor in new development instead of the `post_update_participant` interceptor. + When both interceptors are used, this `post_update_participant_with_metadata` interceptor runs after the + `post_update_participant` interceptor. The (possibly modified) response returned by + `post_update_participant` will be passed to + `post_update_participant_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -780,6 +1050,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_analyze_content(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_analyze_content_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -933,6 +1207,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_compile_suggestion(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_compile_suggestion_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1086,6 +1364,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_participant(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_participant_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1229,6 +1511,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_participant(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_participant_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1374,6 +1660,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_participants(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_participants_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1521,6 +1811,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_suggestions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_suggestions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1693,6 +1987,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_articles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_articles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1846,6 +2144,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_faq_answers(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_faq_answers_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1999,6 +2301,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_knowledge_assist(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_knowledge_assist_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2152,6 +2458,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_suggest_smart_replies(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_suggest_smart_replies_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2305,6 +2615,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_participant(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_participant_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/session_entity_types/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/session_entity_types/client.py index ff6e0f3b08ee..efaef6a2d892 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/session_entity_types/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/session_entity_types/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -494,6 +496,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1410,16 +1439,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1465,16 +1498,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1575,16 +1612,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1630,16 +1671,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/session_entity_types/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/session_entity_types/transports/rest.py index f5a1e75a7c76..51f2452049cf 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/session_entity_types/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/session_entity_types/transports/rest.py @@ -136,12 +136,38 @@ def post_create_session_entity_type( ) -> gcd_session_entity_type.SessionEntityType: """Post-rpc interceptor for create_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_create_session_entity_type` interceptor runs + before the `post_create_session_entity_type_with_metadata` interceptor. """ return response + def post_create_session_entity_type_with_metadata( + self, + response: gcd_session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_session_entity_type.SessionEntityType, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for create_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_create_session_entity_type_with_metadata` + interceptor in new development instead of the `post_create_session_entity_type` interceptor. + When both interceptors are used, this `post_create_session_entity_type_with_metadata` interceptor runs after the + `post_create_session_entity_type` interceptor. The (possibly modified) response returned by + `post_create_session_entity_type` will be passed to + `post_create_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_delete_session_entity_type( self, request: session_entity_type.DeleteSessionEntityTypeRequest, @@ -177,12 +203,37 @@ def post_get_session_entity_type( ) -> session_entity_type.SessionEntityType: """Post-rpc interceptor for get_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_get_session_entity_type` interceptor runs + before the `post_get_session_entity_type_with_metadata` interceptor. """ return response + def post_get_session_entity_type_with_metadata( + self, + response: session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_entity_type.SessionEntityType, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_get_session_entity_type_with_metadata` + interceptor in new development instead of the `post_get_session_entity_type` interceptor. + When both interceptors are used, this `post_get_session_entity_type_with_metadata` interceptor runs after the + `post_get_session_entity_type` interceptor. The (possibly modified) response returned by + `post_get_session_entity_type` will be passed to + `post_get_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_list_session_entity_types( self, request: session_entity_type.ListSessionEntityTypesRequest, @@ -203,12 +254,38 @@ def post_list_session_entity_types( ) -> session_entity_type.ListSessionEntityTypesResponse: """Post-rpc interceptor for list_session_entity_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_session_entity_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_list_session_entity_types` interceptor runs + before the `post_list_session_entity_types_with_metadata` interceptor. """ return response + def post_list_session_entity_types_with_metadata( + self, + response: session_entity_type.ListSessionEntityTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + session_entity_type.ListSessionEntityTypesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_session_entity_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_list_session_entity_types_with_metadata` + interceptor in new development instead of the `post_list_session_entity_types` interceptor. + When both interceptors are used, this `post_list_session_entity_types_with_metadata` interceptor runs after the + `post_list_session_entity_types` interceptor. The (possibly modified) response returned by + `post_list_session_entity_types` will be passed to + `post_list_session_entity_types_with_metadata`. + """ + return response, metadata + def pre_update_session_entity_type( self, request: gcd_session_entity_type.UpdateSessionEntityTypeRequest, @@ -229,12 +306,38 @@ def post_update_session_entity_type( ) -> gcd_session_entity_type.SessionEntityType: """Post-rpc interceptor for update_session_entity_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_session_entity_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SessionEntityTypes server but before - it is returned to user code. + it is returned to user code. This `post_update_session_entity_type` interceptor runs + before the `post_update_session_entity_type_with_metadata` interceptor. """ return response + def post_update_session_entity_type_with_metadata( + self, + response: gcd_session_entity_type.SessionEntityType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_session_entity_type.SessionEntityType, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_session_entity_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SessionEntityTypes server but before it is returned to user code. + + We recommend only using this `post_update_session_entity_type_with_metadata` + interceptor in new development instead of the `post_update_session_entity_type` interceptor. + When both interceptors are used, this `post_update_session_entity_type_with_metadata` interceptor runs after the + `post_update_session_entity_type` interceptor. The (possibly modified) response returned by + `post_update_session_entity_type` will be passed to + `post_update_session_entity_type_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -586,6 +689,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -857,6 +964,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1007,6 +1118,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_session_entity_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_session_entity_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1174,6 +1289,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_session_entity_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_session_entity_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sessions/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sessions/client.py index 2958f1cd9a2f..a900e71999a8 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sessions/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sessions/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -595,6 +597,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1171,16 +1200,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1226,16 +1259,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1336,16 +1373,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1391,16 +1432,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sessions/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sessions/transports/rest.py index 45054242c57a..605210897e81 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sessions/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sessions/transports/rest.py @@ -104,12 +104,37 @@ def post_detect_intent( ) -> gcd_session.DetectIntentResponse: """Post-rpc interceptor for detect_intent - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_detect_intent_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Sessions server but before - it is returned to user code. + it is returned to user code. This `post_detect_intent` interceptor runs + before the `post_detect_intent_with_metadata` interceptor. """ return response + def post_detect_intent_with_metadata( + self, + response: gcd_session.DetectIntentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_session.DetectIntentResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for detect_intent + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Sessions server but before it is returned to user code. + + We recommend only using this `post_detect_intent_with_metadata` + interceptor in new development instead of the `post_detect_intent` interceptor. + When both interceptors are used, this `post_detect_intent_with_metadata` interceptor runs after the + `post_detect_intent` interceptor. The (possibly modified) response returned by + `post_detect_intent` will be passed to + `post_detect_intent_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -450,6 +475,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_detect_intent(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_detect_intent_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sip_trunks/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sip_trunks/client.py index dd081205f989..a5160c06f125 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sip_trunks/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sip_trunks/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -489,6 +491,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1301,16 +1330,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1356,16 +1389,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1466,16 +1503,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1521,16 +1562,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sip_trunks/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sip_trunks/transports/rest.py index c140a7e67b7f..6142706f1ffa 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sip_trunks/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/sip_trunks/transports/rest.py @@ -133,12 +133,35 @@ def post_create_sip_trunk( ) -> gcd_sip_trunk.SipTrunk: """Post-rpc interceptor for create_sip_trunk - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_sip_trunk_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SipTrunks server but before - it is returned to user code. + it is returned to user code. This `post_create_sip_trunk` interceptor runs + before the `post_create_sip_trunk_with_metadata` interceptor. """ return response + def post_create_sip_trunk_with_metadata( + self, + response: gcd_sip_trunk.SipTrunk, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_sip_trunk.SipTrunk, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_sip_trunk + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SipTrunks server but before it is returned to user code. + + We recommend only using this `post_create_sip_trunk_with_metadata` + interceptor in new development instead of the `post_create_sip_trunk` interceptor. + When both interceptors are used, this `post_create_sip_trunk_with_metadata` interceptor runs after the + `post_create_sip_trunk` interceptor. The (possibly modified) response returned by + `post_create_sip_trunk` will be passed to + `post_create_sip_trunk_with_metadata`. + """ + return response, metadata + def pre_delete_sip_trunk( self, request: sip_trunk.DeleteSipTrunkRequest, @@ -168,12 +191,35 @@ def pre_get_sip_trunk( def post_get_sip_trunk(self, response: sip_trunk.SipTrunk) -> sip_trunk.SipTrunk: """Post-rpc interceptor for get_sip_trunk - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_sip_trunk_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SipTrunks server but before - it is returned to user code. + it is returned to user code. This `post_get_sip_trunk` interceptor runs + before the `post_get_sip_trunk_with_metadata` interceptor. """ return response + def post_get_sip_trunk_with_metadata( + self, + response: sip_trunk.SipTrunk, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[sip_trunk.SipTrunk, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_sip_trunk + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SipTrunks server but before it is returned to user code. + + We recommend only using this `post_get_sip_trunk_with_metadata` + interceptor in new development instead of the `post_get_sip_trunk` interceptor. + When both interceptors are used, this `post_get_sip_trunk_with_metadata` interceptor runs after the + `post_get_sip_trunk` interceptor. The (possibly modified) response returned by + `post_get_sip_trunk` will be passed to + `post_get_sip_trunk_with_metadata`. + """ + return response, metadata + def pre_list_sip_trunks( self, request: sip_trunk.ListSipTrunksRequest, @@ -191,12 +237,37 @@ def post_list_sip_trunks( ) -> sip_trunk.ListSipTrunksResponse: """Post-rpc interceptor for list_sip_trunks - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_sip_trunks_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SipTrunks server but before - it is returned to user code. + it is returned to user code. This `post_list_sip_trunks` interceptor runs + before the `post_list_sip_trunks_with_metadata` interceptor. """ return response + def post_list_sip_trunks_with_metadata( + self, + response: sip_trunk.ListSipTrunksResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + sip_trunk.ListSipTrunksResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_sip_trunks + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SipTrunks server but before it is returned to user code. + + We recommend only using this `post_list_sip_trunks_with_metadata` + interceptor in new development instead of the `post_list_sip_trunks` interceptor. + When both interceptors are used, this `post_list_sip_trunks_with_metadata` interceptor runs after the + `post_list_sip_trunks` interceptor. The (possibly modified) response returned by + `post_list_sip_trunks` will be passed to + `post_list_sip_trunks_with_metadata`. + """ + return response, metadata + def pre_update_sip_trunk( self, request: gcd_sip_trunk.UpdateSipTrunkRequest, @@ -216,12 +287,35 @@ def post_update_sip_trunk( ) -> gcd_sip_trunk.SipTrunk: """Post-rpc interceptor for update_sip_trunk - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_sip_trunk_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SipTrunks server but before - it is returned to user code. + it is returned to user code. This `post_update_sip_trunk` interceptor runs + before the `post_update_sip_trunk_with_metadata` interceptor. """ return response + def post_update_sip_trunk_with_metadata( + self, + response: gcd_sip_trunk.SipTrunk, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_sip_trunk.SipTrunk, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_sip_trunk + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SipTrunks server but before it is returned to user code. + + We recommend only using this `post_update_sip_trunk_with_metadata` + interceptor in new development instead of the `post_update_sip_trunk` interceptor. + When both interceptors are used, this `post_update_sip_trunk_with_metadata` interceptor runs after the + `post_update_sip_trunk` interceptor. The (possibly modified) response returned by + `post_update_sip_trunk` will be passed to + `post_update_sip_trunk_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -569,6 +663,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_sip_trunk(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_sip_trunk_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -829,6 +927,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_sip_trunk(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_sip_trunk_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -976,6 +1078,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_sip_trunks(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sip_trunks_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1135,6 +1241,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_sip_trunk(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_sip_trunk_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/versions/client.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/versions/client.py index 34c71f34b62a..1361ccad80f1 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/versions/client.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/versions/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -487,6 +489,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1363,16 +1392,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1418,16 +1451,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, @@ -1528,16 +1565,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -1583,16 +1624,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/versions/transports/rest.py b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/versions/transports/rest.py index 3151e778e1ae..3200ca269ae6 100644 --- a/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/versions/transports/rest.py +++ b/packages/google-cloud-dialogflow/google/cloud/dialogflow_v2beta1/services/versions/transports/rest.py @@ -131,12 +131,35 @@ def pre_create_version( def post_create_version(self, response: gcd_version.Version) -> gcd_version.Version: """Post-rpc interceptor for create_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_create_version` interceptor runs + before the `post_create_version_with_metadata` interceptor. """ return response + def post_create_version_with_metadata( + self, + response: gcd_version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_create_version_with_metadata` + interceptor in new development instead of the `post_create_version` interceptor. + When both interceptors are used, this `post_create_version_with_metadata` interceptor runs after the + `post_create_version` interceptor. The (possibly modified) response returned by + `post_create_version` will be passed to + `post_create_version_with_metadata`. + """ + return response, metadata + def pre_delete_version( self, request: version.DeleteVersionRequest, @@ -164,12 +187,35 @@ def pre_get_version( def post_get_version(self, response: version.Version) -> version.Version: """Post-rpc interceptor for get_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_get_version` interceptor runs + before the `post_get_version_with_metadata` interceptor. """ return response + def post_get_version_with_metadata( + self, + response: version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_get_version_with_metadata` + interceptor in new development instead of the `post_get_version` interceptor. + When both interceptors are used, this `post_get_version_with_metadata` interceptor runs after the + `post_get_version` interceptor. The (possibly modified) response returned by + `post_get_version` will be passed to + `post_get_version_with_metadata`. + """ + return response, metadata + def pre_list_versions( self, request: version.ListVersionsRequest, @@ -187,12 +233,35 @@ def post_list_versions( ) -> version.ListVersionsResponse: """Post-rpc interceptor for list_versions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_versions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_list_versions` interceptor runs + before the `post_list_versions_with_metadata` interceptor. """ return response + def post_list_versions_with_metadata( + self, + response: version.ListVersionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[version.ListVersionsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_versions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_list_versions_with_metadata` + interceptor in new development instead of the `post_list_versions` interceptor. + When both interceptors are used, this `post_list_versions_with_metadata` interceptor runs after the + `post_list_versions` interceptor. The (possibly modified) response returned by + `post_list_versions` will be passed to + `post_list_versions_with_metadata`. + """ + return response, metadata + def pre_update_version( self, request: gcd_version.UpdateVersionRequest, @@ -210,12 +279,35 @@ def pre_update_version( def post_update_version(self, response: gcd_version.Version) -> gcd_version.Version: """Post-rpc interceptor for update_version - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_version_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Versions server but before - it is returned to user code. + it is returned to user code. This `post_update_version` interceptor runs + before the `post_update_version_with_metadata` interceptor. """ return response + def post_update_version_with_metadata( + self, + response: gcd_version.Version, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_version.Version, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_version + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Versions server but before it is returned to user code. + + We recommend only using this `post_update_version_with_metadata` + interceptor in new development instead of the `post_update_version` interceptor. + When both interceptors are used, this `post_update_version_with_metadata` interceptor runs after the + `post_update_version` interceptor. The (possibly modified) response returned by + `post_update_version` will be passed to + `post_update_version_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -574,6 +666,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -847,6 +943,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -992,6 +1092,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_versions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_versions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1162,6 +1266,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_version(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_version_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2.json b/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2.json index 136c7ce083db..7319fdfb442c 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2.json +++ b/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dialogflow", - "version": "2.38.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2beta1.json b/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2beta1.json index 1c257ede5513..9da05b9adb39 100644 --- a/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2beta1.json +++ b/packages/google-cloud-dialogflow/samples/generated_samples/snippet_metadata_google.cloud.dialogflow.v2beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dialogflow", - "version": "2.38.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_agents.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_agents.py index aced1370e2d5..c65e823d8356 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_agents.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_agents.py @@ -76,6 +76,13 @@ from google.cloud.dialogflow_v2.types import agent as gcd_agent from google.cloud.dialogflow_v2.types import validation_result +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -298,6 +305,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AgentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AgentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6134,10 +6184,13 @@ def test_get_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_get_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetAgentRequest.pb(agent.GetAgentRequest()) transcode.return_value = { "method": "post", @@ -6159,6 +6212,7 @@ def test_get_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.Agent() + post_with_metadata.return_value = agent.Agent(), metadata client.get_agent( request, @@ -6170,6 +6224,7 @@ def test_get_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_set_agent_rest_bad_request(request_type=gcd_agent.SetAgentRequest): @@ -6358,10 +6413,13 @@ def test_set_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_set_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_set_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_set_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_agent.SetAgentRequest.pb(gcd_agent.SetAgentRequest()) transcode.return_value = { "method": "post", @@ -6383,6 +6441,7 @@ def test_set_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_agent.Agent() + post_with_metadata.return_value = gcd_agent.Agent(), metadata client.set_agent( request, @@ -6394,6 +6453,7 @@ def test_set_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_agent_rest_bad_request(request_type=agent.DeleteAgentRequest): @@ -6577,10 +6637,13 @@ def test_search_agents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_search_agents" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_search_agents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_search_agents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.SearchAgentsRequest.pb(agent.SearchAgentsRequest()) transcode.return_value = { "method": "post", @@ -6602,6 +6665,7 @@ def test_search_agents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.SearchAgentsResponse() + post_with_metadata.return_value = agent.SearchAgentsResponse(), metadata client.search_agents( request, @@ -6613,6 +6677,7 @@ def test_search_agents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_train_agent_rest_bad_request(request_type=agent.TrainAgentRequest): @@ -6689,10 +6754,13 @@ def test_train_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_train_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_train_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_train_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.TrainAgentRequest.pb(agent.TrainAgentRequest()) transcode.return_value = { "method": "post", @@ -6714,6 +6782,7 @@ def test_train_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.train_agent( request, @@ -6725,6 +6794,7 @@ def test_train_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_agent_rest_bad_request(request_type=agent.ExportAgentRequest): @@ -6801,10 +6871,13 @@ def test_export_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_export_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_export_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_export_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ExportAgentRequest.pb(agent.ExportAgentRequest()) transcode.return_value = { "method": "post", @@ -6826,6 +6899,7 @@ def test_export_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_agent( request, @@ -6837,6 +6911,7 @@ def test_export_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_agent_rest_bad_request(request_type=agent.ImportAgentRequest): @@ -6913,10 +6988,13 @@ def test_import_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_import_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_import_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_import_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ImportAgentRequest.pb(agent.ImportAgentRequest()) transcode.return_value = { "method": "post", @@ -6938,6 +7016,7 @@ def test_import_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_agent( request, @@ -6949,6 +7028,7 @@ def test_import_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_restore_agent_rest_bad_request(request_type=agent.RestoreAgentRequest): @@ -7025,10 +7105,13 @@ def test_restore_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_restore_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_restore_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_restore_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.RestoreAgentRequest.pb(agent.RestoreAgentRequest()) transcode.return_value = { "method": "post", @@ -7050,6 +7133,7 @@ def test_restore_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.restore_agent( request, @@ -7061,6 +7145,7 @@ def test_restore_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_validation_result_rest_bad_request( @@ -7140,10 +7225,13 @@ def test_get_validation_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_validation_result" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_get_validation_result_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_validation_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetValidationResultRequest.pb( agent.GetValidationResultRequest() ) @@ -7169,6 +7257,7 @@ def test_get_validation_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = validation_result.ValidationResult() + post_with_metadata.return_value = validation_result.ValidationResult(), metadata client.get_validation_result( request, @@ -7180,6 +7269,7 @@ def test_get_validation_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_answer_records.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_answer_records.py index ce401ed83240..eb6a842340be 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_answer_records.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_answer_records.py @@ -67,6 +67,13 @@ from google.cloud.dialogflow_v2.types import answer_record from google.cloud.dialogflow_v2.types import answer_record as gcd_answer_record +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -321,6 +328,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AnswerRecordsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AnswerRecordsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2726,10 +2776,14 @@ def test_list_answer_records_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AnswerRecordsRestInterceptor, "post_list_answer_records" ) as post, mock.patch.object( + transports.AnswerRecordsRestInterceptor, + "post_list_answer_records_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AnswerRecordsRestInterceptor, "pre_list_answer_records" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = answer_record.ListAnswerRecordsRequest.pb( answer_record.ListAnswerRecordsRequest() ) @@ -2755,6 +2809,10 @@ def test_list_answer_records_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = answer_record.ListAnswerRecordsResponse() + post_with_metadata.return_value = ( + answer_record.ListAnswerRecordsResponse(), + metadata, + ) client.list_answer_records( request, @@ -2766,6 +2824,7 @@ def test_list_answer_records_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_answer_record_rest_bad_request( @@ -3177,10 +3236,14 @@ def test_update_answer_record_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AnswerRecordsRestInterceptor, "post_update_answer_record" ) as post, mock.patch.object( + transports.AnswerRecordsRestInterceptor, + "post_update_answer_record_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AnswerRecordsRestInterceptor, "pre_update_answer_record" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_answer_record.UpdateAnswerRecordRequest.pb( gcd_answer_record.UpdateAnswerRecordRequest() ) @@ -3206,6 +3269,7 @@ def test_update_answer_record_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_answer_record.AnswerRecord() + post_with_metadata.return_value = gcd_answer_record.AnswerRecord(), metadata client.update_answer_record( request, @@ -3217,6 +3281,7 @@ def test_update_answer_record_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_contexts.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_contexts.py index 43fdefbc3c57..dff779bbc974 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_contexts.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_contexts.py @@ -65,6 +65,13 @@ from google.cloud.dialogflow_v2.types import context from google.cloud.dialogflow_v2.types import context as gcd_context +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -295,6 +302,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ContextsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ContextsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4799,10 +4849,13 @@ def test_list_contexts_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ContextsRestInterceptor, "post_list_contexts" ) as post, mock.patch.object( + transports.ContextsRestInterceptor, "post_list_contexts_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ContextsRestInterceptor, "pre_list_contexts" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = context.ListContextsRequest.pb(context.ListContextsRequest()) transcode.return_value = { "method": "post", @@ -4826,6 +4879,7 @@ def test_list_contexts_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = context.ListContextsResponse() + post_with_metadata.return_value = context.ListContextsResponse(), metadata client.list_contexts( request, @@ -4837,6 +4891,7 @@ def test_list_contexts_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_context_rest_bad_request(request_type=context.GetContextRequest): @@ -4919,10 +4974,13 @@ def test_get_context_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ContextsRestInterceptor, "post_get_context" ) as post, mock.patch.object( + transports.ContextsRestInterceptor, "post_get_context_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ContextsRestInterceptor, "pre_get_context" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = context.GetContextRequest.pb(context.GetContextRequest()) transcode.return_value = { "method": "post", @@ -4944,6 +5002,7 @@ def test_get_context_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = context.Context() + post_with_metadata.return_value = context.Context(), metadata client.get_context( request, @@ -4955,6 +5014,7 @@ def test_get_context_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_context_rest_bad_request(request_type=gcd_context.CreateContextRequest): @@ -5109,10 +5169,13 @@ def test_create_context_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ContextsRestInterceptor, "post_create_context" ) as post, mock.patch.object( + transports.ContextsRestInterceptor, "post_create_context_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ContextsRestInterceptor, "pre_create_context" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_context.CreateContextRequest.pb( gcd_context.CreateContextRequest() ) @@ -5136,6 +5199,7 @@ def test_create_context_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_context.Context() + post_with_metadata.return_value = gcd_context.Context(), metadata client.create_context( request, @@ -5147,6 +5211,7 @@ def test_create_context_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_context_rest_bad_request(request_type=gcd_context.UpdateContextRequest): @@ -5305,10 +5370,13 @@ def test_update_context_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ContextsRestInterceptor, "post_update_context" ) as post, mock.patch.object( + transports.ContextsRestInterceptor, "post_update_context_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ContextsRestInterceptor, "pre_update_context" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_context.UpdateContextRequest.pb( gcd_context.UpdateContextRequest() ) @@ -5332,6 +5400,7 @@ def test_update_context_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_context.Context() + post_with_metadata.return_value = gcd_context.Context(), metadata client.update_context( request, @@ -5343,6 +5412,7 @@ def test_update_context_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_context_rest_bad_request(request_type=context.DeleteContextRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_datasets.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_datasets.py index a7e9c4b55913..ae82c2f6aba8 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_datasets.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_datasets.py @@ -77,6 +77,13 @@ from google.cloud.dialogflow_v2.types import conversation_dataset from google.cloud.dialogflow_v2.types import gcs +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -350,6 +357,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationDatasetsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationDatasetsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4541,11 +4591,15 @@ def test_create_conversation_dataset_rest_interceptors(null_interceptor): transports.ConversationDatasetsRestInterceptor, "post_create_conversation_dataset", ) as post, mock.patch.object( + transports.ConversationDatasetsRestInterceptor, + "post_create_conversation_dataset_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationDatasetsRestInterceptor, "pre_create_conversation_dataset", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_dataset.CreateConversationDatasetRequest.pb( gcd_conversation_dataset.CreateConversationDatasetRequest() ) @@ -4569,6 +4623,7 @@ def test_create_conversation_dataset_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_conversation_dataset( request, @@ -4580,6 +4635,7 @@ def test_create_conversation_dataset_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_dataset_rest_bad_request( @@ -4674,10 +4730,14 @@ def test_get_conversation_dataset_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationDatasetsRestInterceptor, "post_get_conversation_dataset" ) as post, mock.patch.object( + transports.ConversationDatasetsRestInterceptor, + "post_get_conversation_dataset_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationDatasetsRestInterceptor, "pre_get_conversation_dataset" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_dataset.GetConversationDatasetRequest.pb( conversation_dataset.GetConversationDatasetRequest() ) @@ -4703,6 +4763,10 @@ def test_get_conversation_dataset_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_dataset.ConversationDataset() + post_with_metadata.return_value = ( + conversation_dataset.ConversationDataset(), + metadata, + ) client.get_conversation_dataset( request, @@ -4714,6 +4778,7 @@ def test_get_conversation_dataset_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_conversation_datasets_rest_bad_request( @@ -4801,10 +4866,14 @@ def test_list_conversation_datasets_rest_interceptors(null_interceptor): transports.ConversationDatasetsRestInterceptor, "post_list_conversation_datasets", ) as post, mock.patch.object( + transports.ConversationDatasetsRestInterceptor, + "post_list_conversation_datasets_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationDatasetsRestInterceptor, "pre_list_conversation_datasets" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_dataset.ListConversationDatasetsRequest.pb( conversation_dataset.ListConversationDatasetsRequest() ) @@ -4830,6 +4899,10 @@ def test_list_conversation_datasets_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_dataset.ListConversationDatasetsResponse() + post_with_metadata.return_value = ( + conversation_dataset.ListConversationDatasetsResponse(), + metadata, + ) client.list_conversation_datasets( request, @@ -4841,6 +4914,7 @@ def test_list_conversation_datasets_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_conversation_dataset_rest_bad_request( @@ -4926,11 +5000,15 @@ def test_delete_conversation_dataset_rest_interceptors(null_interceptor): transports.ConversationDatasetsRestInterceptor, "post_delete_conversation_dataset", ) as post, mock.patch.object( + transports.ConversationDatasetsRestInterceptor, + "post_delete_conversation_dataset_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationDatasetsRestInterceptor, "pre_delete_conversation_dataset", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_dataset.DeleteConversationDatasetRequest.pb( conversation_dataset.DeleteConversationDatasetRequest() ) @@ -4954,6 +5032,7 @@ def test_delete_conversation_dataset_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_conversation_dataset( request, @@ -4965,6 +5044,7 @@ def test_delete_conversation_dataset_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_conversation_data_rest_bad_request( @@ -5045,10 +5125,14 @@ def test_import_conversation_data_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ConversationDatasetsRestInterceptor, "post_import_conversation_data" ) as post, mock.patch.object( + transports.ConversationDatasetsRestInterceptor, + "post_import_conversation_data_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationDatasetsRestInterceptor, "pre_import_conversation_data" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_dataset.ImportConversationDataRequest.pb( conversation_dataset.ImportConversationDataRequest() ) @@ -5072,6 +5156,7 @@ def test_import_conversation_data_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_conversation_data( request, @@ -5083,6 +5168,7 @@ def test_import_conversation_data_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_models.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_models.py index 3a2f483d9d78..fc45fa66702e 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_models.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_models.py @@ -76,6 +76,13 @@ ) from google.cloud.dialogflow_v2.types import conversation_model +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -347,6 +354,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationModelsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationModelsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7035,10 +7085,14 @@ def test_create_conversation_model_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ConversationModelsRestInterceptor, "post_create_conversation_model" ) as post, mock.patch.object( + transports.ConversationModelsRestInterceptor, + "post_create_conversation_model_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationModelsRestInterceptor, "pre_create_conversation_model" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_model.CreateConversationModelRequest.pb( gcd_conversation_model.CreateConversationModelRequest() ) @@ -7062,6 +7116,7 @@ def test_create_conversation_model_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_conversation_model( request, @@ -7073,6 +7128,7 @@ def test_create_conversation_model_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_model_rest_bad_request( @@ -7167,10 +7223,14 @@ def test_get_conversation_model_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationModelsRestInterceptor, "post_get_conversation_model" ) as post, mock.patch.object( + transports.ConversationModelsRestInterceptor, + "post_get_conversation_model_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationModelsRestInterceptor, "pre_get_conversation_model" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_model.GetConversationModelRequest.pb( conversation_model.GetConversationModelRequest() ) @@ -7196,6 +7256,10 @@ def test_get_conversation_model_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_model.ConversationModel() + post_with_metadata.return_value = ( + conversation_model.ConversationModel(), + metadata, + ) client.get_conversation_model( request, @@ -7207,6 +7271,7 @@ def test_get_conversation_model_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_conversation_models_rest_bad_request( @@ -7293,10 +7358,14 @@ def test_list_conversation_models_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationModelsRestInterceptor, "post_list_conversation_models" ) as post, mock.patch.object( + transports.ConversationModelsRestInterceptor, + "post_list_conversation_models_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationModelsRestInterceptor, "pre_list_conversation_models" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_model.ListConversationModelsRequest.pb( conversation_model.ListConversationModelsRequest() ) @@ -7322,6 +7391,10 @@ def test_list_conversation_models_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_model.ListConversationModelsResponse() + post_with_metadata.return_value = ( + conversation_model.ListConversationModelsResponse(), + metadata, + ) client.list_conversation_models( request, @@ -7333,6 +7406,7 @@ def test_list_conversation_models_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_conversation_model_rest_bad_request( @@ -7413,10 +7487,14 @@ def test_delete_conversation_model_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ConversationModelsRestInterceptor, "post_delete_conversation_model" ) as post, mock.patch.object( + transports.ConversationModelsRestInterceptor, + "post_delete_conversation_model_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationModelsRestInterceptor, "pre_delete_conversation_model" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_model.DeleteConversationModelRequest.pb( conversation_model.DeleteConversationModelRequest() ) @@ -7440,6 +7518,7 @@ def test_delete_conversation_model_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_conversation_model( request, @@ -7451,6 +7530,7 @@ def test_delete_conversation_model_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_deploy_conversation_model_rest_bad_request( @@ -7531,10 +7611,14 @@ def test_deploy_conversation_model_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ConversationModelsRestInterceptor, "post_deploy_conversation_model" ) as post, mock.patch.object( + transports.ConversationModelsRestInterceptor, + "post_deploy_conversation_model_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationModelsRestInterceptor, "pre_deploy_conversation_model" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_model.DeployConversationModelRequest.pb( conversation_model.DeployConversationModelRequest() ) @@ -7558,6 +7642,7 @@ def test_deploy_conversation_model_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.deploy_conversation_model( request, @@ -7569,6 +7654,7 @@ def test_deploy_conversation_model_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_undeploy_conversation_model_rest_bad_request( @@ -7649,10 +7735,14 @@ def test_undeploy_conversation_model_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ConversationModelsRestInterceptor, "post_undeploy_conversation_model" ) as post, mock.patch.object( + transports.ConversationModelsRestInterceptor, + "post_undeploy_conversation_model_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationModelsRestInterceptor, "pre_undeploy_conversation_model" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_model.UndeployConversationModelRequest.pb( conversation_model.UndeployConversationModelRequest() ) @@ -7676,6 +7766,7 @@ def test_undeploy_conversation_model_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.undeploy_conversation_model( request, @@ -7687,6 +7778,7 @@ def test_undeploy_conversation_model_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_model_evaluation_rest_bad_request( @@ -7780,11 +7872,15 @@ def test_get_conversation_model_evaluation_rest_interceptors(null_interceptor): transports.ConversationModelsRestInterceptor, "post_get_conversation_model_evaluation", ) as post, mock.patch.object( + transports.ConversationModelsRestInterceptor, + "post_get_conversation_model_evaluation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationModelsRestInterceptor, "pre_get_conversation_model_evaluation", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_model.GetConversationModelEvaluationRequest.pb( conversation_model.GetConversationModelEvaluationRequest() ) @@ -7810,6 +7906,10 @@ def test_get_conversation_model_evaluation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_model.ConversationModelEvaluation() + post_with_metadata.return_value = ( + conversation_model.ConversationModelEvaluation(), + metadata, + ) client.get_conversation_model_evaluation( request, @@ -7821,6 +7921,7 @@ def test_get_conversation_model_evaluation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_conversation_model_evaluations_rest_bad_request( @@ -7908,11 +8009,15 @@ def test_list_conversation_model_evaluations_rest_interceptors(null_interceptor) transports.ConversationModelsRestInterceptor, "post_list_conversation_model_evaluations", ) as post, mock.patch.object( + transports.ConversationModelsRestInterceptor, + "post_list_conversation_model_evaluations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationModelsRestInterceptor, "pre_list_conversation_model_evaluations", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_model.ListConversationModelEvaluationsRequest.pb( conversation_model.ListConversationModelEvaluationsRequest() ) @@ -7942,6 +8047,10 @@ def test_list_conversation_model_evaluations_rest_interceptors(null_interceptor) post.return_value = ( conversation_model.ListConversationModelEvaluationsResponse() ) + post_with_metadata.return_value = ( + conversation_model.ListConversationModelEvaluationsResponse(), + metadata, + ) client.list_conversation_model_evaluations( request, @@ -7953,6 +8062,7 @@ def test_list_conversation_model_evaluations_rest_interceptors(null_interceptor) pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_conversation_model_evaluation_rest_bad_request( @@ -8038,11 +8148,15 @@ def test_create_conversation_model_evaluation_rest_interceptors(null_interceptor transports.ConversationModelsRestInterceptor, "post_create_conversation_model_evaluation", ) as post, mock.patch.object( + transports.ConversationModelsRestInterceptor, + "post_create_conversation_model_evaluation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationModelsRestInterceptor, "pre_create_conversation_model_evaluation", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_model.CreateConversationModelEvaluationRequest.pb( conversation_model.CreateConversationModelEvaluationRequest() ) @@ -8066,6 +8180,7 @@ def test_create_conversation_model_evaluation_rest_interceptors(null_interceptor ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_conversation_model_evaluation( request, @@ -8077,6 +8192,7 @@ def test_create_conversation_model_evaluation_rest_interceptors(null_interceptor pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_profiles.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_profiles.py index f2a4a6d94404..8b8ad346dec1 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_profiles.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversation_profiles.py @@ -79,6 +79,13 @@ from google.cloud.dialogflow_v2.types import conversation_profile from google.cloud.dialogflow_v2.types import participant +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -352,6 +359,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationProfilesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationProfilesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5903,10 +5953,14 @@ def test_list_conversation_profiles_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_list_conversation_profiles", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_list_conversation_profiles_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_list_conversation_profiles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_profile.ListConversationProfilesRequest.pb( conversation_profile.ListConversationProfilesRequest() ) @@ -5932,6 +5986,10 @@ def test_list_conversation_profiles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_profile.ListConversationProfilesResponse() + post_with_metadata.return_value = ( + conversation_profile.ListConversationProfilesResponse(), + metadata, + ) client.list_conversation_profiles( request, @@ -5943,6 +6001,7 @@ def test_list_conversation_profiles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_profile_rest_bad_request( @@ -6035,10 +6094,14 @@ def test_get_conversation_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationProfilesRestInterceptor, "post_get_conversation_profile" ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_get_conversation_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_get_conversation_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_profile.GetConversationProfileRequest.pb( conversation_profile.GetConversationProfileRequest() ) @@ -6064,6 +6127,10 @@ def test_get_conversation_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_profile.ConversationProfile() + post_with_metadata.return_value = ( + conversation_profile.ConversationProfile(), + metadata, + ) client.get_conversation_profile( request, @@ -6075,6 +6142,7 @@ def test_get_conversation_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_conversation_profile_rest_bad_request( @@ -6341,11 +6409,15 @@ def test_create_conversation_profile_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_create_conversation_profile", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_create_conversation_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_create_conversation_profile", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_profile.CreateConversationProfileRequest.pb( gcd_conversation_profile.CreateConversationProfileRequest() ) @@ -6371,6 +6443,10 @@ def test_create_conversation_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation_profile.ConversationProfile() + post_with_metadata.return_value = ( + gcd_conversation_profile.ConversationProfile(), + metadata, + ) client.create_conversation_profile( request, @@ -6382,6 +6458,7 @@ def test_create_conversation_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_conversation_profile_rest_bad_request( @@ -6656,11 +6733,15 @@ def test_update_conversation_profile_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_update_conversation_profile", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_update_conversation_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_update_conversation_profile", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_profile.UpdateConversationProfileRequest.pb( gcd_conversation_profile.UpdateConversationProfileRequest() ) @@ -6686,6 +6767,10 @@ def test_update_conversation_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation_profile.ConversationProfile() + post_with_metadata.return_value = ( + gcd_conversation_profile.ConversationProfile(), + metadata, + ) client.update_conversation_profile( request, @@ -6697,6 +6782,7 @@ def test_update_conversation_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_conversation_profile_rest_bad_request( @@ -6892,11 +6978,15 @@ def test_set_suggestion_feature_config_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_set_suggestion_feature_config", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_set_suggestion_feature_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_set_suggestion_feature_config", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_profile.SetSuggestionFeatureConfigRequest.pb( gcd_conversation_profile.SetSuggestionFeatureConfigRequest() ) @@ -6920,6 +7010,7 @@ def test_set_suggestion_feature_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.set_suggestion_feature_config( request, @@ -6931,6 +7022,7 @@ def test_set_suggestion_feature_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_clear_suggestion_feature_config_rest_bad_request( @@ -7016,11 +7108,15 @@ def test_clear_suggestion_feature_config_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_clear_suggestion_feature_config", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_clear_suggestion_feature_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_clear_suggestion_feature_config", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_profile.ClearSuggestionFeatureConfigRequest.pb( gcd_conversation_profile.ClearSuggestionFeatureConfigRequest() ) @@ -7044,6 +7140,7 @@ def test_clear_suggestion_feature_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.clear_suggestion_feature_config( request, @@ -7055,6 +7152,7 @@ def test_clear_suggestion_feature_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversations.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversations.py index b785646e2385..7dd7493016a1 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversations.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_conversations.py @@ -73,6 +73,13 @@ from google.cloud.dialogflow_v2.types import conversation from google.cloud.dialogflow_v2.types import conversation as gcd_conversation +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -327,6 +334,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6766,10 +6816,14 @@ def test_create_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_create_conversation" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_create_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_create_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation.CreateConversationRequest.pb( gcd_conversation.CreateConversationRequest() ) @@ -6795,6 +6849,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.Conversation() + post_with_metadata.return_value = gcd_conversation.Conversation(), metadata client.create_conversation( request, @@ -6806,6 +6861,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_conversations_rest_bad_request( @@ -6890,10 +6946,13 @@ def test_list_conversations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_list_conversations" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, "post_list_conversations_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_list_conversations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.ListConversationsRequest.pb( conversation.ListConversationsRequest() ) @@ -6919,6 +6978,10 @@ def test_list_conversations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.ListConversationsResponse() + post_with_metadata.return_value = ( + conversation.ListConversationsResponse(), + metadata, + ) client.list_conversations( request, @@ -6930,6 +6993,7 @@ def test_list_conversations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_rest_bad_request( @@ -7025,10 +7089,13 @@ def test_get_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_get_conversation" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, "post_get_conversation_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_get_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.GetConversationRequest.pb( conversation.GetConversationRequest() ) @@ -7052,6 +7119,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.Conversation() + post_with_metadata.return_value = conversation.Conversation(), metadata client.get_conversation( request, @@ -7063,6 +7131,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_complete_conversation_rest_bad_request( @@ -7158,10 +7227,14 @@ def test_complete_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_complete_conversation" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_complete_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_complete_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.CompleteConversationRequest.pb( conversation.CompleteConversationRequest() ) @@ -7185,6 +7258,7 @@ def test_complete_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.Conversation() + post_with_metadata.return_value = conversation.Conversation(), metadata client.complete_conversation( request, @@ -7196,6 +7270,7 @@ def test_complete_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_messages_rest_bad_request(request_type=conversation.ListMessagesRequest): @@ -7278,10 +7353,13 @@ def test_list_messages_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_list_messages" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, "post_list_messages_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_list_messages" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.ListMessagesRequest.pb( conversation.ListMessagesRequest() ) @@ -7307,6 +7385,7 @@ def test_list_messages_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.ListMessagesResponse() + post_with_metadata.return_value = conversation.ListMessagesResponse(), metadata client.list_messages( request, @@ -7318,6 +7397,7 @@ def test_list_messages_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_suggest_conversation_summary_rest_bad_request( @@ -7406,10 +7486,14 @@ def test_suggest_conversation_summary_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_suggest_conversation_summary" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_suggest_conversation_summary_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_suggest_conversation_summary" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation.SuggestConversationSummaryRequest.pb( gcd_conversation.SuggestConversationSummaryRequest() ) @@ -7435,6 +7519,10 @@ def test_suggest_conversation_summary_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.SuggestConversationSummaryResponse() + post_with_metadata.return_value = ( + gcd_conversation.SuggestConversationSummaryResponse(), + metadata, + ) client.suggest_conversation_summary( request, @@ -7446,6 +7534,7 @@ def test_suggest_conversation_summary_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_generate_stateless_summary_rest_bad_request( @@ -7532,10 +7621,14 @@ def test_generate_stateless_summary_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_generate_stateless_summary" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_generate_stateless_summary_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_generate_stateless_summary" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.GenerateStatelessSummaryRequest.pb( conversation.GenerateStatelessSummaryRequest() ) @@ -7561,6 +7654,10 @@ def test_generate_stateless_summary_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.GenerateStatelessSummaryResponse() + post_with_metadata.return_value = ( + conversation.GenerateStatelessSummaryResponse(), + metadata, + ) client.generate_stateless_summary( request, @@ -7572,6 +7669,7 @@ def test_generate_stateless_summary_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_generate_stateless_suggestion_rest_bad_request( @@ -7653,10 +7751,14 @@ def test_generate_stateless_suggestion_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_generate_stateless_suggestion" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_generate_stateless_suggestion_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_generate_stateless_suggestion" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.GenerateStatelessSuggestionRequest.pb( conversation.GenerateStatelessSuggestionRequest() ) @@ -7682,6 +7784,10 @@ def test_generate_stateless_suggestion_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.GenerateStatelessSuggestionResponse() + post_with_metadata.return_value = ( + conversation.GenerateStatelessSuggestionResponse(), + metadata, + ) client.generate_stateless_suggestion( request, @@ -7693,6 +7799,7 @@ def test_generate_stateless_suggestion_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_search_knowledge_rest_bad_request( @@ -7777,10 +7884,13 @@ def test_search_knowledge_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_search_knowledge" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, "post_search_knowledge_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_search_knowledge" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.SearchKnowledgeRequest.pb( conversation.SearchKnowledgeRequest() ) @@ -7806,6 +7916,10 @@ def test_search_knowledge_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.SearchKnowledgeResponse() + post_with_metadata.return_value = ( + conversation.SearchKnowledgeResponse(), + metadata, + ) client.search_knowledge( request, @@ -7817,6 +7931,7 @@ def test_search_knowledge_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_documents.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_documents.py index e4e4c82e7ca5..2b6acf0fe842 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_documents.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_documents.py @@ -78,6 +78,13 @@ from google.cloud.dialogflow_v2.types import document as gcd_document from google.cloud.dialogflow_v2.types import gcs +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -311,6 +318,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DocumentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DocumentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5720,10 +5770,13 @@ def test_list_documents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentsRestInterceptor, "post_list_documents" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_list_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_list_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.ListDocumentsRequest.pb(document.ListDocumentsRequest()) transcode.return_value = { "method": "post", @@ -5747,6 +5800,7 @@ def test_list_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document.ListDocumentsResponse() + post_with_metadata.return_value = document.ListDocumentsResponse(), metadata client.list_documents( request, @@ -5758,6 +5812,7 @@ def test_list_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_document_rest_bad_request(request_type=document.GetDocumentRequest): @@ -5849,10 +5904,13 @@ def test_get_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentsRestInterceptor, "post_get_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_get_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_get_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.GetDocumentRequest.pb(document.GetDocumentRequest()) transcode.return_value = { "method": "post", @@ -5874,6 +5932,7 @@ def test_get_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document.Document() + post_with_metadata.return_value = document.Document(), metadata client.get_document( request, @@ -5885,6 +5944,7 @@ def test_get_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_document_rest_bad_request( @@ -6054,10 +6114,13 @@ def test_create_document_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_create_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_create_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_create_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_document.CreateDocumentRequest.pb( gcd_document.CreateDocumentRequest() ) @@ -6081,6 +6144,7 @@ def test_create_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_document( request, @@ -6092,6 +6156,7 @@ def test_create_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_documents_rest_bad_request( @@ -6170,10 +6235,13 @@ def test_import_documents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_import_documents" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_import_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_import_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.ImportDocumentsRequest.pb( document.ImportDocumentsRequest() ) @@ -6197,6 +6265,7 @@ def test_import_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_documents( request, @@ -6208,6 +6277,7 @@ def test_import_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_document_rest_bad_request(request_type=document.DeleteDocumentRequest): @@ -6284,10 +6354,13 @@ def test_delete_document_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_delete_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_delete_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_delete_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.DeleteDocumentRequest.pb(document.DeleteDocumentRequest()) transcode.return_value = { "method": "post", @@ -6309,6 +6382,7 @@ def test_delete_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_document( request, @@ -6320,6 +6394,7 @@ def test_delete_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_document_rest_bad_request( @@ -6497,10 +6572,13 @@ def test_update_document_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_update_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_update_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_update_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_document.UpdateDocumentRequest.pb( gcd_document.UpdateDocumentRequest() ) @@ -6524,6 +6602,7 @@ def test_update_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_document( request, @@ -6535,6 +6614,7 @@ def test_update_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_reload_document_rest_bad_request(request_type=document.ReloadDocumentRequest): @@ -6611,10 +6691,13 @@ def test_reload_document_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_reload_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_reload_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_reload_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.ReloadDocumentRequest.pb(document.ReloadDocumentRequest()) transcode.return_value = { "method": "post", @@ -6636,6 +6719,7 @@ def test_reload_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.reload_document( request, @@ -6647,6 +6731,7 @@ def test_reload_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_document_rest_bad_request(request_type=document.ExportDocumentRequest): @@ -6723,10 +6808,13 @@ def test_export_document_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_export_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_export_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_export_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.ExportDocumentRequest.pb(document.ExportDocumentRequest()) transcode.return_value = { "method": "post", @@ -6748,6 +6836,7 @@ def test_export_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_document( request, @@ -6759,6 +6848,7 @@ def test_export_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_encryption_spec_service.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_encryption_spec_service.py index 4cd2f5c3f96e..1dd9d0c39271 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_encryption_spec_service.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_encryption_spec_service.py @@ -71,6 +71,13 @@ from google.cloud.dialogflow_v2.types import encryption_spec as gcd_encryption_spec from google.cloud.dialogflow_v2.types import encryption_spec +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -346,6 +353,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EncryptionSpecServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EncryptionSpecServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2503,10 +2553,14 @@ def test_get_encryption_spec_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EncryptionSpecServiceRestInterceptor, "post_get_encryption_spec" ) as post, mock.patch.object( + transports.EncryptionSpecServiceRestInterceptor, + "post_get_encryption_spec_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EncryptionSpecServiceRestInterceptor, "pre_get_encryption_spec" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = encryption_spec.GetEncryptionSpecRequest.pb( encryption_spec.GetEncryptionSpecRequest() ) @@ -2532,6 +2586,7 @@ def test_get_encryption_spec_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = encryption_spec.EncryptionSpec() + post_with_metadata.return_value = encryption_spec.EncryptionSpec(), metadata client.get_encryption_spec( request, @@ -2543,6 +2598,7 @@ def test_get_encryption_spec_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_encryption_spec_rest_bad_request( @@ -2628,11 +2684,15 @@ def test_initialize_encryption_spec_rest_interceptors(null_interceptor): transports.EncryptionSpecServiceRestInterceptor, "post_initialize_encryption_spec", ) as post, mock.patch.object( + transports.EncryptionSpecServiceRestInterceptor, + "post_initialize_encryption_spec_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EncryptionSpecServiceRestInterceptor, "pre_initialize_encryption_spec", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_encryption_spec.InitializeEncryptionSpecRequest.pb( gcd_encryption_spec.InitializeEncryptionSpecRequest() ) @@ -2656,6 +2716,7 @@ def test_initialize_encryption_spec_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.initialize_encryption_spec( request, @@ -2667,6 +2728,7 @@ def test_initialize_encryption_spec_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_entity_types.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_entity_types.py index 6df134b39b3b..4611c00eafe7 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_entity_types.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_entity_types.py @@ -75,6 +75,13 @@ from google.cloud.dialogflow_v2.types import entity_type from google.cloud.dialogflow_v2.types import entity_type as gcd_entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -314,6 +321,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7415,10 +7465,13 @@ def test_list_entity_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_list_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_list_entity_types_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_list_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.ListEntityTypesRequest.pb( entity_type.ListEntityTypesRequest() ) @@ -7444,6 +7497,10 @@ def test_list_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = entity_type.ListEntityTypesResponse() + post_with_metadata.return_value = ( + entity_type.ListEntityTypesResponse(), + metadata, + ) client.list_entity_types( request, @@ -7455,6 +7512,7 @@ def test_list_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_entity_type_rest_bad_request( @@ -7550,10 +7608,13 @@ def test_get_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_get_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_get_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_get_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.GetEntityTypeRequest.pb( entity_type.GetEntityTypeRequest() ) @@ -7577,6 +7638,7 @@ def test_get_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = entity_type.EntityType() + post_with_metadata.return_value = entity_type.EntityType(), metadata client.get_entity_type( request, @@ -7588,6 +7650,7 @@ def test_get_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_entity_type_rest_bad_request( @@ -7760,10 +7823,13 @@ def test_create_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_create_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_create_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_create_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_entity_type.CreateEntityTypeRequest.pb( gcd_entity_type.CreateEntityTypeRequest() ) @@ -7787,6 +7853,7 @@ def test_create_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_entity_type.EntityType() + post_with_metadata.return_value = gcd_entity_type.EntityType(), metadata client.create_entity_type( request, @@ -7798,6 +7865,7 @@ def test_create_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_entity_type_rest_bad_request( @@ -7974,10 +8042,13 @@ def test_update_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_update_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_update_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_update_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_entity_type.UpdateEntityTypeRequest.pb( gcd_entity_type.UpdateEntityTypeRequest() ) @@ -8001,6 +8072,7 @@ def test_update_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_entity_type.EntityType() + post_with_metadata.return_value = gcd_entity_type.EntityType(), metadata client.update_entity_type( request, @@ -8012,6 +8084,7 @@ def test_update_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_entity_type_rest_bad_request( @@ -8201,10 +8274,14 @@ def test_batch_update_entity_types_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_update_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_update_entity_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_update_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchUpdateEntityTypesRequest.pb( entity_type.BatchUpdateEntityTypesRequest() ) @@ -8228,6 +8305,7 @@ def test_batch_update_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_update_entity_types( request, @@ -8239,6 +8317,7 @@ def test_batch_update_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_delete_entity_types_rest_bad_request( @@ -8319,10 +8398,14 @@ def test_batch_delete_entity_types_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_delete_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_delete_entity_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_delete_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchDeleteEntityTypesRequest.pb( entity_type.BatchDeleteEntityTypesRequest() ) @@ -8346,6 +8429,7 @@ def test_batch_delete_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_delete_entity_types( request, @@ -8357,6 +8441,7 @@ def test_batch_delete_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_create_entities_rest_bad_request( @@ -8437,10 +8522,14 @@ def test_batch_create_entities_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_create_entities" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_create_entities_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_create_entities" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchCreateEntitiesRequest.pb( entity_type.BatchCreateEntitiesRequest() ) @@ -8464,6 +8553,7 @@ def test_batch_create_entities_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_create_entities( request, @@ -8475,6 +8565,7 @@ def test_batch_create_entities_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_update_entities_rest_bad_request( @@ -8555,10 +8646,14 @@ def test_batch_update_entities_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_update_entities" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_update_entities_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_update_entities" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchUpdateEntitiesRequest.pb( entity_type.BatchUpdateEntitiesRequest() ) @@ -8582,6 +8677,7 @@ def test_batch_update_entities_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_update_entities( request, @@ -8593,6 +8689,7 @@ def test_batch_update_entities_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_delete_entities_rest_bad_request( @@ -8673,10 +8770,14 @@ def test_batch_delete_entities_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_delete_entities" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_delete_entities_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_delete_entities" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchDeleteEntitiesRequest.pb( entity_type.BatchDeleteEntitiesRequest() ) @@ -8700,6 +8801,7 @@ def test_batch_delete_entities_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_delete_entities( request, @@ -8711,6 +8813,7 @@ def test_batch_delete_entities_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_environments.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_environments.py index e216c11e0feb..6bcded9af26f 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_environments.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_environments.py @@ -64,6 +64,13 @@ ) from google.cloud.dialogflow_v2.types import audio_config, environment, fulfillment +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -307,6 +314,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EnvironmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EnvironmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4595,10 +4645,13 @@ def test_list_environments_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_list_environments" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_list_environments_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_list_environments" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.ListEnvironmentsRequest.pb( environment.ListEnvironmentsRequest() ) @@ -4624,6 +4677,10 @@ def test_list_environments_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.ListEnvironmentsResponse() + post_with_metadata.return_value = ( + environment.ListEnvironmentsResponse(), + metadata, + ) client.list_environments( request, @@ -4635,6 +4692,7 @@ def test_list_environments_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_environment_rest_bad_request( @@ -4725,10 +4783,13 @@ def test_get_environment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_get_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_get_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_get_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.GetEnvironmentRequest.pb( environment.GetEnvironmentRequest() ) @@ -4752,6 +4813,7 @@ def test_get_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.Environment() + post_with_metadata.return_value = environment.Environment(), metadata client.get_environment( request, @@ -4763,6 +4825,7 @@ def test_get_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_environment_rest_bad_request( @@ -4946,10 +5009,13 @@ def test_create_environment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_create_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_create_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_create_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.CreateEnvironmentRequest.pb( environment.CreateEnvironmentRequest() ) @@ -4973,6 +5039,7 @@ def test_create_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.Environment() + post_with_metadata.return_value = environment.Environment(), metadata client.create_environment( request, @@ -4984,6 +5051,7 @@ def test_create_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_environment_rest_bad_request( @@ -5171,10 +5239,13 @@ def test_update_environment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_update_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_update_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_update_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.UpdateEnvironmentRequest.pb( environment.UpdateEnvironmentRequest() ) @@ -5198,6 +5269,7 @@ def test_update_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.Environment() + post_with_metadata.return_value = environment.Environment(), metadata client.update_environment( request, @@ -5209,6 +5281,7 @@ def test_update_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_environment_rest_bad_request( @@ -5404,10 +5477,14 @@ def test_get_environment_history_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_get_environment_history" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, + "post_get_environment_history_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_get_environment_history" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.GetEnvironmentHistoryRequest.pb( environment.GetEnvironmentHistoryRequest() ) @@ -5433,6 +5510,7 @@ def test_get_environment_history_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.EnvironmentHistory() + post_with_metadata.return_value = environment.EnvironmentHistory(), metadata client.get_environment_history( request, @@ -5444,6 +5522,7 @@ def test_get_environment_history_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_fulfillments.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_fulfillments.py index a832ae550c6d..744c811328fe 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_fulfillments.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_fulfillments.py @@ -63,6 +63,13 @@ from google.cloud.dialogflow_v2.types import fulfillment from google.cloud.dialogflow_v2.types import fulfillment as gcd_fulfillment +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -306,6 +313,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = FulfillmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = FulfillmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2414,10 +2464,13 @@ def test_get_fulfillment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FulfillmentsRestInterceptor, "post_get_fulfillment" ) as post, mock.patch.object( + transports.FulfillmentsRestInterceptor, "post_get_fulfillment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FulfillmentsRestInterceptor, "pre_get_fulfillment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = fulfillment.GetFulfillmentRequest.pb( fulfillment.GetFulfillmentRequest() ) @@ -2441,6 +2494,7 @@ def test_get_fulfillment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = fulfillment.Fulfillment() + post_with_metadata.return_value = fulfillment.Fulfillment(), metadata client.get_fulfillment( request, @@ -2452,6 +2506,7 @@ def test_get_fulfillment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_fulfillment_rest_bad_request( @@ -2620,10 +2675,13 @@ def test_update_fulfillment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FulfillmentsRestInterceptor, "post_update_fulfillment" ) as post, mock.patch.object( + transports.FulfillmentsRestInterceptor, "post_update_fulfillment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FulfillmentsRestInterceptor, "pre_update_fulfillment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_fulfillment.UpdateFulfillmentRequest.pb( gcd_fulfillment.UpdateFulfillmentRequest() ) @@ -2649,6 +2707,7 @@ def test_update_fulfillment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_fulfillment.Fulfillment() + post_with_metadata.return_value = gcd_fulfillment.Fulfillment(), metadata client.update_fulfillment( request, @@ -2660,6 +2719,7 @@ def test_update_fulfillment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generators.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generators.py index 68784c7734cf..04a862183c28 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generators.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_generators.py @@ -65,6 +65,13 @@ from google.cloud.dialogflow_v2.types import generator from google.cloud.dialogflow_v2.types import generator as gcd_generator +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -300,6 +307,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = GeneratorsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = GeneratorsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4429,10 +4479,13 @@ def test_create_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_create_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_create_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_create_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_generator.CreateGeneratorRequest.pb( gcd_generator.CreateGeneratorRequest() ) @@ -4456,6 +4509,7 @@ def test_create_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_generator.Generator() + post_with_metadata.return_value = gcd_generator.Generator(), metadata client.create_generator( request, @@ -4467,6 +4521,7 @@ def test_create_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_generator_rest_bad_request(request_type=generator.GetGeneratorRequest): @@ -4553,10 +4608,13 @@ def test_get_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_get_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_get_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_get_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = generator.GetGeneratorRequest.pb(generator.GetGeneratorRequest()) transcode.return_value = { "method": "post", @@ -4578,6 +4636,7 @@ def test_get_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generator.Generator() + post_with_metadata.return_value = generator.Generator(), metadata client.get_generator( request, @@ -4589,6 +4648,7 @@ def test_get_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_generators_rest_bad_request(request_type=generator.ListGeneratorsRequest): @@ -4671,10 +4731,13 @@ def test_list_generators_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_list_generators" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_list_generators_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_list_generators" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = generator.ListGeneratorsRequest.pb( generator.ListGeneratorsRequest() ) @@ -4700,6 +4763,7 @@ def test_list_generators_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generator.ListGeneratorsResponse() + post_with_metadata.return_value = generator.ListGeneratorsResponse(), metadata client.list_generators( request, @@ -4711,6 +4775,7 @@ def test_list_generators_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_generator_rest_bad_request( @@ -5022,10 +5087,13 @@ def test_update_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_update_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_update_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_update_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_generator.UpdateGeneratorRequest.pb( gcd_generator.UpdateGeneratorRequest() ) @@ -5049,6 +5117,7 @@ def test_update_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_generator.Generator() + post_with_metadata.return_value = gcd_generator.Generator(), metadata client.update_generator( request, @@ -5060,6 +5129,7 @@ def test_update_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_intents.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_intents.py index c48b0af2484d..ab6c061cfab8 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_intents.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_intents.py @@ -76,6 +76,13 @@ from google.cloud.dialogflow_v2.types import intent from google.cloud.dialogflow_v2.types import intent as gcd_intent +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -299,6 +306,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = IntentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = IntentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5757,10 +5807,13 @@ def test_list_intents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_list_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_list_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_list_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.ListIntentsRequest.pb(intent.ListIntentsRequest()) transcode.return_value = { "method": "post", @@ -5782,6 +5835,7 @@ def test_list_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = intent.ListIntentsResponse() + post_with_metadata.return_value = intent.ListIntentsResponse(), metadata client.list_intents( request, @@ -5793,6 +5847,7 @@ def test_list_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_intent_rest_bad_request(request_type=intent.GetIntentRequest): @@ -5903,10 +5958,13 @@ def test_get_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_get_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_get_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_get_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.GetIntentRequest.pb(intent.GetIntentRequest()) transcode.return_value = { "method": "post", @@ -5928,6 +5986,7 @@ def test_get_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = intent.Intent() + post_with_metadata.return_value = intent.Intent(), metadata client.get_intent( request, @@ -5939,6 +5998,7 @@ def test_get_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_intent_rest_bad_request(request_type=gcd_intent.CreateIntentRequest): @@ -6282,10 +6342,13 @@ def test_create_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_create_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_create_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_create_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_intent.CreateIntentRequest.pb(gcd_intent.CreateIntentRequest()) transcode.return_value = { "method": "post", @@ -6307,6 +6370,7 @@ def test_create_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_intent.Intent() + post_with_metadata.return_value = gcd_intent.Intent(), metadata client.create_intent( request, @@ -6318,6 +6382,7 @@ def test_create_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_intent_rest_bad_request(request_type=gcd_intent.UpdateIntentRequest): @@ -6661,10 +6726,13 @@ def test_update_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_update_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_update_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_update_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_intent.UpdateIntentRequest.pb(gcd_intent.UpdateIntentRequest()) transcode.return_value = { "method": "post", @@ -6686,6 +6754,7 @@ def test_update_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_intent.Intent() + post_with_metadata.return_value = gcd_intent.Intent(), metadata client.update_intent( request, @@ -6697,6 +6766,7 @@ def test_update_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_intent_rest_bad_request(request_type=intent.DeleteIntentRequest): @@ -6878,10 +6948,13 @@ def test_batch_update_intents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.IntentsRestInterceptor, "post_batch_update_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_batch_update_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_batch_update_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.BatchUpdateIntentsRequest.pb( intent.BatchUpdateIntentsRequest() ) @@ -6905,6 +6978,7 @@ def test_batch_update_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_update_intents( request, @@ -6916,6 +6990,7 @@ def test_batch_update_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_delete_intents_rest_bad_request( @@ -6994,10 +7069,13 @@ def test_batch_delete_intents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.IntentsRestInterceptor, "post_batch_delete_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_batch_delete_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_batch_delete_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.BatchDeleteIntentsRequest.pb( intent.BatchDeleteIntentsRequest() ) @@ -7021,6 +7099,7 @@ def test_batch_delete_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_delete_intents( request, @@ -7032,6 +7111,7 @@ def test_batch_delete_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_knowledge_bases.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_knowledge_bases.py index 22b2c7ff9475..98c4cb62ce3c 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_knowledge_bases.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_knowledge_bases.py @@ -64,6 +64,13 @@ from google.cloud.dialogflow_v2.types import knowledge_base as gcd_knowledge_base from google.cloud.dialogflow_v2.types import knowledge_base +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -322,6 +329,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = KnowledgeBasesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = KnowledgeBasesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4479,10 +4529,14 @@ def test_list_knowledge_bases_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "post_list_knowledge_bases" ) as post, mock.patch.object( + transports.KnowledgeBasesRestInterceptor, + "post_list_knowledge_bases_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "pre_list_knowledge_bases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = knowledge_base.ListKnowledgeBasesRequest.pb( knowledge_base.ListKnowledgeBasesRequest() ) @@ -4508,6 +4562,10 @@ def test_list_knowledge_bases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = knowledge_base.ListKnowledgeBasesResponse() + post_with_metadata.return_value = ( + knowledge_base.ListKnowledgeBasesResponse(), + metadata, + ) client.list_knowledge_bases( request, @@ -4519,6 +4577,7 @@ def test_list_knowledge_bases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_knowledge_base_rest_bad_request( @@ -4607,10 +4666,14 @@ def test_get_knowledge_base_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "post_get_knowledge_base" ) as post, mock.patch.object( + transports.KnowledgeBasesRestInterceptor, + "post_get_knowledge_base_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "pre_get_knowledge_base" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = knowledge_base.GetKnowledgeBaseRequest.pb( knowledge_base.GetKnowledgeBaseRequest() ) @@ -4636,6 +4699,7 @@ def test_get_knowledge_base_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = knowledge_base.KnowledgeBase() + post_with_metadata.return_value = knowledge_base.KnowledgeBase(), metadata client.get_knowledge_base( request, @@ -4647,6 +4711,7 @@ def test_get_knowledge_base_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_knowledge_base_rest_bad_request( @@ -4809,10 +4874,14 @@ def test_create_knowledge_base_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "post_create_knowledge_base" ) as post, mock.patch.object( + transports.KnowledgeBasesRestInterceptor, + "post_create_knowledge_base_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "pre_create_knowledge_base" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_knowledge_base.CreateKnowledgeBaseRequest.pb( gcd_knowledge_base.CreateKnowledgeBaseRequest() ) @@ -4838,6 +4907,7 @@ def test_create_knowledge_base_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_knowledge_base.KnowledgeBase() + post_with_metadata.return_value = gcd_knowledge_base.KnowledgeBase(), metadata client.create_knowledge_base( request, @@ -4849,6 +4919,7 @@ def test_create_knowledge_base_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_knowledge_base_rest_bad_request( @@ -5124,10 +5195,14 @@ def test_update_knowledge_base_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "post_update_knowledge_base" ) as post, mock.patch.object( + transports.KnowledgeBasesRestInterceptor, + "post_update_knowledge_base_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "pre_update_knowledge_base" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_knowledge_base.UpdateKnowledgeBaseRequest.pb( gcd_knowledge_base.UpdateKnowledgeBaseRequest() ) @@ -5153,6 +5228,7 @@ def test_update_knowledge_base_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_knowledge_base.KnowledgeBase() + post_with_metadata.return_value = gcd_knowledge_base.KnowledgeBase(), metadata client.update_knowledge_base( request, @@ -5164,6 +5240,7 @@ def test_update_knowledge_base_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_participants.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_participants.py index 182d10d6f569..5d04eb382a92 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_participants.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_participants.py @@ -68,6 +68,13 @@ from google.cloud.dialogflow_v2.types import participant as gcd_participant from google.cloud.dialogflow_v2.types import session, session_entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -311,6 +318,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ParticipantsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ParticipantsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6905,10 +6955,13 @@ def test_create_participant_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_create_participant" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_create_participant_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_create_participant" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_participant.CreateParticipantRequest.pb( gcd_participant.CreateParticipantRequest() ) @@ -6934,6 +6987,7 @@ def test_create_participant_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_participant.Participant() + post_with_metadata.return_value = gcd_participant.Participant(), metadata client.create_participant( request, @@ -6945,6 +6999,7 @@ def test_create_participant_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_participant_rest_bad_request( @@ -7039,10 +7094,13 @@ def test_get_participant_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_get_participant" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_get_participant_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_get_participant" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.GetParticipantRequest.pb( participant.GetParticipantRequest() ) @@ -7066,6 +7124,7 @@ def test_get_participant_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.Participant() + post_with_metadata.return_value = participant.Participant(), metadata client.get_participant( request, @@ -7077,6 +7136,7 @@ def test_get_participant_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_participants_rest_bad_request( @@ -7161,10 +7221,13 @@ def test_list_participants_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_list_participants" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_list_participants_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_list_participants" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.ListParticipantsRequest.pb( participant.ListParticipantsRequest() ) @@ -7190,6 +7253,10 @@ def test_list_participants_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.ListParticipantsResponse() + post_with_metadata.return_value = ( + participant.ListParticipantsResponse(), + metadata, + ) client.list_participants( request, @@ -7201,6 +7268,7 @@ def test_list_participants_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_participant_rest_bad_request( @@ -7373,10 +7441,13 @@ def test_update_participant_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_update_participant" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_update_participant_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_update_participant" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_participant.UpdateParticipantRequest.pb( gcd_participant.UpdateParticipantRequest() ) @@ -7402,6 +7473,7 @@ def test_update_participant_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_participant.Participant() + post_with_metadata.return_value = gcd_participant.Participant(), metadata client.update_participant( request, @@ -7413,6 +7485,7 @@ def test_update_participant_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_analyze_content_rest_bad_request( @@ -7501,10 +7574,13 @@ def test_analyze_content_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_analyze_content" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_analyze_content_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_analyze_content" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_participant.AnalyzeContentRequest.pb( gcd_participant.AnalyzeContentRequest() ) @@ -7530,6 +7606,10 @@ def test_analyze_content_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_participant.AnalyzeContentResponse() + post_with_metadata.return_value = ( + gcd_participant.AnalyzeContentResponse(), + metadata, + ) client.analyze_content( request, @@ -7541,6 +7621,7 @@ def test_analyze_content_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_streaming_analyze_content_rest_error(): @@ -7643,10 +7724,13 @@ def test_suggest_articles_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_suggest_articles" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_suggest_articles_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_suggest_articles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.SuggestArticlesRequest.pb( participant.SuggestArticlesRequest() ) @@ -7672,6 +7756,10 @@ def test_suggest_articles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.SuggestArticlesResponse() + post_with_metadata.return_value = ( + participant.SuggestArticlesResponse(), + metadata, + ) client.suggest_articles( request, @@ -7683,6 +7771,7 @@ def test_suggest_articles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_suggest_faq_answers_rest_bad_request( @@ -7773,10 +7862,13 @@ def test_suggest_faq_answers_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_suggest_faq_answers" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_suggest_faq_answers_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_suggest_faq_answers" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.SuggestFaqAnswersRequest.pb( participant.SuggestFaqAnswersRequest() ) @@ -7802,6 +7894,10 @@ def test_suggest_faq_answers_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.SuggestFaqAnswersResponse() + post_with_metadata.return_value = ( + participant.SuggestFaqAnswersResponse(), + metadata, + ) client.suggest_faq_answers( request, @@ -7813,6 +7909,7 @@ def test_suggest_faq_answers_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_suggest_smart_replies_rest_bad_request( @@ -7903,10 +8000,14 @@ def test_suggest_smart_replies_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_suggest_smart_replies" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, + "post_suggest_smart_replies_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_suggest_smart_replies" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.SuggestSmartRepliesRequest.pb( participant.SuggestSmartRepliesRequest() ) @@ -7932,6 +8033,10 @@ def test_suggest_smart_replies_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.SuggestSmartRepliesResponse() + post_with_metadata.return_value = ( + participant.SuggestSmartRepliesResponse(), + metadata, + ) client.suggest_smart_replies( request, @@ -7943,6 +8048,7 @@ def test_suggest_smart_replies_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_suggest_knowledge_assist_rest_bad_request( @@ -8033,10 +8139,14 @@ def test_suggest_knowledge_assist_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_suggest_knowledge_assist" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, + "post_suggest_knowledge_assist_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_suggest_knowledge_assist" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.SuggestKnowledgeAssistRequest.pb( participant.SuggestKnowledgeAssistRequest() ) @@ -8062,6 +8172,10 @@ def test_suggest_knowledge_assist_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.SuggestKnowledgeAssistResponse() + post_with_metadata.return_value = ( + participant.SuggestKnowledgeAssistResponse(), + metadata, + ) client.suggest_knowledge_assist( request, @@ -8073,6 +8187,7 @@ def test_suggest_knowledge_assist_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_session_entity_types.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_session_entity_types.py index e7f5d4f4c89b..c175daae464d 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_session_entity_types.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_session_entity_types.py @@ -67,6 +67,13 @@ from google.cloud.dialogflow_v2.types import entity_type from google.cloud.dialogflow_v2.types import session_entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -338,6 +345,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionEntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionEntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4579,10 +4629,14 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_list_session_entity_types" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_list_session_entity_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_list_session_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_entity_type.ListSessionEntityTypesRequest.pb( session_entity_type.ListSessionEntityTypesRequest() ) @@ -4608,6 +4662,10 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_entity_type.ListSessionEntityTypesResponse() + post_with_metadata.return_value = ( + session_entity_type.ListSessionEntityTypesResponse(), + metadata, + ) client.list_session_entity_types( request, @@ -4619,6 +4677,7 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_session_entity_type_rest_bad_request( @@ -4712,10 +4771,14 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_get_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_get_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_get_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_entity_type.GetSessionEntityTypeRequest.pb( session_entity_type.GetSessionEntityTypeRequest() ) @@ -4741,6 +4804,10 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + session_entity_type.SessionEntityType(), + metadata, + ) client.get_session_entity_type( request, @@ -4752,6 +4819,7 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_session_entity_type_rest_bad_request( @@ -4917,10 +4985,14 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_create_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_create_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_create_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_session_entity_type.CreateSessionEntityTypeRequest.pb( gcd_session_entity_type.CreateSessionEntityTypeRequest() ) @@ -4946,6 +5018,10 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + gcd_session_entity_type.SessionEntityType(), + metadata, + ) client.create_session_entity_type( request, @@ -4957,6 +5033,7 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_session_entity_type_rest_bad_request( @@ -5130,10 +5207,14 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_update_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_update_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_update_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_session_entity_type.UpdateSessionEntityTypeRequest.pb( gcd_session_entity_type.UpdateSessionEntityTypeRequest() ) @@ -5159,6 +5240,10 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + gcd_session_entity_type.SessionEntityType(), + metadata, + ) client.update_session_entity_type( request, @@ -5170,6 +5255,7 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_session_entity_type_rest_bad_request( diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_sessions.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_sessions.py index abe9ecdfd3a0..c8a4f8479d52 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_sessions.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_sessions.py @@ -68,6 +68,13 @@ from google.cloud.dialogflow_v2.types import session as gcd_session from google.cloud.dialogflow_v2.types import session_entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -298,6 +305,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2011,10 +2061,13 @@ def test_detect_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_detect_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_detect_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_detect_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_session.DetectIntentRequest.pb( gcd_session.DetectIntentRequest() ) @@ -2040,6 +2093,7 @@ def test_detect_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session.DetectIntentResponse() + post_with_metadata.return_value = gcd_session.DetectIntentResponse(), metadata client.detect_intent( request, @@ -2051,6 +2105,7 @@ def test_detect_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_streaming_detect_intent_rest_error(): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_versions.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_versions.py index ad52cbe58c78..eb40cff19f99 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_versions.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2/test_versions.py @@ -65,6 +65,13 @@ from google.cloud.dialogflow_v2.types import version from google.cloud.dialogflow_v2.types import version as gcd_version +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -295,6 +302,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = VersionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = VersionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4268,10 +4318,13 @@ def test_list_versions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_list_versions" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_list_versions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_list_versions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.ListVersionsRequest.pb(version.ListVersionsRequest()) transcode.return_value = { "method": "post", @@ -4295,6 +4348,7 @@ def test_list_versions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.ListVersionsResponse() + post_with_metadata.return_value = version.ListVersionsResponse(), metadata client.list_versions( request, @@ -4306,6 +4360,7 @@ def test_list_versions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_version_rest_bad_request(request_type=version.GetVersionRequest): @@ -4392,10 +4447,13 @@ def test_get_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_get_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_get_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_get_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.GetVersionRequest.pb(version.GetVersionRequest()) transcode.return_value = { "method": "post", @@ -4417,6 +4475,7 @@ def test_get_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.Version() + post_with_metadata.return_value = version.Version(), metadata client.get_version( request, @@ -4428,6 +4487,7 @@ def test_get_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_version_rest_bad_request(request_type=gcd_version.CreateVersionRequest): @@ -4588,10 +4648,13 @@ def test_create_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_create_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_create_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_create_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_version.CreateVersionRequest.pb( gcd_version.CreateVersionRequest() ) @@ -4615,6 +4678,7 @@ def test_create_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_version.Version() + post_with_metadata.return_value = gcd_version.Version(), metadata client.create_version( request, @@ -4626,6 +4690,7 @@ def test_create_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_version_rest_bad_request(request_type=gcd_version.UpdateVersionRequest): @@ -4786,10 +4851,13 @@ def test_update_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_update_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_update_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_update_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_version.UpdateVersionRequest.pb( gcd_version.UpdateVersionRequest() ) @@ -4813,6 +4881,7 @@ def test_update_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_version.Version() + post_with_metadata.return_value = gcd_version.Version(), metadata client.update_version( request, @@ -4824,6 +4893,7 @@ def test_update_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_version_rest_bad_request(request_type=version.DeleteVersionRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_agents.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_agents.py index 53f89bf61cbd..fa9ebd851f13 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_agents.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_agents.py @@ -76,6 +76,13 @@ from google.cloud.dialogflow_v2beta1.types import agent as gcd_agent from google.cloud.dialogflow_v2beta1.types import validation_result +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -298,6 +305,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AgentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AgentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6126,10 +6176,13 @@ def test_get_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_get_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetAgentRequest.pb(agent.GetAgentRequest()) transcode.return_value = { "method": "post", @@ -6151,6 +6204,7 @@ def test_get_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.Agent() + post_with_metadata.return_value = agent.Agent(), metadata client.get_agent( request, @@ -6162,6 +6216,7 @@ def test_get_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_set_agent_rest_bad_request(request_type=gcd_agent.SetAgentRequest): @@ -6350,10 +6405,13 @@ def test_set_agent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_set_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_set_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_set_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_agent.SetAgentRequest.pb(gcd_agent.SetAgentRequest()) transcode.return_value = { "method": "post", @@ -6375,6 +6433,7 @@ def test_set_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_agent.Agent() + post_with_metadata.return_value = gcd_agent.Agent(), metadata client.set_agent( request, @@ -6386,6 +6445,7 @@ def test_set_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_agent_rest_bad_request(request_type=agent.DeleteAgentRequest): @@ -6569,10 +6629,13 @@ def test_search_agents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_search_agents" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_search_agents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_search_agents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.SearchAgentsRequest.pb(agent.SearchAgentsRequest()) transcode.return_value = { "method": "post", @@ -6594,6 +6657,7 @@ def test_search_agents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = agent.SearchAgentsResponse() + post_with_metadata.return_value = agent.SearchAgentsResponse(), metadata client.search_agents( request, @@ -6605,6 +6669,7 @@ def test_search_agents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_train_agent_rest_bad_request(request_type=agent.TrainAgentRequest): @@ -6681,10 +6746,13 @@ def test_train_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_train_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_train_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_train_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.TrainAgentRequest.pb(agent.TrainAgentRequest()) transcode.return_value = { "method": "post", @@ -6706,6 +6774,7 @@ def test_train_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.train_agent( request, @@ -6717,6 +6786,7 @@ def test_train_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_agent_rest_bad_request(request_type=agent.ExportAgentRequest): @@ -6793,10 +6863,13 @@ def test_export_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_export_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_export_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_export_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ExportAgentRequest.pb(agent.ExportAgentRequest()) transcode.return_value = { "method": "post", @@ -6818,6 +6891,7 @@ def test_export_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_agent( request, @@ -6829,6 +6903,7 @@ def test_export_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_agent_rest_bad_request(request_type=agent.ImportAgentRequest): @@ -6905,10 +6980,13 @@ def test_import_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_import_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_import_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_import_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.ImportAgentRequest.pb(agent.ImportAgentRequest()) transcode.return_value = { "method": "post", @@ -6930,6 +7008,7 @@ def test_import_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_agent( request, @@ -6941,6 +7020,7 @@ def test_import_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_restore_agent_rest_bad_request(request_type=agent.RestoreAgentRequest): @@ -7017,10 +7097,13 @@ def test_restore_agent_rest_interceptors(null_interceptor): ), mock.patch.object( transports.AgentsRestInterceptor, "post_restore_agent" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_restore_agent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_restore_agent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.RestoreAgentRequest.pb(agent.RestoreAgentRequest()) transcode.return_value = { "method": "post", @@ -7042,6 +7125,7 @@ def test_restore_agent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.restore_agent( request, @@ -7053,6 +7137,7 @@ def test_restore_agent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_validation_result_rest_bad_request( @@ -7132,10 +7217,13 @@ def test_get_validation_result_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AgentsRestInterceptor, "post_get_validation_result" ) as post, mock.patch.object( + transports.AgentsRestInterceptor, "post_get_validation_result_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AgentsRestInterceptor, "pre_get_validation_result" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = agent.GetValidationResultRequest.pb( agent.GetValidationResultRequest() ) @@ -7161,6 +7249,7 @@ def test_get_validation_result_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = validation_result.ValidationResult() + post_with_metadata.return_value = validation_result.ValidationResult(), metadata client.get_validation_result( request, @@ -7172,6 +7261,7 @@ def test_get_validation_result_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_answer_records.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_answer_records.py index 361bc2e6d603..d324e2810216 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_answer_records.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_answer_records.py @@ -67,6 +67,13 @@ from google.cloud.dialogflow_v2beta1.types import answer_record as gcd_answer_record from google.cloud.dialogflow_v2beta1.types import answer_record +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -321,6 +328,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AnswerRecordsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AnswerRecordsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2961,10 +3011,13 @@ def test_get_answer_record_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AnswerRecordsRestInterceptor, "post_get_answer_record" ) as post, mock.patch.object( + transports.AnswerRecordsRestInterceptor, "post_get_answer_record_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AnswerRecordsRestInterceptor, "pre_get_answer_record" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = answer_record.GetAnswerRecordRequest.pb( answer_record.GetAnswerRecordRequest() ) @@ -2988,6 +3041,7 @@ def test_get_answer_record_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = answer_record.AnswerRecord() + post_with_metadata.return_value = answer_record.AnswerRecord(), metadata client.get_answer_record( request, @@ -2999,6 +3053,7 @@ def test_get_answer_record_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_answer_records_rest_bad_request( @@ -3083,10 +3138,14 @@ def test_list_answer_records_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AnswerRecordsRestInterceptor, "post_list_answer_records" ) as post, mock.patch.object( + transports.AnswerRecordsRestInterceptor, + "post_list_answer_records_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AnswerRecordsRestInterceptor, "pre_list_answer_records" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = answer_record.ListAnswerRecordsRequest.pb( answer_record.ListAnswerRecordsRequest() ) @@ -3112,6 +3171,10 @@ def test_list_answer_records_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = answer_record.ListAnswerRecordsResponse() + post_with_metadata.return_value = ( + answer_record.ListAnswerRecordsResponse(), + metadata, + ) client.list_answer_records( request, @@ -3123,6 +3186,7 @@ def test_list_answer_records_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_answer_record_rest_bad_request( @@ -3591,10 +3655,14 @@ def test_update_answer_record_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AnswerRecordsRestInterceptor, "post_update_answer_record" ) as post, mock.patch.object( + transports.AnswerRecordsRestInterceptor, + "post_update_answer_record_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AnswerRecordsRestInterceptor, "pre_update_answer_record" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_answer_record.UpdateAnswerRecordRequest.pb( gcd_answer_record.UpdateAnswerRecordRequest() ) @@ -3620,6 +3688,7 @@ def test_update_answer_record_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_answer_record.AnswerRecord() + post_with_metadata.return_value = gcd_answer_record.AnswerRecord(), metadata client.update_answer_record( request, @@ -3631,6 +3700,7 @@ def test_update_answer_record_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_contexts.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_contexts.py index 02852788f15c..9af8343f998e 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_contexts.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_contexts.py @@ -65,6 +65,13 @@ from google.cloud.dialogflow_v2beta1.types import context from google.cloud.dialogflow_v2beta1.types import context as gcd_context +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -295,6 +302,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ContextsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ContextsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4799,10 +4849,13 @@ def test_list_contexts_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ContextsRestInterceptor, "post_list_contexts" ) as post, mock.patch.object( + transports.ContextsRestInterceptor, "post_list_contexts_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ContextsRestInterceptor, "pre_list_contexts" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = context.ListContextsRequest.pb(context.ListContextsRequest()) transcode.return_value = { "method": "post", @@ -4826,6 +4879,7 @@ def test_list_contexts_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = context.ListContextsResponse() + post_with_metadata.return_value = context.ListContextsResponse(), metadata client.list_contexts( request, @@ -4837,6 +4891,7 @@ def test_list_contexts_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_context_rest_bad_request(request_type=context.GetContextRequest): @@ -4919,10 +4974,13 @@ def test_get_context_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ContextsRestInterceptor, "post_get_context" ) as post, mock.patch.object( + transports.ContextsRestInterceptor, "post_get_context_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ContextsRestInterceptor, "pre_get_context" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = context.GetContextRequest.pb(context.GetContextRequest()) transcode.return_value = { "method": "post", @@ -4944,6 +5002,7 @@ def test_get_context_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = context.Context() + post_with_metadata.return_value = context.Context(), metadata client.get_context( request, @@ -4955,6 +5014,7 @@ def test_get_context_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_context_rest_bad_request(request_type=gcd_context.CreateContextRequest): @@ -5109,10 +5169,13 @@ def test_create_context_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ContextsRestInterceptor, "post_create_context" ) as post, mock.patch.object( + transports.ContextsRestInterceptor, "post_create_context_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ContextsRestInterceptor, "pre_create_context" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_context.CreateContextRequest.pb( gcd_context.CreateContextRequest() ) @@ -5136,6 +5199,7 @@ def test_create_context_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_context.Context() + post_with_metadata.return_value = gcd_context.Context(), metadata client.create_context( request, @@ -5147,6 +5211,7 @@ def test_create_context_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_context_rest_bad_request(request_type=gcd_context.UpdateContextRequest): @@ -5305,10 +5370,13 @@ def test_update_context_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ContextsRestInterceptor, "post_update_context" ) as post, mock.patch.object( + transports.ContextsRestInterceptor, "post_update_context_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ContextsRestInterceptor, "pre_update_context" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_context.UpdateContextRequest.pb( gcd_context.UpdateContextRequest() ) @@ -5332,6 +5400,7 @@ def test_update_context_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_context.Context() + post_with_metadata.return_value = gcd_context.Context(), metadata client.update_context( request, @@ -5343,6 +5412,7 @@ def test_update_context_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_context_rest_bad_request(request_type=context.DeleteContextRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py index 3be5468b0291..b5c9d69273f4 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversation_profiles.py @@ -79,6 +79,13 @@ from google.cloud.dialogflow_v2beta1.types import conversation_profile from google.cloud.dialogflow_v2beta1.types import participant +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -352,6 +359,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationProfilesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationProfilesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5911,10 +5961,14 @@ def test_list_conversation_profiles_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_list_conversation_profiles", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_list_conversation_profiles_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_list_conversation_profiles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_profile.ListConversationProfilesRequest.pb( conversation_profile.ListConversationProfilesRequest() ) @@ -5940,6 +5994,10 @@ def test_list_conversation_profiles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_profile.ListConversationProfilesResponse() + post_with_metadata.return_value = ( + conversation_profile.ListConversationProfilesResponse(), + metadata, + ) client.list_conversation_profiles( request, @@ -5951,6 +6009,7 @@ def test_list_conversation_profiles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_profile_rest_bad_request( @@ -6043,10 +6102,14 @@ def test_get_conversation_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationProfilesRestInterceptor, "post_get_conversation_profile" ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_get_conversation_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_get_conversation_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation_profile.GetConversationProfileRequest.pb( conversation_profile.GetConversationProfileRequest() ) @@ -6072,6 +6135,10 @@ def test_get_conversation_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation_profile.ConversationProfile() + post_with_metadata.return_value = ( + conversation_profile.ConversationProfile(), + metadata, + ) client.get_conversation_profile( request, @@ -6083,6 +6150,7 @@ def test_get_conversation_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_conversation_profile_rest_bad_request( @@ -6349,11 +6417,15 @@ def test_create_conversation_profile_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_create_conversation_profile", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_create_conversation_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_create_conversation_profile", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_profile.CreateConversationProfileRequest.pb( gcd_conversation_profile.CreateConversationProfileRequest() ) @@ -6379,6 +6451,10 @@ def test_create_conversation_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation_profile.ConversationProfile() + post_with_metadata.return_value = ( + gcd_conversation_profile.ConversationProfile(), + metadata, + ) client.create_conversation_profile( request, @@ -6390,6 +6466,7 @@ def test_create_conversation_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_conversation_profile_rest_bad_request( @@ -6664,11 +6741,15 @@ def test_update_conversation_profile_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_update_conversation_profile", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_update_conversation_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_update_conversation_profile", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_profile.UpdateConversationProfileRequest.pb( gcd_conversation_profile.UpdateConversationProfileRequest() ) @@ -6694,6 +6775,10 @@ def test_update_conversation_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation_profile.ConversationProfile() + post_with_metadata.return_value = ( + gcd_conversation_profile.ConversationProfile(), + metadata, + ) client.update_conversation_profile( request, @@ -6705,6 +6790,7 @@ def test_update_conversation_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_conversation_profile_rest_bad_request( @@ -6900,11 +6986,15 @@ def test_set_suggestion_feature_config_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_set_suggestion_feature_config", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_set_suggestion_feature_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_set_suggestion_feature_config", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_profile.SetSuggestionFeatureConfigRequest.pb( gcd_conversation_profile.SetSuggestionFeatureConfigRequest() ) @@ -6928,6 +7018,7 @@ def test_set_suggestion_feature_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.set_suggestion_feature_config( request, @@ -6939,6 +7030,7 @@ def test_set_suggestion_feature_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_clear_suggestion_feature_config_rest_bad_request( @@ -7024,11 +7116,15 @@ def test_clear_suggestion_feature_config_rest_interceptors(null_interceptor): transports.ConversationProfilesRestInterceptor, "post_clear_suggestion_feature_config", ) as post, mock.patch.object( + transports.ConversationProfilesRestInterceptor, + "post_clear_suggestion_feature_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationProfilesRestInterceptor, "pre_clear_suggestion_feature_config", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation_profile.ClearSuggestionFeatureConfigRequest.pb( gcd_conversation_profile.ClearSuggestionFeatureConfigRequest() ) @@ -7052,6 +7148,7 @@ def test_clear_suggestion_feature_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.clear_suggestion_feature_config( request, @@ -7063,6 +7160,7 @@ def test_clear_suggestion_feature_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py index ca787759610e..47751fb815b6 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_conversations.py @@ -73,6 +73,13 @@ from google.cloud.dialogflow_v2beta1.types import audio_config from google.cloud.dialogflow_v2beta1.types import conversation +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -327,6 +334,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7361,10 +7411,14 @@ def test_create_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_create_conversation" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_create_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_create_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation.CreateConversationRequest.pb( gcd_conversation.CreateConversationRequest() ) @@ -7390,6 +7444,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.Conversation() + post_with_metadata.return_value = gcd_conversation.Conversation(), metadata client.create_conversation( request, @@ -7401,6 +7456,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_conversations_rest_bad_request( @@ -7485,10 +7541,13 @@ def test_list_conversations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_list_conversations" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, "post_list_conversations_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_list_conversations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.ListConversationsRequest.pb( conversation.ListConversationsRequest() ) @@ -7514,6 +7573,10 @@ def test_list_conversations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.ListConversationsResponse() + post_with_metadata.return_value = ( + conversation.ListConversationsResponse(), + metadata, + ) client.list_conversations( request, @@ -7525,6 +7588,7 @@ def test_list_conversations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_rest_bad_request( @@ -7620,10 +7684,13 @@ def test_get_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_get_conversation" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, "post_get_conversation_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_get_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.GetConversationRequest.pb( conversation.GetConversationRequest() ) @@ -7647,6 +7714,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.Conversation() + post_with_metadata.return_value = conversation.Conversation(), metadata client.get_conversation( request, @@ -7658,6 +7726,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_complete_conversation_rest_bad_request( @@ -7753,10 +7822,14 @@ def test_complete_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_complete_conversation" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_complete_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_complete_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.CompleteConversationRequest.pb( conversation.CompleteConversationRequest() ) @@ -7780,6 +7853,7 @@ def test_complete_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.Conversation() + post_with_metadata.return_value = conversation.Conversation(), metadata client.complete_conversation( request, @@ -7791,6 +7865,7 @@ def test_complete_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_create_messages_rest_bad_request( @@ -7872,10 +7947,14 @@ def test_batch_create_messages_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_batch_create_messages" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_batch_create_messages_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_batch_create_messages" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.BatchCreateMessagesRequest.pb( conversation.BatchCreateMessagesRequest() ) @@ -7901,6 +7980,10 @@ def test_batch_create_messages_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.BatchCreateMessagesResponse() + post_with_metadata.return_value = ( + conversation.BatchCreateMessagesResponse(), + metadata, + ) client.batch_create_messages( request, @@ -7912,6 +7995,7 @@ def test_batch_create_messages_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_messages_rest_bad_request(request_type=conversation.ListMessagesRequest): @@ -7994,10 +8078,13 @@ def test_list_messages_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_list_messages" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, "post_list_messages_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_list_messages" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.ListMessagesRequest.pb( conversation.ListMessagesRequest() ) @@ -8023,6 +8110,7 @@ def test_list_messages_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.ListMessagesResponse() + post_with_metadata.return_value = conversation.ListMessagesResponse(), metadata client.list_messages( request, @@ -8034,6 +8122,7 @@ def test_list_messages_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_suggest_conversation_summary_rest_bad_request( @@ -8122,10 +8211,14 @@ def test_suggest_conversation_summary_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_suggest_conversation_summary" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_suggest_conversation_summary_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_suggest_conversation_summary" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_conversation.SuggestConversationSummaryRequest.pb( gcd_conversation.SuggestConversationSummaryRequest() ) @@ -8151,6 +8244,10 @@ def test_suggest_conversation_summary_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.SuggestConversationSummaryResponse() + post_with_metadata.return_value = ( + gcd_conversation.SuggestConversationSummaryResponse(), + metadata, + ) client.suggest_conversation_summary( request, @@ -8162,6 +8259,7 @@ def test_suggest_conversation_summary_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_generate_stateless_summary_rest_bad_request( @@ -8248,10 +8346,14 @@ def test_generate_stateless_summary_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_generate_stateless_summary" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_generate_stateless_summary_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_generate_stateless_summary" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.GenerateStatelessSummaryRequest.pb( conversation.GenerateStatelessSummaryRequest() ) @@ -8277,6 +8379,10 @@ def test_generate_stateless_summary_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.GenerateStatelessSummaryResponse() + post_with_metadata.return_value = ( + conversation.GenerateStatelessSummaryResponse(), + metadata, + ) client.generate_stateless_summary( request, @@ -8288,6 +8394,7 @@ def test_generate_stateless_summary_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_generate_stateless_suggestion_rest_bad_request( @@ -8369,10 +8476,14 @@ def test_generate_stateless_suggestion_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_generate_stateless_suggestion" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, + "post_generate_stateless_suggestion_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_generate_stateless_suggestion" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.GenerateStatelessSuggestionRequest.pb( conversation.GenerateStatelessSuggestionRequest() ) @@ -8398,6 +8509,10 @@ def test_generate_stateless_suggestion_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.GenerateStatelessSuggestionResponse() + post_with_metadata.return_value = ( + conversation.GenerateStatelessSuggestionResponse(), + metadata, + ) client.generate_stateless_suggestion( request, @@ -8409,6 +8524,7 @@ def test_generate_stateless_suggestion_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_search_knowledge_rest_bad_request( @@ -8493,10 +8609,13 @@ def test_search_knowledge_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationsRestInterceptor, "post_search_knowledge" ) as post, mock.patch.object( + transports.ConversationsRestInterceptor, "post_search_knowledge_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ConversationsRestInterceptor, "pre_search_knowledge" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversation.SearchKnowledgeRequest.pb( conversation.SearchKnowledgeRequest() ) @@ -8522,6 +8641,10 @@ def test_search_knowledge_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.SearchKnowledgeResponse() + post_with_metadata.return_value = ( + conversation.SearchKnowledgeResponse(), + metadata, + ) client.search_knowledge( request, @@ -8533,6 +8656,7 @@ def test_search_knowledge_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_documents.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_documents.py index 7e78424a9571..5552bc95547c 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_documents.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_documents.py @@ -78,6 +78,13 @@ from google.cloud.dialogflow_v2beta1.types import document as gcd_document from google.cloud.dialogflow_v2beta1.types import gcs +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -311,6 +318,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DocumentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DocumentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5307,10 +5357,13 @@ def test_list_documents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentsRestInterceptor, "post_list_documents" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_list_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_list_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.ListDocumentsRequest.pb(document.ListDocumentsRequest()) transcode.return_value = { "method": "post", @@ -5334,6 +5387,7 @@ def test_list_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document.ListDocumentsResponse() + post_with_metadata.return_value = document.ListDocumentsResponse(), metadata client.list_documents( request, @@ -5345,6 +5399,7 @@ def test_list_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_document_rest_bad_request(request_type=document.GetDocumentRequest): @@ -5436,10 +5491,13 @@ def test_get_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentsRestInterceptor, "post_get_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_get_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_get_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.GetDocumentRequest.pb(document.GetDocumentRequest()) transcode.return_value = { "method": "post", @@ -5461,6 +5519,7 @@ def test_get_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document.Document() + post_with_metadata.return_value = document.Document(), metadata client.get_document( request, @@ -5472,6 +5531,7 @@ def test_get_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_document_rest_bad_request( @@ -5642,10 +5702,13 @@ def test_create_document_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_create_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_create_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_create_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_document.CreateDocumentRequest.pb( gcd_document.CreateDocumentRequest() ) @@ -5669,6 +5732,7 @@ def test_create_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_document( request, @@ -5680,6 +5744,7 @@ def test_create_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_documents_rest_bad_request( @@ -5758,10 +5823,13 @@ def test_import_documents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_import_documents" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_import_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_import_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.ImportDocumentsRequest.pb( document.ImportDocumentsRequest() ) @@ -5785,6 +5853,7 @@ def test_import_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_documents( request, @@ -5796,6 +5865,7 @@ def test_import_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_document_rest_bad_request(request_type=document.DeleteDocumentRequest): @@ -5872,10 +5942,13 @@ def test_delete_document_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_delete_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_delete_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_delete_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.DeleteDocumentRequest.pb(document.DeleteDocumentRequest()) transcode.return_value = { "method": "post", @@ -5897,6 +5970,7 @@ def test_delete_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_document( request, @@ -5908,6 +5982,7 @@ def test_delete_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_document_rest_bad_request( @@ -6086,10 +6161,13 @@ def test_update_document_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_update_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_update_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_update_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_document.UpdateDocumentRequest.pb( gcd_document.UpdateDocumentRequest() ) @@ -6113,6 +6191,7 @@ def test_update_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_document( request, @@ -6124,6 +6203,7 @@ def test_update_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_reload_document_rest_bad_request(request_type=document.ReloadDocumentRequest): @@ -6200,10 +6280,13 @@ def test_reload_document_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentsRestInterceptor, "post_reload_document" ) as post, mock.patch.object( + transports.DocumentsRestInterceptor, "post_reload_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentsRestInterceptor, "pre_reload_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document.ReloadDocumentRequest.pb(document.ReloadDocumentRequest()) transcode.return_value = { "method": "post", @@ -6225,6 +6308,7 @@ def test_reload_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.reload_document( request, @@ -6236,6 +6320,7 @@ def test_reload_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_encryption_spec_service.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_encryption_spec_service.py index 126c4db5804a..7787b74656bb 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_encryption_spec_service.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_encryption_spec_service.py @@ -71,6 +71,13 @@ from google.cloud.dialogflow_v2beta1.types import encryption_spec as gcd_encryption_spec from google.cloud.dialogflow_v2beta1.types import encryption_spec +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -346,6 +353,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EncryptionSpecServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EncryptionSpecServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2503,10 +2553,14 @@ def test_get_encryption_spec_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EncryptionSpecServiceRestInterceptor, "post_get_encryption_spec" ) as post, mock.patch.object( + transports.EncryptionSpecServiceRestInterceptor, + "post_get_encryption_spec_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EncryptionSpecServiceRestInterceptor, "pre_get_encryption_spec" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = encryption_spec.GetEncryptionSpecRequest.pb( encryption_spec.GetEncryptionSpecRequest() ) @@ -2532,6 +2586,7 @@ def test_get_encryption_spec_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = encryption_spec.EncryptionSpec() + post_with_metadata.return_value = encryption_spec.EncryptionSpec(), metadata client.get_encryption_spec( request, @@ -2543,6 +2598,7 @@ def test_get_encryption_spec_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_encryption_spec_rest_bad_request( @@ -2628,11 +2684,15 @@ def test_initialize_encryption_spec_rest_interceptors(null_interceptor): transports.EncryptionSpecServiceRestInterceptor, "post_initialize_encryption_spec", ) as post, mock.patch.object( + transports.EncryptionSpecServiceRestInterceptor, + "post_initialize_encryption_spec_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EncryptionSpecServiceRestInterceptor, "pre_initialize_encryption_spec", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_encryption_spec.InitializeEncryptionSpecRequest.pb( gcd_encryption_spec.InitializeEncryptionSpecRequest() ) @@ -2656,6 +2716,7 @@ def test_initialize_encryption_spec_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.initialize_encryption_spec( request, @@ -2667,6 +2728,7 @@ def test_initialize_encryption_spec_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_entity_types.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_entity_types.py index 09275e12c7e1..cded7d537d63 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_entity_types.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_entity_types.py @@ -75,6 +75,13 @@ from google.cloud.dialogflow_v2beta1.types import entity_type as gcd_entity_type from google.cloud.dialogflow_v2beta1.types import entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -314,6 +321,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7427,10 +7477,13 @@ def test_list_entity_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_list_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_list_entity_types_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_list_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.ListEntityTypesRequest.pb( entity_type.ListEntityTypesRequest() ) @@ -7456,6 +7509,10 @@ def test_list_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = entity_type.ListEntityTypesResponse() + post_with_metadata.return_value = ( + entity_type.ListEntityTypesResponse(), + metadata, + ) client.list_entity_types( request, @@ -7467,6 +7524,7 @@ def test_list_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_entity_type_rest_bad_request( @@ -7562,10 +7620,13 @@ def test_get_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_get_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_get_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_get_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.GetEntityTypeRequest.pb( entity_type.GetEntityTypeRequest() ) @@ -7589,6 +7650,7 @@ def test_get_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = entity_type.EntityType() + post_with_metadata.return_value = entity_type.EntityType(), metadata client.get_entity_type( request, @@ -7600,6 +7662,7 @@ def test_get_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_entity_type_rest_bad_request( @@ -7772,10 +7835,13 @@ def test_create_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_create_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_create_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_create_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_entity_type.CreateEntityTypeRequest.pb( gcd_entity_type.CreateEntityTypeRequest() ) @@ -7799,6 +7865,7 @@ def test_create_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_entity_type.EntityType() + post_with_metadata.return_value = gcd_entity_type.EntityType(), metadata client.create_entity_type( request, @@ -7810,6 +7877,7 @@ def test_create_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_entity_type_rest_bad_request( @@ -7986,10 +8054,13 @@ def test_update_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EntityTypesRestInterceptor, "post_update_entity_type" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, "post_update_entity_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_update_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_entity_type.UpdateEntityTypeRequest.pb( gcd_entity_type.UpdateEntityTypeRequest() ) @@ -8013,6 +8084,7 @@ def test_update_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_entity_type.EntityType() + post_with_metadata.return_value = gcd_entity_type.EntityType(), metadata client.update_entity_type( request, @@ -8024,6 +8096,7 @@ def test_update_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_entity_type_rest_bad_request( @@ -8213,10 +8286,14 @@ def test_batch_update_entity_types_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_update_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_update_entity_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_update_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchUpdateEntityTypesRequest.pb( entity_type.BatchUpdateEntityTypesRequest() ) @@ -8240,6 +8317,7 @@ def test_batch_update_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_update_entity_types( request, @@ -8251,6 +8329,7 @@ def test_batch_update_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_delete_entity_types_rest_bad_request( @@ -8331,10 +8410,14 @@ def test_batch_delete_entity_types_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_delete_entity_types" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_delete_entity_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_delete_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchDeleteEntityTypesRequest.pb( entity_type.BatchDeleteEntityTypesRequest() ) @@ -8358,6 +8441,7 @@ def test_batch_delete_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_delete_entity_types( request, @@ -8369,6 +8453,7 @@ def test_batch_delete_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_create_entities_rest_bad_request( @@ -8449,10 +8534,14 @@ def test_batch_create_entities_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_create_entities" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_create_entities_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_create_entities" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchCreateEntitiesRequest.pb( entity_type.BatchCreateEntitiesRequest() ) @@ -8476,6 +8565,7 @@ def test_batch_create_entities_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_create_entities( request, @@ -8487,6 +8577,7 @@ def test_batch_create_entities_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_update_entities_rest_bad_request( @@ -8567,10 +8658,14 @@ def test_batch_update_entities_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_update_entities" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_update_entities_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_update_entities" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchUpdateEntitiesRequest.pb( entity_type.BatchUpdateEntitiesRequest() ) @@ -8594,6 +8689,7 @@ def test_batch_update_entities_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_update_entities( request, @@ -8605,6 +8701,7 @@ def test_batch_update_entities_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_delete_entities_rest_bad_request( @@ -8685,10 +8782,14 @@ def test_batch_delete_entities_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EntityTypesRestInterceptor, "post_batch_delete_entities" ) as post, mock.patch.object( + transports.EntityTypesRestInterceptor, + "post_batch_delete_entities_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EntityTypesRestInterceptor, "pre_batch_delete_entities" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = entity_type.BatchDeleteEntitiesRequest.pb( entity_type.BatchDeleteEntitiesRequest() ) @@ -8712,6 +8813,7 @@ def test_batch_delete_entities_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_delete_entities( request, @@ -8723,6 +8825,7 @@ def test_batch_delete_entities_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_environments.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_environments.py index 9ef7d59406e8..305987656d2e 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_environments.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_environments.py @@ -64,6 +64,13 @@ ) from google.cloud.dialogflow_v2beta1.types import audio_config, environment, fulfillment +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -307,6 +314,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EnvironmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EnvironmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4596,10 +4646,13 @@ def test_list_environments_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_list_environments" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_list_environments_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_list_environments" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.ListEnvironmentsRequest.pb( environment.ListEnvironmentsRequest() ) @@ -4625,6 +4678,10 @@ def test_list_environments_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.ListEnvironmentsResponse() + post_with_metadata.return_value = ( + environment.ListEnvironmentsResponse(), + metadata, + ) client.list_environments( request, @@ -4636,6 +4693,7 @@ def test_list_environments_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_environment_rest_bad_request( @@ -4726,10 +4784,13 @@ def test_get_environment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_get_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_get_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_get_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.GetEnvironmentRequest.pb( environment.GetEnvironmentRequest() ) @@ -4753,6 +4814,7 @@ def test_get_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.Environment() + post_with_metadata.return_value = environment.Environment(), metadata client.get_environment( request, @@ -4764,6 +4826,7 @@ def test_get_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_environment_rest_bad_request( @@ -4947,10 +5010,13 @@ def test_create_environment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_create_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_create_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_create_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.CreateEnvironmentRequest.pb( environment.CreateEnvironmentRequest() ) @@ -4974,6 +5040,7 @@ def test_create_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.Environment() + post_with_metadata.return_value = environment.Environment(), metadata client.create_environment( request, @@ -4985,6 +5052,7 @@ def test_create_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_environment_rest_bad_request( @@ -5172,10 +5240,13 @@ def test_update_environment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_update_environment" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, "post_update_environment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_update_environment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.UpdateEnvironmentRequest.pb( environment.UpdateEnvironmentRequest() ) @@ -5199,6 +5270,7 @@ def test_update_environment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.Environment() + post_with_metadata.return_value = environment.Environment(), metadata client.update_environment( request, @@ -5210,6 +5282,7 @@ def test_update_environment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_environment_rest_bad_request( @@ -5405,10 +5478,14 @@ def test_get_environment_history_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnvironmentsRestInterceptor, "post_get_environment_history" ) as post, mock.patch.object( + transports.EnvironmentsRestInterceptor, + "post_get_environment_history_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnvironmentsRestInterceptor, "pre_get_environment_history" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = environment.GetEnvironmentHistoryRequest.pb( environment.GetEnvironmentHistoryRequest() ) @@ -5434,6 +5511,7 @@ def test_get_environment_history_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = environment.EnvironmentHistory() + post_with_metadata.return_value = environment.EnvironmentHistory(), metadata client.get_environment_history( request, @@ -5445,6 +5523,7 @@ def test_get_environment_history_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_fulfillments.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_fulfillments.py index ca767709f12f..85e3c7a739cb 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_fulfillments.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_fulfillments.py @@ -63,6 +63,13 @@ from google.cloud.dialogflow_v2beta1.types import fulfillment as gcd_fulfillment from google.cloud.dialogflow_v2beta1.types import fulfillment +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -306,6 +313,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = FulfillmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = FulfillmentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2414,10 +2464,13 @@ def test_get_fulfillment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FulfillmentsRestInterceptor, "post_get_fulfillment" ) as post, mock.patch.object( + transports.FulfillmentsRestInterceptor, "post_get_fulfillment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FulfillmentsRestInterceptor, "pre_get_fulfillment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = fulfillment.GetFulfillmentRequest.pb( fulfillment.GetFulfillmentRequest() ) @@ -2441,6 +2494,7 @@ def test_get_fulfillment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = fulfillment.Fulfillment() + post_with_metadata.return_value = fulfillment.Fulfillment(), metadata client.get_fulfillment( request, @@ -2452,6 +2506,7 @@ def test_get_fulfillment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_fulfillment_rest_bad_request( @@ -2620,10 +2675,13 @@ def test_update_fulfillment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.FulfillmentsRestInterceptor, "post_update_fulfillment" ) as post, mock.patch.object( + transports.FulfillmentsRestInterceptor, "post_update_fulfillment_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.FulfillmentsRestInterceptor, "pre_update_fulfillment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_fulfillment.UpdateFulfillmentRequest.pb( gcd_fulfillment.UpdateFulfillmentRequest() ) @@ -2649,6 +2707,7 @@ def test_update_fulfillment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_fulfillment.Fulfillment() + post_with_metadata.return_value = gcd_fulfillment.Fulfillment(), metadata client.update_fulfillment( request, @@ -2660,6 +2719,7 @@ def test_update_fulfillment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py index bb6f49b7303b..0ab7e7dd2f36 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_generators.py @@ -65,6 +65,13 @@ from google.cloud.dialogflow_v2beta1.types import generator from google.cloud.dialogflow_v2beta1.types import generator as gcd_generator +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -300,6 +307,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = GeneratorsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = GeneratorsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4433,10 +4483,13 @@ def test_create_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_create_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_create_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_create_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_generator.CreateGeneratorRequest.pb( gcd_generator.CreateGeneratorRequest() ) @@ -4460,6 +4513,7 @@ def test_create_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_generator.Generator() + post_with_metadata.return_value = gcd_generator.Generator(), metadata client.create_generator( request, @@ -4471,6 +4525,7 @@ def test_create_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_generator_rest_bad_request(request_type=generator.GetGeneratorRequest): @@ -4557,10 +4612,13 @@ def test_get_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_get_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_get_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_get_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = generator.GetGeneratorRequest.pb(generator.GetGeneratorRequest()) transcode.return_value = { "method": "post", @@ -4582,6 +4640,7 @@ def test_get_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generator.Generator() + post_with_metadata.return_value = generator.Generator(), metadata client.get_generator( request, @@ -4593,6 +4652,7 @@ def test_get_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_generators_rest_bad_request(request_type=generator.ListGeneratorsRequest): @@ -4675,10 +4735,13 @@ def test_list_generators_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_list_generators" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_list_generators_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_list_generators" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = generator.ListGeneratorsRequest.pb( generator.ListGeneratorsRequest() ) @@ -4704,6 +4767,7 @@ def test_list_generators_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = generator.ListGeneratorsResponse() + post_with_metadata.return_value = generator.ListGeneratorsResponse(), metadata client.list_generators( request, @@ -4715,6 +4779,7 @@ def test_list_generators_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_generator_rest_bad_request( @@ -5026,10 +5091,13 @@ def test_update_generator_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GeneratorsRestInterceptor, "post_update_generator" ) as post, mock.patch.object( + transports.GeneratorsRestInterceptor, "post_update_generator_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.GeneratorsRestInterceptor, "pre_update_generator" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_generator.UpdateGeneratorRequest.pb( gcd_generator.UpdateGeneratorRequest() ) @@ -5053,6 +5121,7 @@ def test_update_generator_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_generator.Generator() + post_with_metadata.return_value = gcd_generator.Generator(), metadata client.update_generator( request, @@ -5064,6 +5133,7 @@ def test_update_generator_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_intents.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_intents.py index 2f51458f28ea..877a0b69bb1f 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_intents.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_intents.py @@ -76,6 +76,13 @@ from google.cloud.dialogflow_v2beta1.types import intent from google.cloud.dialogflow_v2beta1.types import intent as gcd_intent +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -299,6 +306,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = IntentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = IntentsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5777,10 +5827,13 @@ def test_list_intents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_list_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_list_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_list_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.ListIntentsRequest.pb(intent.ListIntentsRequest()) transcode.return_value = { "method": "post", @@ -5802,6 +5855,7 @@ def test_list_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = intent.ListIntentsResponse() + post_with_metadata.return_value = intent.ListIntentsResponse(), metadata client.list_intents( request, @@ -5813,6 +5867,7 @@ def test_list_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_intent_rest_bad_request(request_type=intent.GetIntentRequest): @@ -5925,10 +5980,13 @@ def test_get_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_get_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_get_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_get_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.GetIntentRequest.pb(intent.GetIntentRequest()) transcode.return_value = { "method": "post", @@ -5950,6 +6008,7 @@ def test_get_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = intent.Intent() + post_with_metadata.return_value = intent.Intent(), metadata client.get_intent( request, @@ -5961,6 +6020,7 @@ def test_get_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_intent_rest_bad_request(request_type=gcd_intent.CreateIntentRequest): @@ -6346,10 +6406,13 @@ def test_create_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_create_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_create_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_create_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_intent.CreateIntentRequest.pb(gcd_intent.CreateIntentRequest()) transcode.return_value = { "method": "post", @@ -6371,6 +6434,7 @@ def test_create_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_intent.Intent() + post_with_metadata.return_value = gcd_intent.Intent(), metadata client.create_intent( request, @@ -6382,6 +6446,7 @@ def test_create_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_intent_rest_bad_request(request_type=gcd_intent.UpdateIntentRequest): @@ -6767,10 +6832,13 @@ def test_update_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.IntentsRestInterceptor, "post_update_intent" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_update_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_update_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_intent.UpdateIntentRequest.pb(gcd_intent.UpdateIntentRequest()) transcode.return_value = { "method": "post", @@ -6792,6 +6860,7 @@ def test_update_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_intent.Intent() + post_with_metadata.return_value = gcd_intent.Intent(), metadata client.update_intent( request, @@ -6803,6 +6872,7 @@ def test_update_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_intent_rest_bad_request(request_type=intent.DeleteIntentRequest): @@ -6984,10 +7054,13 @@ def test_batch_update_intents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.IntentsRestInterceptor, "post_batch_update_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_batch_update_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_batch_update_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.BatchUpdateIntentsRequest.pb( intent.BatchUpdateIntentsRequest() ) @@ -7011,6 +7084,7 @@ def test_batch_update_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_update_intents( request, @@ -7022,6 +7096,7 @@ def test_batch_update_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_delete_intents_rest_bad_request( @@ -7100,10 +7175,13 @@ def test_batch_delete_intents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.IntentsRestInterceptor, "post_batch_delete_intents" ) as post, mock.patch.object( + transports.IntentsRestInterceptor, "post_batch_delete_intents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.IntentsRestInterceptor, "pre_batch_delete_intents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = intent.BatchDeleteIntentsRequest.pb( intent.BatchDeleteIntentsRequest() ) @@ -7127,6 +7205,7 @@ def test_batch_delete_intents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_delete_intents( request, @@ -7138,6 +7217,7 @@ def test_batch_delete_intents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_knowledge_bases.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_knowledge_bases.py index 1c756113b71e..52096cf2ec0c 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_knowledge_bases.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_knowledge_bases.py @@ -64,6 +64,13 @@ from google.cloud.dialogflow_v2beta1.types import knowledge_base as gcd_knowledge_base from google.cloud.dialogflow_v2beta1.types import knowledge_base +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -322,6 +329,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = KnowledgeBasesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = KnowledgeBasesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4483,10 +4533,14 @@ def test_list_knowledge_bases_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "post_list_knowledge_bases" ) as post, mock.patch.object( + transports.KnowledgeBasesRestInterceptor, + "post_list_knowledge_bases_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "pre_list_knowledge_bases" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = knowledge_base.ListKnowledgeBasesRequest.pb( knowledge_base.ListKnowledgeBasesRequest() ) @@ -4512,6 +4566,10 @@ def test_list_knowledge_bases_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = knowledge_base.ListKnowledgeBasesResponse() + post_with_metadata.return_value = ( + knowledge_base.ListKnowledgeBasesResponse(), + metadata, + ) client.list_knowledge_bases( request, @@ -4523,6 +4581,7 @@ def test_list_knowledge_bases_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_knowledge_base_rest_bad_request( @@ -4611,10 +4670,14 @@ def test_get_knowledge_base_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "post_get_knowledge_base" ) as post, mock.patch.object( + transports.KnowledgeBasesRestInterceptor, + "post_get_knowledge_base_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "pre_get_knowledge_base" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = knowledge_base.GetKnowledgeBaseRequest.pb( knowledge_base.GetKnowledgeBaseRequest() ) @@ -4640,6 +4703,7 @@ def test_get_knowledge_base_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = knowledge_base.KnowledgeBase() + post_with_metadata.return_value = knowledge_base.KnowledgeBase(), metadata client.get_knowledge_base( request, @@ -4651,6 +4715,7 @@ def test_get_knowledge_base_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_knowledge_base_rest_bad_request( @@ -4813,10 +4878,14 @@ def test_create_knowledge_base_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "post_create_knowledge_base" ) as post, mock.patch.object( + transports.KnowledgeBasesRestInterceptor, + "post_create_knowledge_base_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "pre_create_knowledge_base" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_knowledge_base.CreateKnowledgeBaseRequest.pb( gcd_knowledge_base.CreateKnowledgeBaseRequest() ) @@ -4842,6 +4911,7 @@ def test_create_knowledge_base_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_knowledge_base.KnowledgeBase() + post_with_metadata.return_value = gcd_knowledge_base.KnowledgeBase(), metadata client.create_knowledge_base( request, @@ -4853,6 +4923,7 @@ def test_create_knowledge_base_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_knowledge_base_rest_bad_request( @@ -5128,10 +5199,14 @@ def test_update_knowledge_base_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "post_update_knowledge_base" ) as post, mock.patch.object( + transports.KnowledgeBasesRestInterceptor, + "post_update_knowledge_base_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.KnowledgeBasesRestInterceptor, "pre_update_knowledge_base" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_knowledge_base.UpdateKnowledgeBaseRequest.pb( gcd_knowledge_base.UpdateKnowledgeBaseRequest() ) @@ -5157,6 +5232,7 @@ def test_update_knowledge_base_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_knowledge_base.KnowledgeBase() + post_with_metadata.return_value = gcd_knowledge_base.KnowledgeBase(), metadata client.update_knowledge_base( request, @@ -5168,6 +5244,7 @@ def test_update_knowledge_base_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_participants.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_participants.py index eae2191cedc3..daaa17ac46f0 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_participants.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_participants.py @@ -75,6 +75,13 @@ from google.cloud.dialogflow_v2beta1.types import participant from google.cloud.dialogflow_v2beta1.types import session, session_entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -318,6 +325,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ParticipantsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ParticipantsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7867,10 +7917,13 @@ def test_create_participant_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_create_participant" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_create_participant_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_create_participant" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_participant.CreateParticipantRequest.pb( gcd_participant.CreateParticipantRequest() ) @@ -7896,6 +7949,7 @@ def test_create_participant_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_participant.Participant() + post_with_metadata.return_value = gcd_participant.Participant(), metadata client.create_participant( request, @@ -7907,6 +7961,7 @@ def test_create_participant_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_participant_rest_bad_request( @@ -7999,10 +8054,13 @@ def test_get_participant_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_get_participant" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_get_participant_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_get_participant" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.GetParticipantRequest.pb( participant.GetParticipantRequest() ) @@ -8026,6 +8084,7 @@ def test_get_participant_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.Participant() + post_with_metadata.return_value = participant.Participant(), metadata client.get_participant( request, @@ -8037,6 +8096,7 @@ def test_get_participant_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_participants_rest_bad_request( @@ -8121,10 +8181,13 @@ def test_list_participants_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_list_participants" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_list_participants_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_list_participants" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.ListParticipantsRequest.pb( participant.ListParticipantsRequest() ) @@ -8150,6 +8213,10 @@ def test_list_participants_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.ListParticipantsResponse() + post_with_metadata.return_value = ( + participant.ListParticipantsResponse(), + metadata, + ) client.list_participants( request, @@ -8161,6 +8228,7 @@ def test_list_participants_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_participant_rest_bad_request( @@ -8330,10 +8398,13 @@ def test_update_participant_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_update_participant" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_update_participant_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_update_participant" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_participant.UpdateParticipantRequest.pb( gcd_participant.UpdateParticipantRequest() ) @@ -8359,6 +8430,7 @@ def test_update_participant_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_participant.Participant() + post_with_metadata.return_value = gcd_participant.Participant(), metadata client.update_participant( request, @@ -8370,6 +8442,7 @@ def test_update_participant_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_analyze_content_rest_bad_request( @@ -8458,10 +8531,13 @@ def test_analyze_content_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_analyze_content" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_analyze_content_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_analyze_content" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_participant.AnalyzeContentRequest.pb( gcd_participant.AnalyzeContentRequest() ) @@ -8487,6 +8563,10 @@ def test_analyze_content_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_participant.AnalyzeContentResponse() + post_with_metadata.return_value = ( + gcd_participant.AnalyzeContentResponse(), + metadata, + ) client.analyze_content( request, @@ -8498,6 +8578,7 @@ def test_analyze_content_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_streaming_analyze_content_rest_error(): @@ -8600,10 +8681,13 @@ def test_suggest_articles_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_suggest_articles" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_suggest_articles_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_suggest_articles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.SuggestArticlesRequest.pb( participant.SuggestArticlesRequest() ) @@ -8629,6 +8713,10 @@ def test_suggest_articles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.SuggestArticlesResponse() + post_with_metadata.return_value = ( + participant.SuggestArticlesResponse(), + metadata, + ) client.suggest_articles( request, @@ -8640,6 +8728,7 @@ def test_suggest_articles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_suggest_faq_answers_rest_bad_request( @@ -8730,10 +8819,13 @@ def test_suggest_faq_answers_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_suggest_faq_answers" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_suggest_faq_answers_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_suggest_faq_answers" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.SuggestFaqAnswersRequest.pb( participant.SuggestFaqAnswersRequest() ) @@ -8759,6 +8851,10 @@ def test_suggest_faq_answers_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.SuggestFaqAnswersResponse() + post_with_metadata.return_value = ( + participant.SuggestFaqAnswersResponse(), + metadata, + ) client.suggest_faq_answers( request, @@ -8770,6 +8866,7 @@ def test_suggest_faq_answers_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_suggest_smart_replies_rest_bad_request( @@ -8860,10 +8957,14 @@ def test_suggest_smart_replies_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_suggest_smart_replies" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, + "post_suggest_smart_replies_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_suggest_smart_replies" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.SuggestSmartRepliesRequest.pb( participant.SuggestSmartRepliesRequest() ) @@ -8889,6 +8990,10 @@ def test_suggest_smart_replies_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.SuggestSmartRepliesResponse() + post_with_metadata.return_value = ( + participant.SuggestSmartRepliesResponse(), + metadata, + ) client.suggest_smart_replies( request, @@ -8900,6 +9005,7 @@ def test_suggest_smart_replies_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_suggest_knowledge_assist_rest_bad_request( @@ -8990,10 +9096,14 @@ def test_suggest_knowledge_assist_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_suggest_knowledge_assist" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, + "post_suggest_knowledge_assist_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_suggest_knowledge_assist" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.SuggestKnowledgeAssistRequest.pb( participant.SuggestKnowledgeAssistRequest() ) @@ -9019,6 +9129,10 @@ def test_suggest_knowledge_assist_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.SuggestKnowledgeAssistResponse() + post_with_metadata.return_value = ( + participant.SuggestKnowledgeAssistResponse(), + metadata, + ) client.suggest_knowledge_assist( request, @@ -9030,6 +9144,7 @@ def test_suggest_knowledge_assist_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_suggestions_rest_bad_request( @@ -9118,10 +9233,13 @@ def test_list_suggestions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_list_suggestions" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_list_suggestions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_list_suggestions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.ListSuggestionsRequest.pb( participant.ListSuggestionsRequest() ) @@ -9147,6 +9265,10 @@ def test_list_suggestions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.ListSuggestionsResponse() + post_with_metadata.return_value = ( + participant.ListSuggestionsResponse(), + metadata, + ) client.list_suggestions( request, @@ -9158,6 +9280,7 @@ def test_list_suggestions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_compile_suggestion_rest_bad_request( @@ -9248,10 +9371,13 @@ def test_compile_suggestion_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ParticipantsRestInterceptor, "post_compile_suggestion" ) as post, mock.patch.object( + transports.ParticipantsRestInterceptor, "post_compile_suggestion_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ParticipantsRestInterceptor, "pre_compile_suggestion" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = participant.CompileSuggestionRequest.pb( participant.CompileSuggestionRequest() ) @@ -9277,6 +9403,10 @@ def test_compile_suggestion_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = participant.CompileSuggestionResponse() + post_with_metadata.return_value = ( + participant.CompileSuggestionResponse(), + metadata, + ) client.compile_suggestion( request, @@ -9288,6 +9418,7 @@ def test_compile_suggestion_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_session_entity_types.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_session_entity_types.py index c38d1e16ab58..b07a5138fddd 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_session_entity_types.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_session_entity_types.py @@ -67,6 +67,13 @@ from google.cloud.dialogflow_v2beta1.types import entity_type from google.cloud.dialogflow_v2beta1.types import session_entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -338,6 +345,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionEntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionEntityTypesClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4579,10 +4629,14 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_list_session_entity_types" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_list_session_entity_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_list_session_entity_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_entity_type.ListSessionEntityTypesRequest.pb( session_entity_type.ListSessionEntityTypesRequest() ) @@ -4608,6 +4662,10 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_entity_type.ListSessionEntityTypesResponse() + post_with_metadata.return_value = ( + session_entity_type.ListSessionEntityTypesResponse(), + metadata, + ) client.list_session_entity_types( request, @@ -4619,6 +4677,7 @@ def test_list_session_entity_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_session_entity_type_rest_bad_request( @@ -4712,10 +4771,14 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_get_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_get_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_get_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = session_entity_type.GetSessionEntityTypeRequest.pb( session_entity_type.GetSessionEntityTypeRequest() ) @@ -4741,6 +4804,10 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + session_entity_type.SessionEntityType(), + metadata, + ) client.get_session_entity_type( request, @@ -4752,6 +4819,7 @@ def test_get_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_session_entity_type_rest_bad_request( @@ -4917,10 +4985,14 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_create_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_create_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_create_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_session_entity_type.CreateSessionEntityTypeRequest.pb( gcd_session_entity_type.CreateSessionEntityTypeRequest() ) @@ -4946,6 +5018,10 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + gcd_session_entity_type.SessionEntityType(), + metadata, + ) client.create_session_entity_type( request, @@ -4957,6 +5033,7 @@ def test_create_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_session_entity_type_rest_bad_request( @@ -5130,10 +5207,14 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "post_update_session_entity_type" ) as post, mock.patch.object( + transports.SessionEntityTypesRestInterceptor, + "post_update_session_entity_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SessionEntityTypesRestInterceptor, "pre_update_session_entity_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_session_entity_type.UpdateSessionEntityTypeRequest.pb( gcd_session_entity_type.UpdateSessionEntityTypeRequest() ) @@ -5159,6 +5240,10 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session_entity_type.SessionEntityType() + post_with_metadata.return_value = ( + gcd_session_entity_type.SessionEntityType(), + metadata, + ) client.update_session_entity_type( request, @@ -5170,6 +5255,7 @@ def test_update_session_entity_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_session_entity_type_rest_bad_request( diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_sessions.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_sessions.py index deadb5739a04..9c781dd99a87 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_sessions.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_sessions.py @@ -74,6 +74,13 @@ from google.cloud.dialogflow_v2beta1.types import session as gcd_session from google.cloud.dialogflow_v2beta1.types import session_entity_type +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -304,6 +311,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SessionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SessionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2017,10 +2067,13 @@ def test_detect_intent_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SessionsRestInterceptor, "post_detect_intent" ) as post, mock.patch.object( + transports.SessionsRestInterceptor, "post_detect_intent_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SessionsRestInterceptor, "pre_detect_intent" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_session.DetectIntentRequest.pb( gcd_session.DetectIntentRequest() ) @@ -2046,6 +2099,7 @@ def test_detect_intent_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session.DetectIntentResponse() + post_with_metadata.return_value = gcd_session.DetectIntentResponse(), metadata client.detect_intent( request, @@ -2057,6 +2111,7 @@ def test_detect_intent_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_streaming_detect_intent_rest_error(): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_sip_trunks.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_sip_trunks.py index feddae956bdc..48666fe48e28 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_sip_trunks.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_sip_trunks.py @@ -65,6 +65,13 @@ from google.cloud.dialogflow_v2beta1.types import sip_trunk from google.cloud.dialogflow_v2beta1.types import sip_trunk as gcd_sip_trunk +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -298,6 +305,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SipTrunksClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SipTrunksClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4386,10 +4436,13 @@ def test_create_sip_trunk_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SipTrunksRestInterceptor, "post_create_sip_trunk" ) as post, mock.patch.object( + transports.SipTrunksRestInterceptor, "post_create_sip_trunk_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SipTrunksRestInterceptor, "pre_create_sip_trunk" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_sip_trunk.CreateSipTrunkRequest.pb( gcd_sip_trunk.CreateSipTrunkRequest() ) @@ -4413,6 +4466,7 @@ def test_create_sip_trunk_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sip_trunk.SipTrunk() + post_with_metadata.return_value = gcd_sip_trunk.SipTrunk(), metadata client.create_sip_trunk( request, @@ -4424,6 +4478,7 @@ def test_create_sip_trunk_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_sip_trunk_rest_bad_request( @@ -4611,10 +4666,13 @@ def test_list_sip_trunks_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SipTrunksRestInterceptor, "post_list_sip_trunks" ) as post, mock.patch.object( + transports.SipTrunksRestInterceptor, "post_list_sip_trunks_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SipTrunksRestInterceptor, "pre_list_sip_trunks" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sip_trunk.ListSipTrunksRequest.pb(sip_trunk.ListSipTrunksRequest()) transcode.return_value = { "method": "post", @@ -4638,6 +4696,7 @@ def test_list_sip_trunks_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sip_trunk.ListSipTrunksResponse() + post_with_metadata.return_value = sip_trunk.ListSipTrunksResponse(), metadata client.list_sip_trunks( request, @@ -4649,6 +4708,7 @@ def test_list_sip_trunks_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_sip_trunk_rest_bad_request(request_type=sip_trunk.GetSipTrunkRequest): @@ -4733,10 +4793,13 @@ def test_get_sip_trunk_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SipTrunksRestInterceptor, "post_get_sip_trunk" ) as post, mock.patch.object( + transports.SipTrunksRestInterceptor, "post_get_sip_trunk_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SipTrunksRestInterceptor, "pre_get_sip_trunk" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sip_trunk.GetSipTrunkRequest.pb(sip_trunk.GetSipTrunkRequest()) transcode.return_value = { "method": "post", @@ -4758,6 +4821,7 @@ def test_get_sip_trunk_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sip_trunk.SipTrunk() + post_with_metadata.return_value = sip_trunk.SipTrunk(), metadata client.get_sip_trunk( request, @@ -4769,6 +4833,7 @@ def test_get_sip_trunk_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_sip_trunk_rest_bad_request( @@ -4942,10 +5007,13 @@ def test_update_sip_trunk_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SipTrunksRestInterceptor, "post_update_sip_trunk" ) as post, mock.patch.object( + transports.SipTrunksRestInterceptor, "post_update_sip_trunk_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SipTrunksRestInterceptor, "pre_update_sip_trunk" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_sip_trunk.UpdateSipTrunkRequest.pb( gcd_sip_trunk.UpdateSipTrunkRequest() ) @@ -4969,6 +5037,7 @@ def test_update_sip_trunk_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sip_trunk.SipTrunk() + post_with_metadata.return_value = gcd_sip_trunk.SipTrunk(), metadata client.update_sip_trunk( request, @@ -4980,6 +5049,7 @@ def test_update_sip_trunk_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_versions.py b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_versions.py index 5559904b5510..5520dd5088e4 100644 --- a/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_versions.py +++ b/packages/google-cloud-dialogflow/tests/unit/gapic/dialogflow_v2beta1/test_versions.py @@ -65,6 +65,13 @@ from google.cloud.dialogflow_v2beta1.types import version from google.cloud.dialogflow_v2beta1.types import version as gcd_version +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -295,6 +302,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = VersionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = VersionsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4273,10 +4323,13 @@ def test_list_versions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_list_versions" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_list_versions_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_list_versions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.ListVersionsRequest.pb(version.ListVersionsRequest()) transcode.return_value = { "method": "post", @@ -4300,6 +4353,7 @@ def test_list_versions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.ListVersionsResponse() + post_with_metadata.return_value = version.ListVersionsResponse(), metadata client.list_versions( request, @@ -4311,6 +4365,7 @@ def test_list_versions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_version_rest_bad_request(request_type=version.GetVersionRequest): @@ -4397,10 +4452,13 @@ def test_get_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_get_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_get_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_get_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = version.GetVersionRequest.pb(version.GetVersionRequest()) transcode.return_value = { "method": "post", @@ -4422,6 +4480,7 @@ def test_get_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = version.Version() + post_with_metadata.return_value = version.Version(), metadata client.get_version( request, @@ -4433,6 +4492,7 @@ def test_get_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_version_rest_bad_request(request_type=gcd_version.CreateVersionRequest): @@ -4593,10 +4653,13 @@ def test_create_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_create_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_create_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_create_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_version.CreateVersionRequest.pb( gcd_version.CreateVersionRequest() ) @@ -4620,6 +4683,7 @@ def test_create_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_version.Version() + post_with_metadata.return_value = gcd_version.Version(), metadata client.create_version( request, @@ -4631,6 +4695,7 @@ def test_create_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_version_rest_bad_request(request_type=gcd_version.UpdateVersionRequest): @@ -4791,10 +4856,13 @@ def test_update_version_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.VersionsRestInterceptor, "post_update_version" ) as post, mock.patch.object( + transports.VersionsRestInterceptor, "post_update_version_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.VersionsRestInterceptor, "pre_update_version" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = gcd_version.UpdateVersionRequest.pb( gcd_version.UpdateVersionRequest() ) @@ -4818,6 +4886,7 @@ def test_update_version_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_version.Version() + post_with_metadata.return_value = gcd_version.Version(), metadata client.update_version( request, @@ -4829,6 +4898,7 @@ def test_update_version_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_version_rest_bad_request(request_type=version.DeleteVersionRequest): diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine/gapic_version.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine/gapic_version.py index 458413f5c30f..558c8aab67c5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine/gapic_version.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/gapic_version.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/gapic_version.py index 458413f5c30f..558c8aab67c5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/gapic_version.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/completion_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/completion_service/client.py index b0a10091075a..c220728633b4 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/completion_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/completion_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -492,6 +494,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1279,16 +1308,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1334,16 +1367,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/completion_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/completion_service/transports/rest.py index d4d346f19cac..50716645d965 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/completion_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/completion_service/transports/rest.py @@ -139,12 +139,38 @@ def post_complete_query( ) -> completion_service.CompleteQueryResponse: """Post-rpc interceptor for complete_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_complete_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_complete_query` interceptor runs + before the `post_complete_query_with_metadata` interceptor. """ return response + def post_complete_query_with_metadata( + self, + response: completion_service.CompleteQueryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + completion_service.CompleteQueryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for complete_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_complete_query_with_metadata` + interceptor in new development instead of the `post_complete_query` interceptor. + When both interceptors are used, this `post_complete_query_with_metadata` interceptor runs after the + `post_complete_query` interceptor. The (possibly modified) response returned by + `post_complete_query` will be passed to + `post_complete_query_with_metadata`. + """ + return response, metadata + def pre_import_completion_suggestions( self, request: import_config.ImportCompletionSuggestionsRequest, @@ -165,12 +191,35 @@ def post_import_completion_suggestions( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_completion_suggestions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_completion_suggestions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_import_completion_suggestions` interceptor runs + before the `post_import_completion_suggestions_with_metadata` interceptor. """ return response + def post_import_completion_suggestions_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_completion_suggestions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_import_completion_suggestions_with_metadata` + interceptor in new development instead of the `post_import_completion_suggestions` interceptor. + When both interceptors are used, this `post_import_completion_suggestions_with_metadata` interceptor runs after the + `post_import_completion_suggestions` interceptor. The (possibly modified) response returned by + `post_import_completion_suggestions` will be passed to + `post_import_completion_suggestions_with_metadata`. + """ + return response, metadata + def pre_import_suggestion_deny_list_entries( self, request: import_config.ImportSuggestionDenyListEntriesRequest, @@ -191,12 +240,35 @@ def post_import_suggestion_deny_list_entries( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_suggestion_deny_list_entries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_suggestion_deny_list_entries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_import_suggestion_deny_list_entries` interceptor runs + before the `post_import_suggestion_deny_list_entries_with_metadata` interceptor. """ return response + def post_import_suggestion_deny_list_entries_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_suggestion_deny_list_entries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_import_suggestion_deny_list_entries_with_metadata` + interceptor in new development instead of the `post_import_suggestion_deny_list_entries` interceptor. + When both interceptors are used, this `post_import_suggestion_deny_list_entries_with_metadata` interceptor runs after the + `post_import_suggestion_deny_list_entries` interceptor. The (possibly modified) response returned by + `post_import_suggestion_deny_list_entries` will be passed to + `post_import_suggestion_deny_list_entries_with_metadata`. + """ + return response, metadata + def pre_purge_completion_suggestions( self, request: purge_config.PurgeCompletionSuggestionsRequest, @@ -217,12 +289,35 @@ def post_purge_completion_suggestions( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_completion_suggestions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_completion_suggestions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_purge_completion_suggestions` interceptor runs + before the `post_purge_completion_suggestions_with_metadata` interceptor. """ return response + def post_purge_completion_suggestions_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_completion_suggestions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_purge_completion_suggestions_with_metadata` + interceptor in new development instead of the `post_purge_completion_suggestions` interceptor. + When both interceptors are used, this `post_purge_completion_suggestions_with_metadata` interceptor runs after the + `post_purge_completion_suggestions` interceptor. The (possibly modified) response returned by + `post_purge_completion_suggestions` will be passed to + `post_purge_completion_suggestions_with_metadata`. + """ + return response, metadata + def pre_purge_suggestion_deny_list_entries( self, request: purge_config.PurgeSuggestionDenyListEntriesRequest, @@ -243,12 +338,35 @@ def post_purge_suggestion_deny_list_entries( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_suggestion_deny_list_entries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_suggestion_deny_list_entries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_purge_suggestion_deny_list_entries` interceptor runs + before the `post_purge_suggestion_deny_list_entries_with_metadata` interceptor. """ return response + def post_purge_suggestion_deny_list_entries_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_suggestion_deny_list_entries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_purge_suggestion_deny_list_entries_with_metadata` + interceptor in new development instead of the `post_purge_suggestion_deny_list_entries` interceptor. + When both interceptors are used, this `post_purge_suggestion_deny_list_entries_with_metadata` interceptor runs after the + `post_purge_suggestion_deny_list_entries` interceptor. The (possibly modified) response returned by + `post_purge_suggestion_deny_list_entries` will be passed to + `post_purge_suggestion_deny_list_entries_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -710,6 +828,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_complete_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_complete_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -865,6 +987,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_completion_suggestions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_import_completion_suggestions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1023,6 +1152,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_suggestion_deny_list_entries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_import_suggestion_deny_list_entries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1176,6 +1312,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_completion_suggestions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_purge_completion_suggestions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1332,6 +1472,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_suggestion_deny_list_entries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_purge_suggestion_deny_list_entries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/control_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/control_service/client.py index 78ee6e7b3636..0a341d204c99 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/control_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/control_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -519,6 +521,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1379,16 +1408,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1434,16 +1467,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/control_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/control_service/transports/rest.py index c98e3ca97a24..b7e75fb0eecc 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/control_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/control_service/transports/rest.py @@ -132,12 +132,35 @@ def pre_create_control( def post_create_control(self, response: gcd_control.Control) -> gcd_control.Control: """Post-rpc interceptor for create_control - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_control_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_create_control` interceptor runs + before the `post_create_control_with_metadata` interceptor. """ return response + def post_create_control_with_metadata( + self, + response: gcd_control.Control, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_control.Control, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_control + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_create_control_with_metadata` + interceptor in new development instead of the `post_create_control` interceptor. + When both interceptors are used, this `post_create_control_with_metadata` interceptor runs after the + `post_create_control` interceptor. The (possibly modified) response returned by + `post_create_control` will be passed to + `post_create_control_with_metadata`. + """ + return response, metadata + def pre_delete_control( self, request: control_service.DeleteControlRequest, @@ -169,12 +192,35 @@ def pre_get_control( def post_get_control(self, response: control.Control) -> control.Control: """Post-rpc interceptor for get_control - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_control_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_get_control` interceptor runs + before the `post_get_control_with_metadata` interceptor. """ return response + def post_get_control_with_metadata( + self, + response: control.Control, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[control.Control, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_control + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_get_control_with_metadata` + interceptor in new development instead of the `post_get_control` interceptor. + When both interceptors are used, this `post_get_control_with_metadata` interceptor runs after the + `post_get_control` interceptor. The (possibly modified) response returned by + `post_get_control` will be passed to + `post_get_control_with_metadata`. + """ + return response, metadata + def pre_list_controls( self, request: control_service.ListControlsRequest, @@ -194,12 +240,37 @@ def post_list_controls( ) -> control_service.ListControlsResponse: """Post-rpc interceptor for list_controls - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_controls_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_list_controls` interceptor runs + before the `post_list_controls_with_metadata` interceptor. """ return response + def post_list_controls_with_metadata( + self, + response: control_service.ListControlsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + control_service.ListControlsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_controls + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_list_controls_with_metadata` + interceptor in new development instead of the `post_list_controls` interceptor. + When both interceptors are used, this `post_list_controls_with_metadata` interceptor runs after the + `post_list_controls` interceptor. The (possibly modified) response returned by + `post_list_controls` will be passed to + `post_list_controls_with_metadata`. + """ + return response, metadata + def pre_update_control( self, request: control_service.UpdateControlRequest, @@ -217,12 +288,35 @@ def pre_update_control( def post_update_control(self, response: gcd_control.Control) -> gcd_control.Control: """Post-rpc interceptor for update_control - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_control_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_update_control` interceptor runs + before the `post_update_control_with_metadata` interceptor. """ return response + def post_update_control_with_metadata( + self, + response: gcd_control.Control, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_control.Control, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_control + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_update_control_with_metadata` + interceptor in new development instead of the `post_update_control` interceptor. + When both interceptors are used, this `post_update_control_with_metadata` interceptor runs after the + `post_update_control` interceptor. The (possibly modified) response returned by + `post_update_control` will be passed to + `post_update_control_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -514,6 +608,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_control(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_control_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -767,6 +865,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_control(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_control_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -907,6 +1009,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_controls(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_controls_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1060,6 +1166,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_control(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_control_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/conversational_search_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/conversational_search_service/client.py index 886076fa0b0d..d86f07e4dff8 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/conversational_search_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/conversational_search_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -657,6 +659,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2392,16 +2421,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2447,16 +2480,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/conversational_search_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/conversational_search_service/transports/rest.py index aa3fe27111cc..56f0b2e148a1 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/conversational_search_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/conversational_search_service/transports/rest.py @@ -198,12 +198,38 @@ def post_answer_query( ) -> conversational_search_service.AnswerQueryResponse: """Post-rpc interceptor for answer_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_answer_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_answer_query` interceptor runs + before the `post_answer_query_with_metadata` interceptor. """ return response + def post_answer_query_with_metadata( + self, + response: conversational_search_service.AnswerQueryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.AnswerQueryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for answer_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_answer_query_with_metadata` + interceptor in new development instead of the `post_answer_query` interceptor. + When both interceptors are used, this `post_answer_query_with_metadata` interceptor runs after the + `post_answer_query` interceptor. The (possibly modified) response returned by + `post_answer_query` will be passed to + `post_answer_query_with_metadata`. + """ + return response, metadata + def pre_converse_conversation( self, request: conversational_search_service.ConverseConversationRequest, @@ -224,12 +250,38 @@ def post_converse_conversation( ) -> conversational_search_service.ConverseConversationResponse: """Post-rpc interceptor for converse_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_converse_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_converse_conversation` interceptor runs + before the `post_converse_conversation_with_metadata` interceptor. """ return response + def post_converse_conversation_with_metadata( + self, + response: conversational_search_service.ConverseConversationResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.ConverseConversationResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for converse_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_converse_conversation_with_metadata` + interceptor in new development instead of the `post_converse_conversation` interceptor. + When both interceptors are used, this `post_converse_conversation_with_metadata` interceptor runs after the + `post_converse_conversation` interceptor. The (possibly modified) response returned by + `post_converse_conversation` will be passed to + `post_converse_conversation_with_metadata`. + """ + return response, metadata + def pre_create_conversation( self, request: conversational_search_service.CreateConversationRequest, @@ -250,12 +302,35 @@ def post_create_conversation( ) -> gcd_conversation.Conversation: """Post-rpc interceptor for create_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation` interceptor runs + before the `post_create_conversation_with_metadata` interceptor. """ return response + def post_create_conversation_with_metadata( + self, + response: gcd_conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_create_conversation_with_metadata` + interceptor in new development instead of the `post_create_conversation` interceptor. + When both interceptors are used, this `post_create_conversation_with_metadata` interceptor runs after the + `post_create_conversation` interceptor. The (possibly modified) response returned by + `post_create_conversation` will be passed to + `post_create_conversation_with_metadata`. + """ + return response, metadata + def pre_create_session( self, request: conversational_search_service.CreateSessionRequest, @@ -274,12 +349,35 @@ def pre_create_session( def post_create_session(self, response: gcd_session.Session) -> gcd_session.Session: """Post-rpc interceptor for create_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_create_session` interceptor runs + before the `post_create_session_with_metadata` interceptor. """ return response + def post_create_session_with_metadata( + self, + response: gcd_session.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_session.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_create_session_with_metadata` + interceptor in new development instead of the `post_create_session` interceptor. + When both interceptors are used, this `post_create_session_with_metadata` interceptor runs after the + `post_create_session` interceptor. The (possibly modified) response returned by + `post_create_session` will be passed to + `post_create_session_with_metadata`. + """ + return response, metadata + def pre_delete_conversation( self, request: conversational_search_service.DeleteConversationRequest, @@ -328,12 +426,33 @@ def pre_get_answer( def post_get_answer(self, response: answer.Answer) -> answer.Answer: """Post-rpc interceptor for get_answer - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_answer_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_get_answer` interceptor runs + before the `post_get_answer_with_metadata` interceptor. """ return response + def post_get_answer_with_metadata( + self, response: answer.Answer, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[answer.Answer, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_answer + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_get_answer_with_metadata` + interceptor in new development instead of the `post_get_answer` interceptor. + When both interceptors are used, this `post_get_answer_with_metadata` interceptor runs after the + `post_get_answer` interceptor. The (possibly modified) response returned by + `post_get_answer` will be passed to + `post_get_answer_with_metadata`. + """ + return response, metadata + def pre_get_conversation( self, request: conversational_search_service.GetConversationRequest, @@ -354,12 +473,35 @@ def post_get_conversation( ) -> conversation.Conversation: """Post-rpc interceptor for get_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation` interceptor runs + before the `post_get_conversation_with_metadata` interceptor. """ return response + def post_get_conversation_with_metadata( + self, + response: conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_get_conversation_with_metadata` + interceptor in new development instead of the `post_get_conversation` interceptor. + When both interceptors are used, this `post_get_conversation_with_metadata` interceptor runs after the + `post_get_conversation` interceptor. The (possibly modified) response returned by + `post_get_conversation` will be passed to + `post_get_conversation_with_metadata`. + """ + return response, metadata + def pre_get_session( self, request: conversational_search_service.GetSessionRequest, @@ -378,12 +520,35 @@ def pre_get_session( def post_get_session(self, response: session.Session) -> session.Session: """Post-rpc interceptor for get_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_get_session` interceptor runs + before the `post_get_session_with_metadata` interceptor. """ return response + def post_get_session_with_metadata( + self, + response: session.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_get_session_with_metadata` + interceptor in new development instead of the `post_get_session` interceptor. + When both interceptors are used, this `post_get_session_with_metadata` interceptor runs after the + `post_get_session` interceptor. The (possibly modified) response returned by + `post_get_session` will be passed to + `post_get_session_with_metadata`. + """ + return response, metadata + def pre_list_conversations( self, request: conversational_search_service.ListConversationsRequest, @@ -404,12 +569,38 @@ def post_list_conversations( ) -> conversational_search_service.ListConversationsResponse: """Post-rpc interceptor for list_conversations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_list_conversations` interceptor runs + before the `post_list_conversations_with_metadata` interceptor. """ return response + def post_list_conversations_with_metadata( + self, + response: conversational_search_service.ListConversationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.ListConversationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_conversations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_list_conversations_with_metadata` + interceptor in new development instead of the `post_list_conversations` interceptor. + When both interceptors are used, this `post_list_conversations_with_metadata` interceptor runs after the + `post_list_conversations` interceptor. The (possibly modified) response returned by + `post_list_conversations` will be passed to + `post_list_conversations_with_metadata`. + """ + return response, metadata + def pre_list_sessions( self, request: conversational_search_service.ListSessionsRequest, @@ -430,12 +621,38 @@ def post_list_sessions( ) -> conversational_search_service.ListSessionsResponse: """Post-rpc interceptor for list_sessions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_sessions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_list_sessions` interceptor runs + before the `post_list_sessions_with_metadata` interceptor. """ return response + def post_list_sessions_with_metadata( + self, + response: conversational_search_service.ListSessionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.ListSessionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_sessions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_list_sessions_with_metadata` + interceptor in new development instead of the `post_list_sessions` interceptor. + When both interceptors are used, this `post_list_sessions_with_metadata` interceptor runs after the + `post_list_sessions` interceptor. The (possibly modified) response returned by + `post_list_sessions` will be passed to + `post_list_sessions_with_metadata`. + """ + return response, metadata + def pre_update_conversation( self, request: conversational_search_service.UpdateConversationRequest, @@ -456,12 +673,35 @@ def post_update_conversation( ) -> gcd_conversation.Conversation: """Post-rpc interceptor for update_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_update_conversation` interceptor runs + before the `post_update_conversation_with_metadata` interceptor. """ return response + def post_update_conversation_with_metadata( + self, + response: gcd_conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_update_conversation_with_metadata` + interceptor in new development instead of the `post_update_conversation` interceptor. + When both interceptors are used, this `post_update_conversation_with_metadata` interceptor runs after the + `post_update_conversation` interceptor. The (possibly modified) response returned by + `post_update_conversation` will be passed to + `post_update_conversation_with_metadata`. + """ + return response, metadata + def pre_update_session( self, request: conversational_search_service.UpdateSessionRequest, @@ -480,12 +720,35 @@ def pre_update_session( def post_update_session(self, response: gcd_session.Session) -> gcd_session.Session: """Post-rpc interceptor for update_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_update_session` interceptor runs + before the `post_update_session_with_metadata` interceptor. """ return response + def post_update_session_with_metadata( + self, + response: gcd_session.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_session.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_update_session_with_metadata` + interceptor in new development instead of the `post_update_session` interceptor. + When both interceptors are used, this `post_update_session_with_metadata` interceptor runs after the + `post_update_session` interceptor. The (possibly modified) response returned by + `post_update_session` will be passed to + `post_update_session_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -779,6 +1042,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_answer_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_answer_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -939,6 +1206,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_converse_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_converse_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1093,6 +1364,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1242,6 +1517,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1604,6 +1883,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_answer(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_answer_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1751,6 +2034,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1894,6 +2181,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2039,6 +2330,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2186,6 +2481,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_sessions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sessions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2342,6 +2641,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2491,6 +2794,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/data_store_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/data_store_service/client.py index fa43ce47c295..e4c15b458c7c 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/data_store_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/data_store_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -572,6 +574,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1519,16 +1548,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1574,16 +1607,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/data_store_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/data_store_service/transports/rest.py index 33d3286ea2b0..954f6aeb7030 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/data_store_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/data_store_service/transports/rest.py @@ -138,12 +138,35 @@ def post_create_data_store( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_create_data_store` interceptor runs + before the `post_create_data_store_with_metadata` interceptor. """ return response + def post_create_data_store_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_create_data_store_with_metadata` + interceptor in new development instead of the `post_create_data_store` interceptor. + When both interceptors are used, this `post_create_data_store_with_metadata` interceptor runs after the + `post_create_data_store` interceptor. The (possibly modified) response returned by + `post_create_data_store` will be passed to + `post_create_data_store_with_metadata`. + """ + return response, metadata + def pre_delete_data_store( self, request: data_store_service.DeleteDataStoreRequest, @@ -164,12 +187,35 @@ def post_delete_data_store( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_delete_data_store` interceptor runs + before the `post_delete_data_store_with_metadata` interceptor. """ return response + def post_delete_data_store_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_delete_data_store_with_metadata` + interceptor in new development instead of the `post_delete_data_store` interceptor. + When both interceptors are used, this `post_delete_data_store_with_metadata` interceptor runs after the + `post_delete_data_store` interceptor. The (possibly modified) response returned by + `post_delete_data_store` will be passed to + `post_delete_data_store_with_metadata`. + """ + return response, metadata + def pre_get_data_store( self, request: data_store_service.GetDataStoreRequest, @@ -189,12 +235,35 @@ def post_get_data_store( ) -> data_store.DataStore: """Post-rpc interceptor for get_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_get_data_store` interceptor runs + before the `post_get_data_store_with_metadata` interceptor. """ return response + def post_get_data_store_with_metadata( + self, + response: data_store.DataStore, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[data_store.DataStore, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_get_data_store_with_metadata` + interceptor in new development instead of the `post_get_data_store` interceptor. + When both interceptors are used, this `post_get_data_store_with_metadata` interceptor runs after the + `post_get_data_store` interceptor. The (possibly modified) response returned by + `post_get_data_store` will be passed to + `post_get_data_store_with_metadata`. + """ + return response, metadata + def pre_list_data_stores( self, request: data_store_service.ListDataStoresRequest, @@ -215,12 +284,38 @@ def post_list_data_stores( ) -> data_store_service.ListDataStoresResponse: """Post-rpc interceptor for list_data_stores - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_data_stores_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_list_data_stores` interceptor runs + before the `post_list_data_stores_with_metadata` interceptor. """ return response + def post_list_data_stores_with_metadata( + self, + response: data_store_service.ListDataStoresResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_store_service.ListDataStoresResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_data_stores + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_list_data_stores_with_metadata` + interceptor in new development instead of the `post_list_data_stores` interceptor. + When both interceptors are used, this `post_list_data_stores_with_metadata` interceptor runs after the + `post_list_data_stores` interceptor. The (possibly modified) response returned by + `post_list_data_stores` will be passed to + `post_list_data_stores_with_metadata`. + """ + return response, metadata + def pre_update_data_store( self, request: data_store_service.UpdateDataStoreRequest, @@ -241,12 +336,35 @@ def post_update_data_store( ) -> gcd_data_store.DataStore: """Post-rpc interceptor for update_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_update_data_store` interceptor runs + before the `post_update_data_store_with_metadata` interceptor. """ return response + def post_update_data_store_with_metadata( + self, + response: gcd_data_store.DataStore, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_data_store.DataStore, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_update_data_store_with_metadata` + interceptor in new development instead of the `post_update_data_store` interceptor. + When both interceptors are used, this `post_update_data_store_with_metadata` interceptor runs after the + `post_update_data_store` interceptor. The (possibly modified) response returned by + `post_update_data_store` will be passed to + `post_update_data_store_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -716,6 +834,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -862,6 +984,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1006,6 +1132,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1153,6 +1283,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_data_stores(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_data_stores_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1308,6 +1442,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/document_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/document_service/client.py index 641902a60428..413697f53938 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/document_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/document_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -581,6 +583,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1813,16 +1842,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1868,16 +1901,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/document_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/document_service/transports/rest.py index 4e2c3b994a8b..7e00ed76fd0f 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/document_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/document_service/transports/rest.py @@ -163,12 +163,38 @@ def post_batch_get_documents_metadata( ) -> document_service.BatchGetDocumentsMetadataResponse: """Post-rpc interceptor for batch_get_documents_metadata - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_get_documents_metadata_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_batch_get_documents_metadata` interceptor runs + before the `post_batch_get_documents_metadata_with_metadata` interceptor. """ return response + def post_batch_get_documents_metadata_with_metadata( + self, + response: document_service.BatchGetDocumentsMetadataResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + document_service.BatchGetDocumentsMetadataResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_get_documents_metadata + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_batch_get_documents_metadata_with_metadata` + interceptor in new development instead of the `post_batch_get_documents_metadata` interceptor. + When both interceptors are used, this `post_batch_get_documents_metadata_with_metadata` interceptor runs after the + `post_batch_get_documents_metadata` interceptor. The (possibly modified) response returned by + `post_batch_get_documents_metadata` will be passed to + `post_batch_get_documents_metadata_with_metadata`. + """ + return response, metadata + def pre_create_document( self, request: document_service.CreateDocumentRequest, @@ -188,12 +214,35 @@ def post_create_document( ) -> gcd_document.Document: """Post-rpc interceptor for create_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_create_document` interceptor runs + before the `post_create_document_with_metadata` interceptor. """ return response + def post_create_document_with_metadata( + self, + response: gcd_document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_create_document_with_metadata` + interceptor in new development instead of the `post_create_document` interceptor. + When both interceptors are used, this `post_create_document_with_metadata` interceptor runs after the + `post_create_document` interceptor. The (possibly modified) response returned by + `post_create_document` will be passed to + `post_create_document_with_metadata`. + """ + return response, metadata + def pre_delete_document( self, request: document_service.DeleteDocumentRequest, @@ -225,12 +274,35 @@ def pre_get_document( def post_get_document(self, response: document.Document) -> document.Document: """Post-rpc interceptor for get_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_get_document` interceptor runs + before the `post_get_document_with_metadata` interceptor. """ return response + def post_get_document_with_metadata( + self, + response: document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_get_document_with_metadata` + interceptor in new development instead of the `post_get_document` interceptor. + When both interceptors are used, this `post_get_document_with_metadata` interceptor runs after the + `post_get_document` interceptor. The (possibly modified) response returned by + `post_get_document` will be passed to + `post_get_document_with_metadata`. + """ + return response, metadata + def pre_import_documents( self, request: import_config.ImportDocumentsRequest, @@ -250,12 +322,35 @@ def post_import_documents( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_import_documents` interceptor runs + before the `post_import_documents_with_metadata` interceptor. """ return response + def post_import_documents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_import_documents_with_metadata` + interceptor in new development instead of the `post_import_documents` interceptor. + When both interceptors are used, this `post_import_documents_with_metadata` interceptor runs after the + `post_import_documents` interceptor. The (possibly modified) response returned by + `post_import_documents` will be passed to + `post_import_documents_with_metadata`. + """ + return response, metadata + def pre_list_documents( self, request: document_service.ListDocumentsRequest, @@ -275,12 +370,37 @@ def post_list_documents( ) -> document_service.ListDocumentsResponse: """Post-rpc interceptor for list_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_list_documents` interceptor runs + before the `post_list_documents_with_metadata` interceptor. """ return response + def post_list_documents_with_metadata( + self, + response: document_service.ListDocumentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + document_service.ListDocumentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_list_documents_with_metadata` + interceptor in new development instead of the `post_list_documents` interceptor. + When both interceptors are used, this `post_list_documents_with_metadata` interceptor runs after the + `post_list_documents` interceptor. The (possibly modified) response returned by + `post_list_documents` will be passed to + `post_list_documents_with_metadata`. + """ + return response, metadata + def pre_purge_documents( self, request: purge_config.PurgeDocumentsRequest, @@ -300,12 +420,35 @@ def post_purge_documents( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_purge_documents` interceptor runs + before the `post_purge_documents_with_metadata` interceptor. """ return response + def post_purge_documents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_purge_documents_with_metadata` + interceptor in new development instead of the `post_purge_documents` interceptor. + When both interceptors are used, this `post_purge_documents_with_metadata` interceptor runs after the + `post_purge_documents` interceptor. The (possibly modified) response returned by + `post_purge_documents` will be passed to + `post_purge_documents_with_metadata`. + """ + return response, metadata + def pre_update_document( self, request: document_service.UpdateDocumentRequest, @@ -325,12 +468,35 @@ def post_update_document( ) -> gcd_document.Document: """Post-rpc interceptor for update_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_update_document` interceptor runs + before the `post_update_document_with_metadata` interceptor. """ return response + def post_update_document_with_metadata( + self, + response: gcd_document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_update_document_with_metadata` + interceptor in new development instead of the `post_update_document` interceptor. + When both interceptors are used, this `post_update_document_with_metadata` interceptor runs after the + `post_update_document` interceptor. The (possibly modified) response returned by + `post_update_document` will be passed to + `post_update_document_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -799,6 +965,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_get_documents_metadata(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_get_documents_metadata_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -954,6 +1124,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1207,6 +1381,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1356,6 +1534,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1501,6 +1683,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1652,6 +1838,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_purge_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1803,6 +1993,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/engine_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/engine_service/client.py index d64184effa1a..ba41703167c5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/engine_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/engine_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -521,6 +523,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1433,16 +1462,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1488,16 +1521,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/engine_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/engine_service/transports/rest.py index 1309d3b56ae3..c3981c1e9ffb 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/engine_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/engine_service/transports/rest.py @@ -137,12 +137,35 @@ def post_create_engine( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_create_engine` interceptor runs + before the `post_create_engine_with_metadata` interceptor. """ return response + def post_create_engine_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_create_engine_with_metadata` + interceptor in new development instead of the `post_create_engine` interceptor. + When both interceptors are used, this `post_create_engine_with_metadata` interceptor runs after the + `post_create_engine` interceptor. The (possibly modified) response returned by + `post_create_engine` will be passed to + `post_create_engine_with_metadata`. + """ + return response, metadata + def pre_delete_engine( self, request: engine_service.DeleteEngineRequest, @@ -162,12 +185,35 @@ def post_delete_engine( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_delete_engine` interceptor runs + before the `post_delete_engine_with_metadata` interceptor. """ return response + def post_delete_engine_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_delete_engine_with_metadata` + interceptor in new development instead of the `post_delete_engine` interceptor. + When both interceptors are used, this `post_delete_engine_with_metadata` interceptor runs after the + `post_delete_engine` interceptor. The (possibly modified) response returned by + `post_delete_engine` will be passed to + `post_delete_engine_with_metadata`. + """ + return response, metadata + def pre_get_engine( self, request: engine_service.GetEngineRequest, @@ -185,12 +231,33 @@ def pre_get_engine( def post_get_engine(self, response: engine.Engine) -> engine.Engine: """Post-rpc interceptor for get_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_engine` interceptor runs + before the `post_get_engine_with_metadata` interceptor. """ return response + def post_get_engine_with_metadata( + self, response: engine.Engine, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_get_engine_with_metadata` + interceptor in new development instead of the `post_get_engine` interceptor. + When both interceptors are used, this `post_get_engine_with_metadata` interceptor runs after the + `post_get_engine` interceptor. The (possibly modified) response returned by + `post_get_engine` will be passed to + `post_get_engine_with_metadata`. + """ + return response, metadata + def pre_list_engines( self, request: engine_service.ListEnginesRequest, @@ -210,12 +277,37 @@ def post_list_engines( ) -> engine_service.ListEnginesResponse: """Post-rpc interceptor for list_engines - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_engines_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_list_engines` interceptor runs + before the `post_list_engines_with_metadata` interceptor. """ return response + def post_list_engines_with_metadata( + self, + response: engine_service.ListEnginesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + engine_service.ListEnginesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_engines + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_list_engines_with_metadata` + interceptor in new development instead of the `post_list_engines` interceptor. + When both interceptors are used, this `post_list_engines_with_metadata` interceptor runs after the + `post_list_engines` interceptor. The (possibly modified) response returned by + `post_list_engines` will be passed to + `post_list_engines_with_metadata`. + """ + return response, metadata + def pre_update_engine( self, request: engine_service.UpdateEngineRequest, @@ -233,12 +325,35 @@ def pre_update_engine( def post_update_engine(self, response: gcd_engine.Engine) -> gcd_engine.Engine: """Post-rpc interceptor for update_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_update_engine` interceptor runs + before the `post_update_engine_with_metadata` interceptor. """ return response + def post_update_engine_with_metadata( + self, + response: gcd_engine.Engine, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_update_engine_with_metadata` + interceptor in new development instead of the `post_update_engine` interceptor. + When both interceptors are used, this `post_update_engine_with_metadata` interceptor runs after the + `post_update_engine` interceptor. The (possibly modified) response returned by + `post_update_engine` will be passed to + `post_update_engine_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -704,6 +819,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -847,6 +966,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -996,6 +1119,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1143,6 +1270,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_engines(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_engines_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1296,6 +1427,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/grounded_generation_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/grounded_generation_service/client.py index 103c667a79ec..f43125276d83 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/grounded_generation_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/grounded_generation_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -531,6 +533,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1061,16 +1090,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1116,16 +1149,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/grounded_generation_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/grounded_generation_service/transports/rest.py index 9b7b9e98fbcb..63a382de86bc 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/grounded_generation_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/grounded_generation_service/transports/rest.py @@ -112,12 +112,38 @@ def post_check_grounding( ) -> grounded_generation_service.CheckGroundingResponse: """Post-rpc interceptor for check_grounding - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_check_grounding_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the GroundedGenerationService server but before - it is returned to user code. + it is returned to user code. This `post_check_grounding` interceptor runs + before the `post_check_grounding_with_metadata` interceptor. """ return response + def post_check_grounding_with_metadata( + self, + response: grounded_generation_service.CheckGroundingResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grounded_generation_service.CheckGroundingResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for check_grounding + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the GroundedGenerationService server but before it is returned to user code. + + We recommend only using this `post_check_grounding_with_metadata` + interceptor in new development instead of the `post_check_grounding` interceptor. + When both interceptors are used, this `post_check_grounding_with_metadata` interceptor runs after the + `post_check_grounding` interceptor. The (possibly modified) response returned by + `post_check_grounding` will be passed to + `post_check_grounding_with_metadata`. + """ + return response, metadata + def pre_generate_grounded_content( self, request: grounded_generation_service.GenerateGroundedContentRequest, @@ -138,12 +164,38 @@ def post_generate_grounded_content( ) -> grounded_generation_service.GenerateGroundedContentResponse: """Post-rpc interceptor for generate_grounded_content - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_generate_grounded_content_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the GroundedGenerationService server but before - it is returned to user code. + it is returned to user code. This `post_generate_grounded_content` interceptor runs + before the `post_generate_grounded_content_with_metadata` interceptor. """ return response + def post_generate_grounded_content_with_metadata( + self, + response: grounded_generation_service.GenerateGroundedContentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grounded_generation_service.GenerateGroundedContentResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for generate_grounded_content + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the GroundedGenerationService server but before it is returned to user code. + + We recommend only using this `post_generate_grounded_content_with_metadata` + interceptor in new development instead of the `post_generate_grounded_content` interceptor. + When both interceptors are used, this `post_generate_grounded_content_with_metadata` interceptor runs after the + `post_generate_grounded_content` interceptor. The (possibly modified) response returned by + `post_generate_grounded_content` will be passed to + `post_generate_grounded_content_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -437,6 +489,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_check_grounding(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_check_grounding_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -595,6 +651,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_generate_grounded_content(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_generate_grounded_content_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/project_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/project_service/client.py index 73cd5a91dbd5..f4eb201ca72b 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/project_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/project_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -483,6 +485,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -867,16 +896,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -922,16 +955,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/project_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/project_service/transports/rest.py index 280f111b3be5..c0ac7275aac5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/project_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/project_service/transports/rest.py @@ -103,12 +103,35 @@ def post_provision_project( ) -> operations_pb2.Operation: """Post-rpc interceptor for provision_project - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_provision_project_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ProjectService server but before - it is returned to user code. + it is returned to user code. This `post_provision_project` interceptor runs + before the `post_provision_project_with_metadata` interceptor. """ return response + def post_provision_project_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for provision_project + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ProjectService server but before it is returned to user code. + + We recommend only using this `post_provision_project_with_metadata` + interceptor in new development instead of the `post_provision_project` interceptor. + When both interceptors are used, this `post_provision_project_with_metadata` interceptor runs after the + `post_provision_project` interceptor. The (possibly modified) response returned by + `post_provision_project` will be passed to + `post_provision_project_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -576,6 +599,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_provision_project(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_provision_project_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/rank_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/rank_service/client.py index f475c2211c8b..6d2c31aa1956 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/rank_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/rank_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -484,6 +486,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -823,16 +852,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -878,16 +911,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/rank_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/rank_service/transports/rest.py index 04d8e0b8bcf6..3107d51a859b 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/rank_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/rank_service/transports/rest.py @@ -101,12 +101,35 @@ def post_rank( ) -> rank_service.RankResponse: """Post-rpc interceptor for rank - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_rank_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the RankService server but before - it is returned to user code. + it is returned to user code. This `post_rank` interceptor runs + before the `post_rank_with_metadata` interceptor. """ return response + def post_rank_with_metadata( + self, + response: rank_service.RankResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[rank_service.RankResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for rank + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the RankService server but before it is returned to user code. + + We recommend only using this `post_rank_with_metadata` + interceptor in new development instead of the `post_rank` interceptor. + When both interceptors are used, this `post_rank_with_metadata` interceptor runs after the + `post_rank` interceptor. The (possibly modified) response returned by + `post_rank` will be passed to + `post_rank_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -395,6 +418,8 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_rank(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_rank_with_metadata(resp, response_metadata) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/recommendation_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/recommendation_service/client.py index b37910f058fa..bdeca9a78d99 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/recommendation_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/recommendation_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -562,6 +564,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -911,16 +940,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -966,16 +999,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/recommendation_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/recommendation_service/transports/rest.py index 01fe3f63615d..863143a7e3ef 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/recommendation_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/recommendation_service/transports/rest.py @@ -103,12 +103,38 @@ def post_recommend( ) -> recommendation_service.RecommendResponse: """Post-rpc interceptor for recommend - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_recommend_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the RecommendationService server but before - it is returned to user code. + it is returned to user code. This `post_recommend` interceptor runs + before the `post_recommend_with_metadata` interceptor. """ return response + def post_recommend_with_metadata( + self, + response: recommendation_service.RecommendResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + recommendation_service.RecommendResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for recommend + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the RecommendationService server but before it is returned to user code. + + We recommend only using this `post_recommend_with_metadata` + interceptor in new development instead of the `post_recommend` interceptor. + When both interceptors are used, this `post_recommend_with_metadata` interceptor runs after the + `post_recommend` interceptor. The (possibly modified) response returned by + `post_recommend` will be passed to + `post_recommend_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -395,6 +421,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_recommend(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_recommend_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/schema_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/schema_service/client.py index f24399b38f93..d8ad7a3575d0 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/schema_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/schema_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -517,6 +519,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1383,16 +1412,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1438,16 +1471,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/schema_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/schema_service/transports/rest.py index 9e33bef7723d..693ea25901a8 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/schema_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/schema_service/transports/rest.py @@ -135,12 +135,35 @@ def post_create_schema( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_create_schema` interceptor runs + before the `post_create_schema_with_metadata` interceptor. """ return response + def post_create_schema_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_create_schema_with_metadata` + interceptor in new development instead of the `post_create_schema` interceptor. + When both interceptors are used, this `post_create_schema_with_metadata` interceptor runs after the + `post_create_schema` interceptor. The (possibly modified) response returned by + `post_create_schema` will be passed to + `post_create_schema_with_metadata`. + """ + return response, metadata + def pre_delete_schema( self, request: schema_service.DeleteSchemaRequest, @@ -160,12 +183,35 @@ def post_delete_schema( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_delete_schema` interceptor runs + before the `post_delete_schema_with_metadata` interceptor. """ return response + def post_delete_schema_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_delete_schema_with_metadata` + interceptor in new development instead of the `post_delete_schema` interceptor. + When both interceptors are used, this `post_delete_schema_with_metadata` interceptor runs after the + `post_delete_schema` interceptor. The (possibly modified) response returned by + `post_delete_schema` will be passed to + `post_delete_schema_with_metadata`. + """ + return response, metadata + def pre_get_schema( self, request: schema_service.GetSchemaRequest, @@ -183,12 +229,33 @@ def pre_get_schema( def post_get_schema(self, response: schema.Schema) -> schema.Schema: """Post-rpc interceptor for get_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_get_schema` interceptor runs + before the `post_get_schema_with_metadata` interceptor. """ return response + def post_get_schema_with_metadata( + self, response: schema.Schema, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[schema.Schema, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_get_schema_with_metadata` + interceptor in new development instead of the `post_get_schema` interceptor. + When both interceptors are used, this `post_get_schema_with_metadata` interceptor runs after the + `post_get_schema` interceptor. The (possibly modified) response returned by + `post_get_schema` will be passed to + `post_get_schema_with_metadata`. + """ + return response, metadata + def pre_list_schemas( self, request: schema_service.ListSchemasRequest, @@ -208,12 +275,37 @@ def post_list_schemas( ) -> schema_service.ListSchemasResponse: """Post-rpc interceptor for list_schemas - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_schemas_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_list_schemas` interceptor runs + before the `post_list_schemas_with_metadata` interceptor. """ return response + def post_list_schemas_with_metadata( + self, + response: schema_service.ListSchemasResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + schema_service.ListSchemasResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_schemas + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_list_schemas_with_metadata` + interceptor in new development instead of the `post_list_schemas` interceptor. + When both interceptors are used, this `post_list_schemas_with_metadata` interceptor runs after the + `post_list_schemas` interceptor. The (possibly modified) response returned by + `post_list_schemas` will be passed to + `post_list_schemas_with_metadata`. + """ + return response, metadata + def pre_update_schema( self, request: schema_service.UpdateSchemaRequest, @@ -233,12 +325,35 @@ def post_update_schema( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_update_schema` interceptor runs + before the `post_update_schema_with_metadata` interceptor. """ return response + def post_update_schema_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_update_schema_with_metadata` + interceptor in new development instead of the `post_update_schema` interceptor. + When both interceptors are used, this `post_update_schema_with_metadata` interceptor runs after the + `post_update_schema` interceptor. The (possibly modified) response returned by + `post_update_schema` will be passed to + `post_update_schema_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -704,6 +819,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -847,6 +966,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -995,6 +1118,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1142,6 +1269,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_schemas(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_schemas_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1293,6 +1424,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_service/client.py index de36fe6fcde3..f2abeafec42f 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -611,6 +613,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1084,16 +1113,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1139,16 +1172,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_service/transports/rest.py index 88ee2feedd8b..29755bad44db 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_service/transports/rest.py @@ -109,12 +109,35 @@ def post_search( ) -> search_service.SearchResponse: """Post-rpc interceptor for search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchService server but before - it is returned to user code. + it is returned to user code. This `post_search` interceptor runs + before the `post_search_with_metadata` interceptor. """ return response + def post_search_with_metadata( + self, + response: search_service.SearchResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[search_service.SearchResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchService server but before it is returned to user code. + + We recommend only using this `post_search_with_metadata` + interceptor in new development instead of the `post_search` interceptor. + When both interceptors are used, this `post_search_with_metadata` interceptor runs after the + `post_search` interceptor. The (possibly modified) response returned by + `post_search` will be passed to + `post_search_with_metadata`. + """ + return response, metadata + def pre_search_lite( self, request: search_service.SearchRequest, @@ -132,12 +155,35 @@ def post_search_lite( ) -> search_service.SearchResponse: """Post-rpc interceptor for search_lite - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_lite_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchService server but before - it is returned to user code. + it is returned to user code. This `post_search_lite` interceptor runs + before the `post_search_lite_with_metadata` interceptor. """ return response + def post_search_lite_with_metadata( + self, + response: search_service.SearchResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[search_service.SearchResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search_lite + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchService server but before it is returned to user code. + + We recommend only using this `post_search_lite_with_metadata` + interceptor in new development instead of the `post_search_lite` interceptor. + When both interceptors are used, this `post_search_lite_with_metadata` interceptor runs after the + `post_search_lite` interceptor. The (possibly modified) response returned by + `post_search_lite` will be passed to + `post_search_lite_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -428,6 +474,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -585,6 +635,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_lite(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_lite_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_tuning_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_tuning_service/client.py index c5e377e3a91f..34f4d69f35be 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_tuning_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_tuning_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -515,6 +517,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -968,16 +997,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1023,16 +1056,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_tuning_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_tuning_service/transports/rest.py index 9d8d10a495be..54b9defa25f1 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_tuning_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/search_tuning_service/transports/rest.py @@ -112,12 +112,38 @@ def post_list_custom_models( ) -> search_tuning_service.ListCustomModelsResponse: """Post-rpc interceptor for list_custom_models - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_custom_models_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchTuningService server but before - it is returned to user code. + it is returned to user code. This `post_list_custom_models` interceptor runs + before the `post_list_custom_models_with_metadata` interceptor. """ return response + def post_list_custom_models_with_metadata( + self, + response: search_tuning_service.ListCustomModelsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + search_tuning_service.ListCustomModelsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_custom_models + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchTuningService server but before it is returned to user code. + + We recommend only using this `post_list_custom_models_with_metadata` + interceptor in new development instead of the `post_list_custom_models` interceptor. + When both interceptors are used, this `post_list_custom_models_with_metadata` interceptor runs after the + `post_list_custom_models` interceptor. The (possibly modified) response returned by + `post_list_custom_models` will be passed to + `post_list_custom_models_with_metadata`. + """ + return response, metadata + def pre_train_custom_model( self, request: search_tuning_service.TrainCustomModelRequest, @@ -138,12 +164,35 @@ def post_train_custom_model( ) -> operations_pb2.Operation: """Post-rpc interceptor for train_custom_model - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_train_custom_model_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchTuningService server but before - it is returned to user code. + it is returned to user code. This `post_train_custom_model` interceptor runs + before the `post_train_custom_model_with_metadata` interceptor. """ return response + def post_train_custom_model_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for train_custom_model + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchTuningService server but before it is returned to user code. + + We recommend only using this `post_train_custom_model_with_metadata` + interceptor in new development instead of the `post_train_custom_model` interceptor. + When both interceptors are used, this `post_train_custom_model_with_metadata` interceptor runs after the + `post_train_custom_model` interceptor. The (possibly modified) response returned by + `post_train_custom_model` will be passed to + `post_train_custom_model_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -607,6 +656,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_custom_models(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_custom_models_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -761,6 +814,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_train_custom_model(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_train_custom_model_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/site_search_engine_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/site_search_engine_service/client.py index f4ab9ab7f612..a5cbd3d6ac64 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/site_search_engine_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/site_search_engine_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -520,6 +522,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2229,16 +2258,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2284,16 +2317,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/site_search_engine_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/site_search_engine_service/transports/rest.py index 47d095386599..e91563826a8a 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/site_search_engine_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/site_search_engine_service/transports/rest.py @@ -195,12 +195,35 @@ def post_batch_create_target_sites( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_create_target_sites - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_create_target_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_batch_create_target_sites` interceptor runs + before the `post_batch_create_target_sites_with_metadata` interceptor. """ return response + def post_batch_create_target_sites_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_create_target_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_batch_create_target_sites_with_metadata` + interceptor in new development instead of the `post_batch_create_target_sites` interceptor. + When both interceptors are used, this `post_batch_create_target_sites_with_metadata` interceptor runs after the + `post_batch_create_target_sites` interceptor. The (possibly modified) response returned by + `post_batch_create_target_sites` will be passed to + `post_batch_create_target_sites_with_metadata`. + """ + return response, metadata + def pre_batch_verify_target_sites( self, request: site_search_engine_service.BatchVerifyTargetSitesRequest, @@ -221,12 +244,35 @@ def post_batch_verify_target_sites( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_verify_target_sites - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_verify_target_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_batch_verify_target_sites` interceptor runs + before the `post_batch_verify_target_sites_with_metadata` interceptor. """ return response + def post_batch_verify_target_sites_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_verify_target_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_batch_verify_target_sites_with_metadata` + interceptor in new development instead of the `post_batch_verify_target_sites` interceptor. + When both interceptors are used, this `post_batch_verify_target_sites_with_metadata` interceptor runs after the + `post_batch_verify_target_sites` interceptor. The (possibly modified) response returned by + `post_batch_verify_target_sites` will be passed to + `post_batch_verify_target_sites_with_metadata`. + """ + return response, metadata + def pre_create_target_site( self, request: site_search_engine_service.CreateTargetSiteRequest, @@ -247,12 +293,35 @@ def post_create_target_site( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_create_target_site` interceptor runs + before the `post_create_target_site_with_metadata` interceptor. """ return response + def post_create_target_site_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_create_target_site_with_metadata` + interceptor in new development instead of the `post_create_target_site` interceptor. + When both interceptors are used, this `post_create_target_site_with_metadata` interceptor runs after the + `post_create_target_site` interceptor. The (possibly modified) response returned by + `post_create_target_site` will be passed to + `post_create_target_site_with_metadata`. + """ + return response, metadata + def pre_delete_target_site( self, request: site_search_engine_service.DeleteTargetSiteRequest, @@ -273,12 +342,35 @@ def post_delete_target_site( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_delete_target_site` interceptor runs + before the `post_delete_target_site_with_metadata` interceptor. """ return response + def post_delete_target_site_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_delete_target_site_with_metadata` + interceptor in new development instead of the `post_delete_target_site` interceptor. + When both interceptors are used, this `post_delete_target_site_with_metadata` interceptor runs after the + `post_delete_target_site` interceptor. The (possibly modified) response returned by + `post_delete_target_site` will be passed to + `post_delete_target_site_with_metadata`. + """ + return response, metadata + def pre_disable_advanced_site_search( self, request: site_search_engine_service.DisableAdvancedSiteSearchRequest, @@ -299,12 +391,35 @@ def post_disable_advanced_site_search( ) -> operations_pb2.Operation: """Post-rpc interceptor for disable_advanced_site_search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_disable_advanced_site_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_disable_advanced_site_search` interceptor runs + before the `post_disable_advanced_site_search_with_metadata` interceptor. """ return response + def post_disable_advanced_site_search_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for disable_advanced_site_search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_disable_advanced_site_search_with_metadata` + interceptor in new development instead of the `post_disable_advanced_site_search` interceptor. + When both interceptors are used, this `post_disable_advanced_site_search_with_metadata` interceptor runs after the + `post_disable_advanced_site_search` interceptor. The (possibly modified) response returned by + `post_disable_advanced_site_search` will be passed to + `post_disable_advanced_site_search_with_metadata`. + """ + return response, metadata + def pre_enable_advanced_site_search( self, request: site_search_engine_service.EnableAdvancedSiteSearchRequest, @@ -325,12 +440,35 @@ def post_enable_advanced_site_search( ) -> operations_pb2.Operation: """Post-rpc interceptor for enable_advanced_site_search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_enable_advanced_site_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_enable_advanced_site_search` interceptor runs + before the `post_enable_advanced_site_search_with_metadata` interceptor. """ return response + def post_enable_advanced_site_search_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for enable_advanced_site_search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_enable_advanced_site_search_with_metadata` + interceptor in new development instead of the `post_enable_advanced_site_search` interceptor. + When both interceptors are used, this `post_enable_advanced_site_search_with_metadata` interceptor runs after the + `post_enable_advanced_site_search` interceptor. The (possibly modified) response returned by + `post_enable_advanced_site_search` will be passed to + `post_enable_advanced_site_search_with_metadata`. + """ + return response, metadata + def pre_fetch_domain_verification_status( self, request: site_search_engine_service.FetchDomainVerificationStatusRequest, @@ -351,12 +489,38 @@ def post_fetch_domain_verification_status( ) -> site_search_engine_service.FetchDomainVerificationStatusResponse: """Post-rpc interceptor for fetch_domain_verification_status - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_domain_verification_status_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_fetch_domain_verification_status` interceptor runs + before the `post_fetch_domain_verification_status_with_metadata` interceptor. """ return response + def post_fetch_domain_verification_status_with_metadata( + self, + response: site_search_engine_service.FetchDomainVerificationStatusResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine_service.FetchDomainVerificationStatusResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for fetch_domain_verification_status + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_fetch_domain_verification_status_with_metadata` + interceptor in new development instead of the `post_fetch_domain_verification_status` interceptor. + When both interceptors are used, this `post_fetch_domain_verification_status_with_metadata` interceptor runs after the + `post_fetch_domain_verification_status` interceptor. The (possibly modified) response returned by + `post_fetch_domain_verification_status` will be passed to + `post_fetch_domain_verification_status_with_metadata`. + """ + return response, metadata + def pre_get_site_search_engine( self, request: site_search_engine_service.GetSiteSearchEngineRequest, @@ -377,12 +541,37 @@ def post_get_site_search_engine( ) -> site_search_engine.SiteSearchEngine: """Post-rpc interceptor for get_site_search_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_site_search_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_site_search_engine` interceptor runs + before the `post_get_site_search_engine_with_metadata` interceptor. """ return response + def post_get_site_search_engine_with_metadata( + self, + response: site_search_engine.SiteSearchEngine, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine.SiteSearchEngine, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_site_search_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_get_site_search_engine_with_metadata` + interceptor in new development instead of the `post_get_site_search_engine` interceptor. + When both interceptors are used, this `post_get_site_search_engine_with_metadata` interceptor runs after the + `post_get_site_search_engine` interceptor. The (possibly modified) response returned by + `post_get_site_search_engine` will be passed to + `post_get_site_search_engine_with_metadata`. + """ + return response, metadata + def pre_get_target_site( self, request: site_search_engine_service.GetTargetSiteRequest, @@ -403,12 +592,35 @@ def post_get_target_site( ) -> site_search_engine.TargetSite: """Post-rpc interceptor for get_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_target_site` interceptor runs + before the `post_get_target_site_with_metadata` interceptor. """ return response + def post_get_target_site_with_metadata( + self, + response: site_search_engine.TargetSite, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_search_engine.TargetSite, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_get_target_site_with_metadata` + interceptor in new development instead of the `post_get_target_site` interceptor. + When both interceptors are used, this `post_get_target_site_with_metadata` interceptor runs after the + `post_get_target_site` interceptor. The (possibly modified) response returned by + `post_get_target_site` will be passed to + `post_get_target_site_with_metadata`. + """ + return response, metadata + def pre_list_target_sites( self, request: site_search_engine_service.ListTargetSitesRequest, @@ -429,12 +641,38 @@ def post_list_target_sites( ) -> site_search_engine_service.ListTargetSitesResponse: """Post-rpc interceptor for list_target_sites - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_target_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_list_target_sites` interceptor runs + before the `post_list_target_sites_with_metadata` interceptor. """ return response + def post_list_target_sites_with_metadata( + self, + response: site_search_engine_service.ListTargetSitesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine_service.ListTargetSitesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_target_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_list_target_sites_with_metadata` + interceptor in new development instead of the `post_list_target_sites` interceptor. + When both interceptors are used, this `post_list_target_sites_with_metadata` interceptor runs after the + `post_list_target_sites` interceptor. The (possibly modified) response returned by + `post_list_target_sites` will be passed to + `post_list_target_sites_with_metadata`. + """ + return response, metadata + def pre_recrawl_uris( self, request: site_search_engine_service.RecrawlUrisRequest, @@ -455,12 +693,35 @@ def post_recrawl_uris( ) -> operations_pb2.Operation: """Post-rpc interceptor for recrawl_uris - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_recrawl_uris_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_recrawl_uris` interceptor runs + before the `post_recrawl_uris_with_metadata` interceptor. """ return response + def post_recrawl_uris_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for recrawl_uris + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_recrawl_uris_with_metadata` + interceptor in new development instead of the `post_recrawl_uris` interceptor. + When both interceptors are used, this `post_recrawl_uris_with_metadata` interceptor runs after the + `post_recrawl_uris` interceptor. The (possibly modified) response returned by + `post_recrawl_uris` will be passed to + `post_recrawl_uris_with_metadata`. + """ + return response, metadata + def pre_update_target_site( self, request: site_search_engine_service.UpdateTargetSiteRequest, @@ -481,12 +742,35 @@ def post_update_target_site( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_update_target_site` interceptor runs + before the `post_update_target_site_with_metadata` interceptor. """ return response + def post_update_target_site_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_update_target_site_with_metadata` + interceptor in new development instead of the `post_update_target_site` interceptor. + When both interceptors are used, this `post_update_target_site_with_metadata` interceptor runs after the + `post_update_target_site` interceptor. The (possibly modified) response returned by + `post_update_target_site` will be passed to + `post_update_target_site_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -954,6 +1238,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_create_target_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_target_sites_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1106,6 +1394,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_verify_target_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_verify_target_sites_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1260,6 +1552,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1408,6 +1704,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1563,6 +1863,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_disable_advanced_site_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_disable_advanced_site_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1716,6 +2020,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_enable_advanced_site_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_enable_advanced_site_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1871,6 +2179,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_domain_verification_status(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_fetch_domain_verification_status_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2024,6 +2339,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_site_search_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_site_search_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2173,6 +2492,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2323,6 +2646,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_target_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_target_sites_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2477,6 +2804,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_recrawl_uris(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_recrawl_uris_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2631,6 +2962,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/user_event_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/user_event_service/client.py index 1fe7caa085df..3f6297d88125 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/user_event_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/user_event_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -549,6 +551,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1245,16 +1274,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1300,16 +1333,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/user_event_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/user_event_service/transports/rest.py index 0c2f6955f404..ca635d0a5725 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/user_event_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1/services/user_event_service/transports/rest.py @@ -134,12 +134,35 @@ def post_collect_user_event( ) -> httpbody_pb2.HttpBody: """Post-rpc interceptor for collect_user_event - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_collect_user_event_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_collect_user_event` interceptor runs + before the `post_collect_user_event_with_metadata` interceptor. """ return response + def post_collect_user_event_with_metadata( + self, + response: httpbody_pb2.HttpBody, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[httpbody_pb2.HttpBody, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for collect_user_event + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_collect_user_event_with_metadata` + interceptor in new development instead of the `post_collect_user_event` interceptor. + When both interceptors are used, this `post_collect_user_event_with_metadata` interceptor runs after the + `post_collect_user_event` interceptor. The (possibly modified) response returned by + `post_collect_user_event` will be passed to + `post_collect_user_event_with_metadata`. + """ + return response, metadata + def pre_import_user_events( self, request: import_config.ImportUserEventsRequest, @@ -159,12 +182,35 @@ def post_import_user_events( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_user_events - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_user_events_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_import_user_events` interceptor runs + before the `post_import_user_events_with_metadata` interceptor. """ return response + def post_import_user_events_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_user_events + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_import_user_events_with_metadata` + interceptor in new development instead of the `post_import_user_events` interceptor. + When both interceptors are used, this `post_import_user_events_with_metadata` interceptor runs after the + `post_import_user_events` interceptor. The (possibly modified) response returned by + `post_import_user_events` will be passed to + `post_import_user_events_with_metadata`. + """ + return response, metadata + def pre_purge_user_events( self, request: purge_config.PurgeUserEventsRequest, @@ -184,12 +230,35 @@ def post_purge_user_events( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_user_events - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_user_events_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_purge_user_events` interceptor runs + before the `post_purge_user_events_with_metadata` interceptor. """ return response + def post_purge_user_events_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_user_events + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_purge_user_events_with_metadata` + interceptor in new development instead of the `post_purge_user_events` interceptor. + When both interceptors are used, this `post_purge_user_events_with_metadata` interceptor runs after the + `post_purge_user_events` interceptor. The (possibly modified) response returned by + `post_purge_user_events` will be passed to + `post_purge_user_events_with_metadata`. + """ + return response, metadata + def pre_write_user_event( self, request: user_event_service.WriteUserEventRequest, @@ -210,12 +279,35 @@ def post_write_user_event( ) -> user_event.UserEvent: """Post-rpc interceptor for write_user_event - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_write_user_event_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_write_user_event` interceptor runs + before the `post_write_user_event_with_metadata` interceptor. """ return response + def post_write_user_event_with_metadata( + self, + response: user_event.UserEvent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[user_event.UserEvent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for write_user_event + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_write_user_event_with_metadata` + interceptor in new development instead of the `post_write_user_event` interceptor. + When both interceptors are used, this `post_write_user_event_with_metadata` interceptor runs after the + `post_write_user_event` interceptor. The (possibly modified) response returned by + `post_write_user_event` will be passed to + `post_write_user_event_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -725,6 +817,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_collect_user_event(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_collect_user_event_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -876,6 +972,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_user_events(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_user_events_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1027,6 +1127,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_user_events(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_purge_user_events_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1180,6 +1284,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_write_user_event(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_write_user_event_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/gapic_version.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/gapic_version.py index 458413f5c30f..558c8aab67c5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/gapic_version.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/acl_config_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/acl_config_service/client.py index 918f2fdf61cf..f41c2fe62140 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/acl_config_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/acl_config_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -487,6 +489,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -941,16 +970,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -996,16 +1029,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/acl_config_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/acl_config_service/transports/rest.py index 726dcae7e136..23723a13f14a 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/acl_config_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/acl_config_service/transports/rest.py @@ -111,12 +111,35 @@ def post_get_acl_config( ) -> acl_config.AclConfig: """Post-rpc interceptor for get_acl_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_acl_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AclConfigService server but before - it is returned to user code. + it is returned to user code. This `post_get_acl_config` interceptor runs + before the `post_get_acl_config_with_metadata` interceptor. """ return response + def post_get_acl_config_with_metadata( + self, + response: acl_config.AclConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[acl_config.AclConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_acl_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AclConfigService server but before it is returned to user code. + + We recommend only using this `post_get_acl_config_with_metadata` + interceptor in new development instead of the `post_get_acl_config` interceptor. + When both interceptors are used, this `post_get_acl_config_with_metadata` interceptor runs after the + `post_get_acl_config` interceptor. The (possibly modified) response returned by + `post_get_acl_config` will be passed to + `post_get_acl_config_with_metadata`. + """ + return response, metadata + def pre_update_acl_config( self, request: acl_config_service.UpdateAclConfigRequest, @@ -137,12 +160,35 @@ def post_update_acl_config( ) -> acl_config.AclConfig: """Post-rpc interceptor for update_acl_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_acl_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the AclConfigService server but before - it is returned to user code. + it is returned to user code. This `post_update_acl_config` interceptor runs + before the `post_update_acl_config_with_metadata` interceptor. """ return response + def post_update_acl_config_with_metadata( + self, + response: acl_config.AclConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[acl_config.AclConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_acl_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the AclConfigService server but before it is returned to user code. + + We recommend only using this `post_update_acl_config_with_metadata` + interceptor in new development instead of the `post_update_acl_config` interceptor. + When both interceptors are used, this `post_update_acl_config_with_metadata` interceptor runs after the + `post_update_acl_config` interceptor. The (possibly modified) response returned by + `post_update_acl_config` will be passed to + `post_update_acl_config_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -421,6 +467,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_acl_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_acl_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -571,6 +621,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_acl_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_acl_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/chunk_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/chunk_service/client.py index f7ee8eca8c23..ea229ac434ec 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/chunk_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/chunk_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -521,6 +523,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1019,16 +1048,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1074,16 +1107,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/chunk_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/chunk_service/transports/rest.py index e59aee5e4361..e8816968c282 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/chunk_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/chunk_service/transports/rest.py @@ -107,12 +107,33 @@ def pre_get_chunk( def post_get_chunk(self, response: chunk.Chunk) -> chunk.Chunk: """Post-rpc interceptor for get_chunk - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_chunk_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ChunkService server but before - it is returned to user code. + it is returned to user code. This `post_get_chunk` interceptor runs + before the `post_get_chunk_with_metadata` interceptor. """ return response + def post_get_chunk_with_metadata( + self, response: chunk.Chunk, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[chunk.Chunk, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_chunk + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ChunkService server but before it is returned to user code. + + We recommend only using this `post_get_chunk_with_metadata` + interceptor in new development instead of the `post_get_chunk` interceptor. + When both interceptors are used, this `post_get_chunk_with_metadata` interceptor runs after the + `post_get_chunk` interceptor. The (possibly modified) response returned by + `post_get_chunk` will be passed to + `post_get_chunk_with_metadata`. + """ + return response, metadata + def pre_list_chunks( self, request: chunk_service.ListChunksRequest, @@ -132,12 +153,37 @@ def post_list_chunks( ) -> chunk_service.ListChunksResponse: """Post-rpc interceptor for list_chunks - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_chunks_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ChunkService server but before - it is returned to user code. + it is returned to user code. This `post_list_chunks` interceptor runs + before the `post_list_chunks_with_metadata` interceptor. """ return response + def post_list_chunks_with_metadata( + self, + response: chunk_service.ListChunksResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + chunk_service.ListChunksResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_chunks + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ChunkService server but before it is returned to user code. + + We recommend only using this `post_list_chunks_with_metadata` + interceptor in new development instead of the `post_list_chunks` interceptor. + When both interceptors are used, this `post_list_chunks_with_metadata` interceptor runs after the + `post_list_chunks` interceptor. The (possibly modified) response returned by + `post_list_chunks` will be passed to + `post_list_chunks_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -424,6 +470,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_chunk(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_chunk_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -573,6 +623,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_chunks(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_chunks_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/completion_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/completion_service/client.py index 4d7f618a5724..7b6ce61a0c43 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/completion_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/completion_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -492,6 +494,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1279,16 +1308,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1334,16 +1367,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/completion_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/completion_service/transports/rest.py index 8699c3653d94..ef7dfa07beeb 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/completion_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/completion_service/transports/rest.py @@ -139,12 +139,38 @@ def post_complete_query( ) -> completion_service.CompleteQueryResponse: """Post-rpc interceptor for complete_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_complete_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_complete_query` interceptor runs + before the `post_complete_query_with_metadata` interceptor. """ return response + def post_complete_query_with_metadata( + self, + response: completion_service.CompleteQueryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + completion_service.CompleteQueryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for complete_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_complete_query_with_metadata` + interceptor in new development instead of the `post_complete_query` interceptor. + When both interceptors are used, this `post_complete_query_with_metadata` interceptor runs after the + `post_complete_query` interceptor. The (possibly modified) response returned by + `post_complete_query` will be passed to + `post_complete_query_with_metadata`. + """ + return response, metadata + def pre_import_completion_suggestions( self, request: import_config.ImportCompletionSuggestionsRequest, @@ -165,12 +191,35 @@ def post_import_completion_suggestions( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_completion_suggestions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_completion_suggestions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_import_completion_suggestions` interceptor runs + before the `post_import_completion_suggestions_with_metadata` interceptor. """ return response + def post_import_completion_suggestions_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_completion_suggestions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_import_completion_suggestions_with_metadata` + interceptor in new development instead of the `post_import_completion_suggestions` interceptor. + When both interceptors are used, this `post_import_completion_suggestions_with_metadata` interceptor runs after the + `post_import_completion_suggestions` interceptor. The (possibly modified) response returned by + `post_import_completion_suggestions` will be passed to + `post_import_completion_suggestions_with_metadata`. + """ + return response, metadata + def pre_import_suggestion_deny_list_entries( self, request: import_config.ImportSuggestionDenyListEntriesRequest, @@ -191,12 +240,35 @@ def post_import_suggestion_deny_list_entries( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_suggestion_deny_list_entries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_suggestion_deny_list_entries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_import_suggestion_deny_list_entries` interceptor runs + before the `post_import_suggestion_deny_list_entries_with_metadata` interceptor. """ return response + def post_import_suggestion_deny_list_entries_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_suggestion_deny_list_entries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_import_suggestion_deny_list_entries_with_metadata` + interceptor in new development instead of the `post_import_suggestion_deny_list_entries` interceptor. + When both interceptors are used, this `post_import_suggestion_deny_list_entries_with_metadata` interceptor runs after the + `post_import_suggestion_deny_list_entries` interceptor. The (possibly modified) response returned by + `post_import_suggestion_deny_list_entries` will be passed to + `post_import_suggestion_deny_list_entries_with_metadata`. + """ + return response, metadata + def pre_purge_completion_suggestions( self, request: purge_config.PurgeCompletionSuggestionsRequest, @@ -217,12 +289,35 @@ def post_purge_completion_suggestions( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_completion_suggestions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_completion_suggestions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_purge_completion_suggestions` interceptor runs + before the `post_purge_completion_suggestions_with_metadata` interceptor. """ return response + def post_purge_completion_suggestions_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_completion_suggestions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_purge_completion_suggestions_with_metadata` + interceptor in new development instead of the `post_purge_completion_suggestions` interceptor. + When both interceptors are used, this `post_purge_completion_suggestions_with_metadata` interceptor runs after the + `post_purge_completion_suggestions` interceptor. The (possibly modified) response returned by + `post_purge_completion_suggestions` will be passed to + `post_purge_completion_suggestions_with_metadata`. + """ + return response, metadata + def pre_purge_suggestion_deny_list_entries( self, request: purge_config.PurgeSuggestionDenyListEntriesRequest, @@ -243,12 +338,35 @@ def post_purge_suggestion_deny_list_entries( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_suggestion_deny_list_entries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_suggestion_deny_list_entries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_purge_suggestion_deny_list_entries` interceptor runs + before the `post_purge_suggestion_deny_list_entries_with_metadata` interceptor. """ return response + def post_purge_suggestion_deny_list_entries_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_suggestion_deny_list_entries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_purge_suggestion_deny_list_entries_with_metadata` + interceptor in new development instead of the `post_purge_suggestion_deny_list_entries` interceptor. + When both interceptors are used, this `post_purge_suggestion_deny_list_entries_with_metadata` interceptor runs after the + `post_purge_suggestion_deny_list_entries` interceptor. The (possibly modified) response returned by + `post_purge_suggestion_deny_list_entries` will be passed to + `post_purge_suggestion_deny_list_entries_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -705,6 +823,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_complete_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_complete_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -860,6 +982,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_completion_suggestions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_import_completion_suggestions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1018,6 +1147,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_suggestion_deny_list_entries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_import_suggestion_deny_list_entries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1171,6 +1307,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_completion_suggestions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_purge_completion_suggestions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1327,6 +1467,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_suggestion_deny_list_entries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_purge_suggestion_deny_list_entries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/control_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/control_service/client.py index 635bf733158a..32b31d756ced 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/control_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/control_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -519,6 +521,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1379,16 +1408,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1434,16 +1467,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/control_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/control_service/transports/rest.py index 328215d3f487..55ebc98b86d9 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/control_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/control_service/transports/rest.py @@ -132,12 +132,35 @@ def pre_create_control( def post_create_control(self, response: gcd_control.Control) -> gcd_control.Control: """Post-rpc interceptor for create_control - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_control_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_create_control` interceptor runs + before the `post_create_control_with_metadata` interceptor. """ return response + def post_create_control_with_metadata( + self, + response: gcd_control.Control, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_control.Control, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_control + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_create_control_with_metadata` + interceptor in new development instead of the `post_create_control` interceptor. + When both interceptors are used, this `post_create_control_with_metadata` interceptor runs after the + `post_create_control` interceptor. The (possibly modified) response returned by + `post_create_control` will be passed to + `post_create_control_with_metadata`. + """ + return response, metadata + def pre_delete_control( self, request: control_service.DeleteControlRequest, @@ -169,12 +192,35 @@ def pre_get_control( def post_get_control(self, response: control.Control) -> control.Control: """Post-rpc interceptor for get_control - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_control_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_get_control` interceptor runs + before the `post_get_control_with_metadata` interceptor. """ return response + def post_get_control_with_metadata( + self, + response: control.Control, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[control.Control, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_control + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_get_control_with_metadata` + interceptor in new development instead of the `post_get_control` interceptor. + When both interceptors are used, this `post_get_control_with_metadata` interceptor runs after the + `post_get_control` interceptor. The (possibly modified) response returned by + `post_get_control` will be passed to + `post_get_control_with_metadata`. + """ + return response, metadata + def pre_list_controls( self, request: control_service.ListControlsRequest, @@ -194,12 +240,37 @@ def post_list_controls( ) -> control_service.ListControlsResponse: """Post-rpc interceptor for list_controls - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_controls_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_list_controls` interceptor runs + before the `post_list_controls_with_metadata` interceptor. """ return response + def post_list_controls_with_metadata( + self, + response: control_service.ListControlsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + control_service.ListControlsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_controls + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_list_controls_with_metadata` + interceptor in new development instead of the `post_list_controls` interceptor. + When both interceptors are used, this `post_list_controls_with_metadata` interceptor runs after the + `post_list_controls` interceptor. The (possibly modified) response returned by + `post_list_controls` will be passed to + `post_list_controls_with_metadata`. + """ + return response, metadata + def pre_update_control( self, request: control_service.UpdateControlRequest, @@ -217,12 +288,35 @@ def pre_update_control( def post_update_control(self, response: gcd_control.Control) -> gcd_control.Control: """Post-rpc interceptor for update_control - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_control_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_update_control` interceptor runs + before the `post_update_control_with_metadata` interceptor. """ return response + def post_update_control_with_metadata( + self, + response: gcd_control.Control, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_control.Control, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_control + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_update_control_with_metadata` + interceptor in new development instead of the `post_update_control` interceptor. + When both interceptors are used, this `post_update_control_with_metadata` interceptor runs after the + `post_update_control` interceptor. The (possibly modified) response returned by + `post_update_control` will be passed to + `post_update_control_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -514,6 +608,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_control(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_control_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -767,6 +865,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_control(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_control_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -907,6 +1009,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_controls(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_controls_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1060,6 +1166,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_control(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_control_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/conversational_search_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/conversational_search_service/client.py index 93bb1c4b7184..9d925b66b803 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/conversational_search_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/conversational_search_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -657,6 +659,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2392,16 +2421,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2447,16 +2480,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/conversational_search_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/conversational_search_service/transports/rest.py index 5c8af6b0c029..afa86200b662 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/conversational_search_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/conversational_search_service/transports/rest.py @@ -198,12 +198,38 @@ def post_answer_query( ) -> conversational_search_service.AnswerQueryResponse: """Post-rpc interceptor for answer_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_answer_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_answer_query` interceptor runs + before the `post_answer_query_with_metadata` interceptor. """ return response + def post_answer_query_with_metadata( + self, + response: conversational_search_service.AnswerQueryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.AnswerQueryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for answer_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_answer_query_with_metadata` + interceptor in new development instead of the `post_answer_query` interceptor. + When both interceptors are used, this `post_answer_query_with_metadata` interceptor runs after the + `post_answer_query` interceptor. The (possibly modified) response returned by + `post_answer_query` will be passed to + `post_answer_query_with_metadata`. + """ + return response, metadata + def pre_converse_conversation( self, request: conversational_search_service.ConverseConversationRequest, @@ -224,12 +250,38 @@ def post_converse_conversation( ) -> conversational_search_service.ConverseConversationResponse: """Post-rpc interceptor for converse_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_converse_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_converse_conversation` interceptor runs + before the `post_converse_conversation_with_metadata` interceptor. """ return response + def post_converse_conversation_with_metadata( + self, + response: conversational_search_service.ConverseConversationResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.ConverseConversationResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for converse_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_converse_conversation_with_metadata` + interceptor in new development instead of the `post_converse_conversation` interceptor. + When both interceptors are used, this `post_converse_conversation_with_metadata` interceptor runs after the + `post_converse_conversation` interceptor. The (possibly modified) response returned by + `post_converse_conversation` will be passed to + `post_converse_conversation_with_metadata`. + """ + return response, metadata + def pre_create_conversation( self, request: conversational_search_service.CreateConversationRequest, @@ -250,12 +302,35 @@ def post_create_conversation( ) -> gcd_conversation.Conversation: """Post-rpc interceptor for create_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation` interceptor runs + before the `post_create_conversation_with_metadata` interceptor. """ return response + def post_create_conversation_with_metadata( + self, + response: gcd_conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_create_conversation_with_metadata` + interceptor in new development instead of the `post_create_conversation` interceptor. + When both interceptors are used, this `post_create_conversation_with_metadata` interceptor runs after the + `post_create_conversation` interceptor. The (possibly modified) response returned by + `post_create_conversation` will be passed to + `post_create_conversation_with_metadata`. + """ + return response, metadata + def pre_create_session( self, request: conversational_search_service.CreateSessionRequest, @@ -274,12 +349,35 @@ def pre_create_session( def post_create_session(self, response: gcd_session.Session) -> gcd_session.Session: """Post-rpc interceptor for create_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_create_session` interceptor runs + before the `post_create_session_with_metadata` interceptor. """ return response + def post_create_session_with_metadata( + self, + response: gcd_session.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_session.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_create_session_with_metadata` + interceptor in new development instead of the `post_create_session` interceptor. + When both interceptors are used, this `post_create_session_with_metadata` interceptor runs after the + `post_create_session` interceptor. The (possibly modified) response returned by + `post_create_session` will be passed to + `post_create_session_with_metadata`. + """ + return response, metadata + def pre_delete_conversation( self, request: conversational_search_service.DeleteConversationRequest, @@ -328,12 +426,33 @@ def pre_get_answer( def post_get_answer(self, response: answer.Answer) -> answer.Answer: """Post-rpc interceptor for get_answer - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_answer_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_get_answer` interceptor runs + before the `post_get_answer_with_metadata` interceptor. """ return response + def post_get_answer_with_metadata( + self, response: answer.Answer, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[answer.Answer, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_answer + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_get_answer_with_metadata` + interceptor in new development instead of the `post_get_answer` interceptor. + When both interceptors are used, this `post_get_answer_with_metadata` interceptor runs after the + `post_get_answer` interceptor. The (possibly modified) response returned by + `post_get_answer` will be passed to + `post_get_answer_with_metadata`. + """ + return response, metadata + def pre_get_conversation( self, request: conversational_search_service.GetConversationRequest, @@ -354,12 +473,35 @@ def post_get_conversation( ) -> conversation.Conversation: """Post-rpc interceptor for get_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation` interceptor runs + before the `post_get_conversation_with_metadata` interceptor. """ return response + def post_get_conversation_with_metadata( + self, + response: conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_get_conversation_with_metadata` + interceptor in new development instead of the `post_get_conversation` interceptor. + When both interceptors are used, this `post_get_conversation_with_metadata` interceptor runs after the + `post_get_conversation` interceptor. The (possibly modified) response returned by + `post_get_conversation` will be passed to + `post_get_conversation_with_metadata`. + """ + return response, metadata + def pre_get_session( self, request: conversational_search_service.GetSessionRequest, @@ -378,12 +520,35 @@ def pre_get_session( def post_get_session(self, response: session.Session) -> session.Session: """Post-rpc interceptor for get_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_get_session` interceptor runs + before the `post_get_session_with_metadata` interceptor. """ return response + def post_get_session_with_metadata( + self, + response: session.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_get_session_with_metadata` + interceptor in new development instead of the `post_get_session` interceptor. + When both interceptors are used, this `post_get_session_with_metadata` interceptor runs after the + `post_get_session` interceptor. The (possibly modified) response returned by + `post_get_session` will be passed to + `post_get_session_with_metadata`. + """ + return response, metadata + def pre_list_conversations( self, request: conversational_search_service.ListConversationsRequest, @@ -404,12 +569,38 @@ def post_list_conversations( ) -> conversational_search_service.ListConversationsResponse: """Post-rpc interceptor for list_conversations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_list_conversations` interceptor runs + before the `post_list_conversations_with_metadata` interceptor. """ return response + def post_list_conversations_with_metadata( + self, + response: conversational_search_service.ListConversationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.ListConversationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_conversations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_list_conversations_with_metadata` + interceptor in new development instead of the `post_list_conversations` interceptor. + When both interceptors are used, this `post_list_conversations_with_metadata` interceptor runs after the + `post_list_conversations` interceptor. The (possibly modified) response returned by + `post_list_conversations` will be passed to + `post_list_conversations_with_metadata`. + """ + return response, metadata + def pre_list_sessions( self, request: conversational_search_service.ListSessionsRequest, @@ -430,12 +621,38 @@ def post_list_sessions( ) -> conversational_search_service.ListSessionsResponse: """Post-rpc interceptor for list_sessions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_sessions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_list_sessions` interceptor runs + before the `post_list_sessions_with_metadata` interceptor. """ return response + def post_list_sessions_with_metadata( + self, + response: conversational_search_service.ListSessionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.ListSessionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_sessions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_list_sessions_with_metadata` + interceptor in new development instead of the `post_list_sessions` interceptor. + When both interceptors are used, this `post_list_sessions_with_metadata` interceptor runs after the + `post_list_sessions` interceptor. The (possibly modified) response returned by + `post_list_sessions` will be passed to + `post_list_sessions_with_metadata`. + """ + return response, metadata + def pre_update_conversation( self, request: conversational_search_service.UpdateConversationRequest, @@ -456,12 +673,35 @@ def post_update_conversation( ) -> gcd_conversation.Conversation: """Post-rpc interceptor for update_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_update_conversation` interceptor runs + before the `post_update_conversation_with_metadata` interceptor. """ return response + def post_update_conversation_with_metadata( + self, + response: gcd_conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_update_conversation_with_metadata` + interceptor in new development instead of the `post_update_conversation` interceptor. + When both interceptors are used, this `post_update_conversation_with_metadata` interceptor runs after the + `post_update_conversation` interceptor. The (possibly modified) response returned by + `post_update_conversation` will be passed to + `post_update_conversation_with_metadata`. + """ + return response, metadata + def pre_update_session( self, request: conversational_search_service.UpdateSessionRequest, @@ -480,12 +720,35 @@ def pre_update_session( def post_update_session(self, response: gcd_session.Session) -> gcd_session.Session: """Post-rpc interceptor for update_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_update_session` interceptor runs + before the `post_update_session_with_metadata` interceptor. """ return response + def post_update_session_with_metadata( + self, + response: gcd_session.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_session.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_update_session_with_metadata` + interceptor in new development instead of the `post_update_session` interceptor. + When both interceptors are used, this `post_update_session_with_metadata` interceptor runs after the + `post_update_session` interceptor. The (possibly modified) response returned by + `post_update_session` will be passed to + `post_update_session_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -779,6 +1042,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_answer_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_answer_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -939,6 +1206,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_converse_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_converse_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1093,6 +1364,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1242,6 +1517,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1604,6 +1883,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_answer(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_answer_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1751,6 +2034,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1894,6 +2181,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2039,6 +2330,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2186,6 +2481,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_sessions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sessions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2342,6 +2641,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2491,6 +2794,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/data_store_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/data_store_service/client.py index 8d406ec85e0e..c3971eb3d937 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/data_store_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/data_store_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -573,6 +575,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1800,16 +1829,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1855,16 +1888,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/data_store_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/data_store_service/transports/rest.py index 517ce2a29575..800edaea0d33 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/data_store_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/data_store_service/transports/rest.py @@ -158,12 +158,35 @@ def post_create_data_store( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_create_data_store` interceptor runs + before the `post_create_data_store_with_metadata` interceptor. """ return response + def post_create_data_store_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_create_data_store_with_metadata` + interceptor in new development instead of the `post_create_data_store` interceptor. + When both interceptors are used, this `post_create_data_store_with_metadata` interceptor runs after the + `post_create_data_store` interceptor. The (possibly modified) response returned by + `post_create_data_store` will be passed to + `post_create_data_store_with_metadata`. + """ + return response, metadata + def pre_delete_data_store( self, request: data_store_service.DeleteDataStoreRequest, @@ -184,12 +207,35 @@ def post_delete_data_store( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_delete_data_store` interceptor runs + before the `post_delete_data_store_with_metadata` interceptor. """ return response + def post_delete_data_store_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_delete_data_store_with_metadata` + interceptor in new development instead of the `post_delete_data_store` interceptor. + When both interceptors are used, this `post_delete_data_store_with_metadata` interceptor runs after the + `post_delete_data_store` interceptor. The (possibly modified) response returned by + `post_delete_data_store` will be passed to + `post_delete_data_store_with_metadata`. + """ + return response, metadata + def pre_get_data_store( self, request: data_store_service.GetDataStoreRequest, @@ -209,12 +255,35 @@ def post_get_data_store( ) -> data_store.DataStore: """Post-rpc interceptor for get_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_get_data_store` interceptor runs + before the `post_get_data_store_with_metadata` interceptor. """ return response + def post_get_data_store_with_metadata( + self, + response: data_store.DataStore, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[data_store.DataStore, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_get_data_store_with_metadata` + interceptor in new development instead of the `post_get_data_store` interceptor. + When both interceptors are used, this `post_get_data_store_with_metadata` interceptor runs after the + `post_get_data_store` interceptor. The (possibly modified) response returned by + `post_get_data_store` will be passed to + `post_get_data_store_with_metadata`. + """ + return response, metadata + def pre_get_document_processing_config( self, request: data_store_service.GetDocumentProcessingConfigRequest, @@ -235,12 +304,38 @@ def post_get_document_processing_config( ) -> document_processing_config.DocumentProcessingConfig: """Post-rpc interceptor for get_document_processing_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_document_processing_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_get_document_processing_config` interceptor runs + before the `post_get_document_processing_config_with_metadata` interceptor. """ return response + def post_get_document_processing_config_with_metadata( + self, + response: document_processing_config.DocumentProcessingConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + document_processing_config.DocumentProcessingConfig, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_document_processing_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_get_document_processing_config_with_metadata` + interceptor in new development instead of the `post_get_document_processing_config` interceptor. + When both interceptors are used, this `post_get_document_processing_config_with_metadata` interceptor runs after the + `post_get_document_processing_config` interceptor. The (possibly modified) response returned by + `post_get_document_processing_config` will be passed to + `post_get_document_processing_config_with_metadata`. + """ + return response, metadata + def pre_list_data_stores( self, request: data_store_service.ListDataStoresRequest, @@ -261,12 +356,38 @@ def post_list_data_stores( ) -> data_store_service.ListDataStoresResponse: """Post-rpc interceptor for list_data_stores - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_data_stores_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_list_data_stores` interceptor runs + before the `post_list_data_stores_with_metadata` interceptor. """ return response + def post_list_data_stores_with_metadata( + self, + response: data_store_service.ListDataStoresResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_store_service.ListDataStoresResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_data_stores + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_list_data_stores_with_metadata` + interceptor in new development instead of the `post_list_data_stores` interceptor. + When both interceptors are used, this `post_list_data_stores_with_metadata` interceptor runs after the + `post_list_data_stores` interceptor. The (possibly modified) response returned by + `post_list_data_stores` will be passed to + `post_list_data_stores_with_metadata`. + """ + return response, metadata + def pre_update_data_store( self, request: data_store_service.UpdateDataStoreRequest, @@ -287,12 +408,35 @@ def post_update_data_store( ) -> gcd_data_store.DataStore: """Post-rpc interceptor for update_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_update_data_store` interceptor runs + before the `post_update_data_store_with_metadata` interceptor. """ return response + def post_update_data_store_with_metadata( + self, + response: gcd_data_store.DataStore, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_data_store.DataStore, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_update_data_store_with_metadata` + interceptor in new development instead of the `post_update_data_store` interceptor. + When both interceptors are used, this `post_update_data_store_with_metadata` interceptor runs after the + `post_update_data_store` interceptor. The (possibly modified) response returned by + `post_update_data_store` will be passed to + `post_update_data_store_with_metadata`. + """ + return response, metadata + def pre_update_document_processing_config( self, request: data_store_service.UpdateDocumentProcessingConfigRequest, @@ -313,12 +457,38 @@ def post_update_document_processing_config( ) -> gcd_document_processing_config.DocumentProcessingConfig: """Post-rpc interceptor for update_document_processing_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_document_processing_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_update_document_processing_config` interceptor runs + before the `post_update_document_processing_config_with_metadata` interceptor. """ return response + def post_update_document_processing_config_with_metadata( + self, + response: gcd_document_processing_config.DocumentProcessingConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_document_processing_config.DocumentProcessingConfig, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for update_document_processing_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_update_document_processing_config_with_metadata` + interceptor in new development instead of the `post_update_document_processing_config` interceptor. + When both interceptors are used, this `post_update_document_processing_config_with_metadata` interceptor runs after the + `post_update_document_processing_config` interceptor. The (possibly modified) response returned by + `post_update_document_processing_config` will be passed to + `post_update_document_processing_config_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -783,6 +953,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -929,6 +1103,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1073,6 +1251,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1227,6 +1409,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_document_processing_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_get_document_processing_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1378,6 +1567,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_data_stores(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_data_stores_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1533,6 +1726,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1693,6 +1890,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_document_processing_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_update_document_processing_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/document_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/document_service/client.py index dae45c98012c..f76039ec91a5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/document_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/document_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -553,6 +555,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1912,16 +1941,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1967,16 +2000,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/document_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/document_service/transports/rest.py index dc6056ab8d50..b7fd7d2105d4 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/document_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/document_service/transports/rest.py @@ -171,12 +171,38 @@ def post_batch_get_documents_metadata( ) -> document_service.BatchGetDocumentsMetadataResponse: """Post-rpc interceptor for batch_get_documents_metadata - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_get_documents_metadata_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_batch_get_documents_metadata` interceptor runs + before the `post_batch_get_documents_metadata_with_metadata` interceptor. """ return response + def post_batch_get_documents_metadata_with_metadata( + self, + response: document_service.BatchGetDocumentsMetadataResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + document_service.BatchGetDocumentsMetadataResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_get_documents_metadata + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_batch_get_documents_metadata_with_metadata` + interceptor in new development instead of the `post_batch_get_documents_metadata` interceptor. + When both interceptors are used, this `post_batch_get_documents_metadata_with_metadata` interceptor runs after the + `post_batch_get_documents_metadata` interceptor. The (possibly modified) response returned by + `post_batch_get_documents_metadata` will be passed to + `post_batch_get_documents_metadata_with_metadata`. + """ + return response, metadata + def pre_create_document( self, request: document_service.CreateDocumentRequest, @@ -196,12 +222,35 @@ def post_create_document( ) -> gcd_document.Document: """Post-rpc interceptor for create_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_create_document` interceptor runs + before the `post_create_document_with_metadata` interceptor. """ return response + def post_create_document_with_metadata( + self, + response: gcd_document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_create_document_with_metadata` + interceptor in new development instead of the `post_create_document` interceptor. + When both interceptors are used, this `post_create_document_with_metadata` interceptor runs after the + `post_create_document` interceptor. The (possibly modified) response returned by + `post_create_document` will be passed to + `post_create_document_with_metadata`. + """ + return response, metadata + def pre_delete_document( self, request: document_service.DeleteDocumentRequest, @@ -233,12 +282,35 @@ def pre_get_document( def post_get_document(self, response: document.Document) -> document.Document: """Post-rpc interceptor for get_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_get_document` interceptor runs + before the `post_get_document_with_metadata` interceptor. """ return response + def post_get_document_with_metadata( + self, + response: document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_get_document_with_metadata` + interceptor in new development instead of the `post_get_document` interceptor. + When both interceptors are used, this `post_get_document_with_metadata` interceptor runs after the + `post_get_document` interceptor. The (possibly modified) response returned by + `post_get_document` will be passed to + `post_get_document_with_metadata`. + """ + return response, metadata + def pre_get_processed_document( self, request: document_service.GetProcessedDocumentRequest, @@ -259,12 +331,35 @@ def post_get_processed_document( ) -> document.ProcessedDocument: """Post-rpc interceptor for get_processed_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_processed_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_get_processed_document` interceptor runs + before the `post_get_processed_document_with_metadata` interceptor. """ return response + def post_get_processed_document_with_metadata( + self, + response: document.ProcessedDocument, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[document.ProcessedDocument, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_processed_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_get_processed_document_with_metadata` + interceptor in new development instead of the `post_get_processed_document` interceptor. + When both interceptors are used, this `post_get_processed_document_with_metadata` interceptor runs after the + `post_get_processed_document` interceptor. The (possibly modified) response returned by + `post_get_processed_document` will be passed to + `post_get_processed_document_with_metadata`. + """ + return response, metadata + def pre_import_documents( self, request: import_config.ImportDocumentsRequest, @@ -284,12 +379,35 @@ def post_import_documents( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_import_documents` interceptor runs + before the `post_import_documents_with_metadata` interceptor. """ return response + def post_import_documents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_import_documents_with_metadata` + interceptor in new development instead of the `post_import_documents` interceptor. + When both interceptors are used, this `post_import_documents_with_metadata` interceptor runs after the + `post_import_documents` interceptor. The (possibly modified) response returned by + `post_import_documents` will be passed to + `post_import_documents_with_metadata`. + """ + return response, metadata + def pre_list_documents( self, request: document_service.ListDocumentsRequest, @@ -309,12 +427,37 @@ def post_list_documents( ) -> document_service.ListDocumentsResponse: """Post-rpc interceptor for list_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_list_documents` interceptor runs + before the `post_list_documents_with_metadata` interceptor. """ return response + def post_list_documents_with_metadata( + self, + response: document_service.ListDocumentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + document_service.ListDocumentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_list_documents_with_metadata` + interceptor in new development instead of the `post_list_documents` interceptor. + When both interceptors are used, this `post_list_documents_with_metadata` interceptor runs after the + `post_list_documents` interceptor. The (possibly modified) response returned by + `post_list_documents` will be passed to + `post_list_documents_with_metadata`. + """ + return response, metadata + def pre_purge_documents( self, request: purge_config.PurgeDocumentsRequest, @@ -334,12 +477,35 @@ def post_purge_documents( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_purge_documents` interceptor runs + before the `post_purge_documents_with_metadata` interceptor. """ return response + def post_purge_documents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_purge_documents_with_metadata` + interceptor in new development instead of the `post_purge_documents` interceptor. + When both interceptors are used, this `post_purge_documents_with_metadata` interceptor runs after the + `post_purge_documents` interceptor. The (possibly modified) response returned by + `post_purge_documents` will be passed to + `post_purge_documents_with_metadata`. + """ + return response, metadata + def pre_update_document( self, request: document_service.UpdateDocumentRequest, @@ -359,12 +525,35 @@ def post_update_document( ) -> gcd_document.Document: """Post-rpc interceptor for update_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_update_document` interceptor runs + before the `post_update_document_with_metadata` interceptor. """ return response + def post_update_document_with_metadata( + self, + response: gcd_document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_update_document_with_metadata` + interceptor in new development instead of the `post_update_document` interceptor. + When both interceptors are used, this `post_update_document_with_metadata` interceptor runs after the + `post_update_document` interceptor. The (possibly modified) response returned by + `post_update_document` will be passed to + `post_update_document_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -828,6 +1017,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_get_documents_metadata(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_get_documents_metadata_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -983,6 +1176,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1236,6 +1433,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1384,6 +1585,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_processed_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_processed_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1533,6 +1738,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1678,6 +1887,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1829,6 +2042,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_purge_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1980,6 +2197,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/engine_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/engine_service/client.py index 991c6a051619..0b3439a6aa59 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/engine_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/engine_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -521,6 +523,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1778,16 +1807,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1833,16 +1866,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/engine_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/engine_service/transports/rest.py index 5017fd21f1f4..400c78f3c948 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/engine_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/engine_service/transports/rest.py @@ -161,12 +161,35 @@ def post_create_engine( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_create_engine` interceptor runs + before the `post_create_engine_with_metadata` interceptor. """ return response + def post_create_engine_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_create_engine_with_metadata` + interceptor in new development instead of the `post_create_engine` interceptor. + When both interceptors are used, this `post_create_engine_with_metadata` interceptor runs after the + `post_create_engine` interceptor. The (possibly modified) response returned by + `post_create_engine` will be passed to + `post_create_engine_with_metadata`. + """ + return response, metadata + def pre_delete_engine( self, request: engine_service.DeleteEngineRequest, @@ -186,12 +209,35 @@ def post_delete_engine( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_delete_engine` interceptor runs + before the `post_delete_engine_with_metadata` interceptor. """ return response + def post_delete_engine_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_delete_engine_with_metadata` + interceptor in new development instead of the `post_delete_engine` interceptor. + When both interceptors are used, this `post_delete_engine_with_metadata` interceptor runs after the + `post_delete_engine` interceptor. The (possibly modified) response returned by + `post_delete_engine` will be passed to + `post_delete_engine_with_metadata`. + """ + return response, metadata + def pre_get_engine( self, request: engine_service.GetEngineRequest, @@ -209,12 +255,33 @@ def pre_get_engine( def post_get_engine(self, response: engine.Engine) -> engine.Engine: """Post-rpc interceptor for get_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_engine` interceptor runs + before the `post_get_engine_with_metadata` interceptor. """ return response + def post_get_engine_with_metadata( + self, response: engine.Engine, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_get_engine_with_metadata` + interceptor in new development instead of the `post_get_engine` interceptor. + When both interceptors are used, this `post_get_engine_with_metadata` interceptor runs after the + `post_get_engine` interceptor. The (possibly modified) response returned by + `post_get_engine` will be passed to + `post_get_engine_with_metadata`. + """ + return response, metadata + def pre_list_engines( self, request: engine_service.ListEnginesRequest, @@ -234,12 +301,37 @@ def post_list_engines( ) -> engine_service.ListEnginesResponse: """Post-rpc interceptor for list_engines - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_engines_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_list_engines` interceptor runs + before the `post_list_engines_with_metadata` interceptor. """ return response + def post_list_engines_with_metadata( + self, + response: engine_service.ListEnginesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + engine_service.ListEnginesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_engines + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_list_engines_with_metadata` + interceptor in new development instead of the `post_list_engines` interceptor. + When both interceptors are used, this `post_list_engines_with_metadata` interceptor runs after the + `post_list_engines` interceptor. The (possibly modified) response returned by + `post_list_engines` will be passed to + `post_list_engines_with_metadata`. + """ + return response, metadata + def pre_pause_engine( self, request: engine_service.PauseEngineRequest, @@ -257,12 +349,33 @@ def pre_pause_engine( def post_pause_engine(self, response: engine.Engine) -> engine.Engine: """Post-rpc interceptor for pause_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_pause_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_pause_engine` interceptor runs + before the `post_pause_engine_with_metadata` interceptor. """ return response + def post_pause_engine_with_metadata( + self, response: engine.Engine, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for pause_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_pause_engine_with_metadata` + interceptor in new development instead of the `post_pause_engine` interceptor. + When both interceptors are used, this `post_pause_engine_with_metadata` interceptor runs after the + `post_pause_engine` interceptor. The (possibly modified) response returned by + `post_pause_engine` will be passed to + `post_pause_engine_with_metadata`. + """ + return response, metadata + def pre_resume_engine( self, request: engine_service.ResumeEngineRequest, @@ -280,12 +393,33 @@ def pre_resume_engine( def post_resume_engine(self, response: engine.Engine) -> engine.Engine: """Post-rpc interceptor for resume_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_resume_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_resume_engine` interceptor runs + before the `post_resume_engine_with_metadata` interceptor. """ return response + def post_resume_engine_with_metadata( + self, response: engine.Engine, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for resume_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_resume_engine_with_metadata` + interceptor in new development instead of the `post_resume_engine` interceptor. + When both interceptors are used, this `post_resume_engine_with_metadata` interceptor runs after the + `post_resume_engine` interceptor. The (possibly modified) response returned by + `post_resume_engine` will be passed to + `post_resume_engine_with_metadata`. + """ + return response, metadata + def pre_tune_engine( self, request: engine_service.TuneEngineRequest, @@ -305,12 +439,35 @@ def post_tune_engine( ) -> operations_pb2.Operation: """Post-rpc interceptor for tune_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_tune_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_tune_engine` interceptor runs + before the `post_tune_engine_with_metadata` interceptor. """ return response + def post_tune_engine_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for tune_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_tune_engine_with_metadata` + interceptor in new development instead of the `post_tune_engine` interceptor. + When both interceptors are used, this `post_tune_engine_with_metadata` interceptor runs after the + `post_tune_engine` interceptor. The (possibly modified) response returned by + `post_tune_engine` will be passed to + `post_tune_engine_with_metadata`. + """ + return response, metadata + def pre_update_engine( self, request: engine_service.UpdateEngineRequest, @@ -328,12 +485,35 @@ def pre_update_engine( def post_update_engine(self, response: gcd_engine.Engine) -> gcd_engine.Engine: """Post-rpc interceptor for update_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_update_engine` interceptor runs + before the `post_update_engine_with_metadata` interceptor. """ return response + def post_update_engine_with_metadata( + self, + response: gcd_engine.Engine, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_update_engine_with_metadata` + interceptor in new development instead of the `post_update_engine` interceptor. + When both interceptors are used, this `post_update_engine_with_metadata` interceptor runs after the + `post_update_engine` interceptor. The (possibly modified) response returned by + `post_update_engine` will be passed to + `post_update_engine_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -794,6 +974,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -937,6 +1121,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1086,6 +1274,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1233,6 +1425,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_engines(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_engines_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1389,6 +1585,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_pause_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_pause_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1539,6 +1739,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_resume_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_resume_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1695,6 +1899,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_tune_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_tune_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1846,6 +2054,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/estimate_billing_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/estimate_billing_service/client.py index 4b70618b5684..79a0afbf55c4 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/estimate_billing_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/estimate_billing_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -485,6 +487,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -847,16 +876,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -902,16 +935,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/estimate_billing_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/estimate_billing_service/transports/rest.py index ca7d96da4fd6..442b78676720 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/estimate_billing_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/estimate_billing_service/transports/rest.py @@ -104,12 +104,35 @@ def post_estimate_data_size( ) -> operations_pb2.Operation: """Post-rpc interceptor for estimate_data_size - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_estimate_data_size_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EstimateBillingService server but before - it is returned to user code. + it is returned to user code. This `post_estimate_data_size` interceptor runs + before the `post_estimate_data_size_with_metadata` interceptor. """ return response + def post_estimate_data_size_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for estimate_data_size + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EstimateBillingService server but before it is returned to user code. + + We recommend only using this `post_estimate_data_size_with_metadata` + interceptor in new development instead of the `post_estimate_data_size` interceptor. + When both interceptors are used, this `post_estimate_data_size_with_metadata` interceptor runs after the + `post_estimate_data_size` interceptor. The (possibly modified) response returned by + `post_estimate_data_size` will be passed to + `post_estimate_data_size_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -574,6 +597,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_estimate_data_size(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_estimate_data_size_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/evaluation_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/evaluation_service/client.py index a478f8307575..d0083bc2ee24 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/evaluation_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/evaluation_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -654,6 +656,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1438,16 +1467,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1493,16 +1526,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/evaluation_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/evaluation_service/transports/rest.py index bdcb6826075e..964b6bfc0425 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/evaluation_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/evaluation_service/transports/rest.py @@ -128,12 +128,35 @@ def post_create_evaluation( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_evaluation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_evaluation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EvaluationService server but before - it is returned to user code. + it is returned to user code. This `post_create_evaluation` interceptor runs + before the `post_create_evaluation_with_metadata` interceptor. """ return response + def post_create_evaluation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_evaluation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_create_evaluation_with_metadata` + interceptor in new development instead of the `post_create_evaluation` interceptor. + When both interceptors are used, this `post_create_evaluation_with_metadata` interceptor runs after the + `post_create_evaluation` interceptor. The (possibly modified) response returned by + `post_create_evaluation` will be passed to + `post_create_evaluation_with_metadata`. + """ + return response, metadata + def pre_get_evaluation( self, request: evaluation_service.GetEvaluationRequest, @@ -153,12 +176,35 @@ def post_get_evaluation( ) -> evaluation.Evaluation: """Post-rpc interceptor for get_evaluation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_evaluation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EvaluationService server but before - it is returned to user code. + it is returned to user code. This `post_get_evaluation` interceptor runs + before the `post_get_evaluation_with_metadata` interceptor. """ return response + def post_get_evaluation_with_metadata( + self, + response: evaluation.Evaluation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[evaluation.Evaluation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_evaluation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_get_evaluation_with_metadata` + interceptor in new development instead of the `post_get_evaluation` interceptor. + When both interceptors are used, this `post_get_evaluation_with_metadata` interceptor runs after the + `post_get_evaluation` interceptor. The (possibly modified) response returned by + `post_get_evaluation` will be passed to + `post_get_evaluation_with_metadata`. + """ + return response, metadata + def pre_list_evaluation_results( self, request: evaluation_service.ListEvaluationResultsRequest, @@ -179,12 +225,38 @@ def post_list_evaluation_results( ) -> evaluation_service.ListEvaluationResultsResponse: """Post-rpc interceptor for list_evaluation_results - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_evaluation_results_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EvaluationService server but before - it is returned to user code. + it is returned to user code. This `post_list_evaluation_results` interceptor runs + before the `post_list_evaluation_results_with_metadata` interceptor. """ return response + def post_list_evaluation_results_with_metadata( + self, + response: evaluation_service.ListEvaluationResultsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + evaluation_service.ListEvaluationResultsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_evaluation_results + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_list_evaluation_results_with_metadata` + interceptor in new development instead of the `post_list_evaluation_results` interceptor. + When both interceptors are used, this `post_list_evaluation_results_with_metadata` interceptor runs after the + `post_list_evaluation_results` interceptor. The (possibly modified) response returned by + `post_list_evaluation_results` will be passed to + `post_list_evaluation_results_with_metadata`. + """ + return response, metadata + def pre_list_evaluations( self, request: evaluation_service.ListEvaluationsRequest, @@ -205,12 +277,38 @@ def post_list_evaluations( ) -> evaluation_service.ListEvaluationsResponse: """Post-rpc interceptor for list_evaluations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_evaluations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EvaluationService server but before - it is returned to user code. + it is returned to user code. This `post_list_evaluations` interceptor runs + before the `post_list_evaluations_with_metadata` interceptor. """ return response + def post_list_evaluations_with_metadata( + self, + response: evaluation_service.ListEvaluationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + evaluation_service.ListEvaluationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_evaluations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_list_evaluations_with_metadata` + interceptor in new development instead of the `post_list_evaluations` interceptor. + When both interceptors are used, this `post_list_evaluations_with_metadata` interceptor runs after the + `post_list_evaluations` interceptor. The (possibly modified) response returned by + `post_list_evaluations` will be passed to + `post_list_evaluations_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -674,6 +772,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_evaluation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_evaluation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -821,6 +923,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_evaluation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_evaluation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -971,6 +1077,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_evaluation_results(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_evaluation_results_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1123,6 +1233,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_evaluations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_evaluations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/grounded_generation_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/grounded_generation_service/client.py index 71f9203f5418..0793fbc77a5a 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/grounded_generation_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/grounded_generation_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -491,6 +493,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -841,16 +870,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -896,16 +929,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/grounded_generation_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/grounded_generation_service/transports/rest.py index b116b81a73ba..3fd56ba5c903 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/grounded_generation_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/grounded_generation_service/transports/rest.py @@ -104,12 +104,38 @@ def post_check_grounding( ) -> grounded_generation_service.CheckGroundingResponse: """Post-rpc interceptor for check_grounding - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_check_grounding_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the GroundedGenerationService server but before - it is returned to user code. + it is returned to user code. This `post_check_grounding` interceptor runs + before the `post_check_grounding_with_metadata` interceptor. """ return response + def post_check_grounding_with_metadata( + self, + response: grounded_generation_service.CheckGroundingResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grounded_generation_service.CheckGroundingResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for check_grounding + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the GroundedGenerationService server but before it is returned to user code. + + We recommend only using this `post_check_grounding_with_metadata` + interceptor in new development instead of the `post_check_grounding` interceptor. + When both interceptors are used, this `post_check_grounding_with_metadata` interceptor runs after the + `post_check_grounding` interceptor. The (possibly modified) response returned by + `post_check_grounding` will be passed to + `post_check_grounding_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -403,6 +429,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_check_grounding(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_check_grounding_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/project_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/project_service/client.py index 69a62d2b1fde..c77064ba5d02 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/project_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/project_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -486,6 +488,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1139,16 +1168,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1194,16 +1227,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/project_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/project_service/transports/rest.py index dfed7b617f50..672f0809a5f9 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/project_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/project_service/transports/rest.py @@ -119,12 +119,35 @@ def pre_get_project( def post_get_project(self, response: project.Project) -> project.Project: """Post-rpc interceptor for get_project - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_project_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ProjectService server but before - it is returned to user code. + it is returned to user code. This `post_get_project` interceptor runs + before the `post_get_project_with_metadata` interceptor. """ return response + def post_get_project_with_metadata( + self, + response: project.Project, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[project.Project, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_project + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ProjectService server but before it is returned to user code. + + We recommend only using this `post_get_project_with_metadata` + interceptor in new development instead of the `post_get_project` interceptor. + When both interceptors are used, this `post_get_project_with_metadata` interceptor runs after the + `post_get_project` interceptor. The (possibly modified) response returned by + `post_get_project` will be passed to + `post_get_project_with_metadata`. + """ + return response, metadata + def pre_provision_project( self, request: project_service.ProvisionProjectRequest, @@ -144,12 +167,35 @@ def post_provision_project( ) -> operations_pb2.Operation: """Post-rpc interceptor for provision_project - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_provision_project_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ProjectService server but before - it is returned to user code. + it is returned to user code. This `post_provision_project` interceptor runs + before the `post_provision_project_with_metadata` interceptor. """ return response + def post_provision_project_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for provision_project + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ProjectService server but before it is returned to user code. + + We recommend only using this `post_provision_project_with_metadata` + interceptor in new development instead of the `post_provision_project` interceptor. + When both interceptors are used, this `post_provision_project_with_metadata` interceptor runs after the + `post_provision_project` interceptor. The (possibly modified) response returned by + `post_provision_project` will be passed to + `post_provision_project_with_metadata`. + """ + return response, metadata + def pre_report_consent_change( self, request: project_service.ReportConsentChangeRequest, @@ -170,12 +216,35 @@ def post_report_consent_change( ) -> gcd_project.Project: """Post-rpc interceptor for report_consent_change - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_report_consent_change_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ProjectService server but before - it is returned to user code. + it is returned to user code. This `post_report_consent_change` interceptor runs + before the `post_report_consent_change_with_metadata` interceptor. """ return response + def post_report_consent_change_with_metadata( + self, + response: gcd_project.Project, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_project.Project, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for report_consent_change + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ProjectService server but before it is returned to user code. + + We recommend only using this `post_report_consent_change_with_metadata` + interceptor in new development instead of the `post_report_consent_change` interceptor. + When both interceptors are used, this `post_report_consent_change_with_metadata` interceptor runs after the + `post_report_consent_change` interceptor. The (possibly modified) response returned by + `post_report_consent_change` will be passed to + `post_report_consent_change_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -633,6 +702,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_project(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_project_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -784,6 +857,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_provision_project(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_provision_project_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -936,6 +1013,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_report_consent_change(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_report_consent_change_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/rank_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/rank_service/client.py index d6b5797f9682..91452ffdeefe 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/rank_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/rank_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -484,6 +486,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -823,16 +852,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -878,16 +911,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/rank_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/rank_service/transports/rest.py index 89fd6747b0e4..79b8a40a7ad1 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/rank_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/rank_service/transports/rest.py @@ -101,12 +101,35 @@ def post_rank( ) -> rank_service.RankResponse: """Post-rpc interceptor for rank - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_rank_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the RankService server but before - it is returned to user code. + it is returned to user code. This `post_rank` interceptor runs + before the `post_rank_with_metadata` interceptor. """ return response + def post_rank_with_metadata( + self, + response: rank_service.RankResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[rank_service.RankResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for rank + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the RankService server but before it is returned to user code. + + We recommend only using this `post_rank_with_metadata` + interceptor in new development instead of the `post_rank` interceptor. + When both interceptors are used, this `post_rank_with_metadata` interceptor runs after the + `post_rank` interceptor. The (possibly modified) response returned by + `post_rank` will be passed to + `post_rank_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -395,6 +418,8 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_rank(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_rank_with_metadata(resp, response_metadata) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/recommendation_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/recommendation_service/client.py index 5eeba0346cd3..b3274ab4aaa0 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/recommendation_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/recommendation_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -562,6 +564,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -911,16 +940,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -966,16 +999,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/recommendation_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/recommendation_service/transports/rest.py index 69a77197e128..4c165c141afe 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/recommendation_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/recommendation_service/transports/rest.py @@ -103,12 +103,38 @@ def post_recommend( ) -> recommendation_service.RecommendResponse: """Post-rpc interceptor for recommend - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_recommend_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the RecommendationService server but before - it is returned to user code. + it is returned to user code. This `post_recommend` interceptor runs + before the `post_recommend_with_metadata` interceptor. """ return response + def post_recommend_with_metadata( + self, + response: recommendation_service.RecommendResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + recommendation_service.RecommendResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for recommend + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the RecommendationService server but before it is returned to user code. + + We recommend only using this `post_recommend_with_metadata` + interceptor in new development instead of the `post_recommend` interceptor. + When both interceptors are used, this `post_recommend_with_metadata` interceptor runs after the + `post_recommend` interceptor. The (possibly modified) response returned by + `post_recommend` will be passed to + `post_recommend_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -395,6 +421,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_recommend(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_recommend_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_service/client.py index 7b048b486d3c..31fa66505510 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -520,6 +522,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1540,16 +1569,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1595,16 +1628,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_service/transports/rest.py index d8084dcb7cba..d20ce3d47973 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_service/transports/rest.py @@ -144,12 +144,35 @@ def post_create_sample_query( ) -> gcd_sample_query.SampleQuery: """Post-rpc interceptor for create_sample_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_sample_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_create_sample_query` interceptor runs + before the `post_create_sample_query_with_metadata` interceptor. """ return response + def post_create_sample_query_with_metadata( + self, + response: gcd_sample_query.SampleQuery, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_sample_query.SampleQuery, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_sample_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_create_sample_query_with_metadata` + interceptor in new development instead of the `post_create_sample_query` interceptor. + When both interceptors are used, this `post_create_sample_query_with_metadata` interceptor runs after the + `post_create_sample_query` interceptor. The (possibly modified) response returned by + `post_create_sample_query` will be passed to + `post_create_sample_query_with_metadata`. + """ + return response, metadata + def pre_delete_sample_query( self, request: sample_query_service.DeleteSampleQueryRequest, @@ -185,12 +208,35 @@ def post_get_sample_query( ) -> sample_query.SampleQuery: """Post-rpc interceptor for get_sample_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_sample_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_get_sample_query` interceptor runs + before the `post_get_sample_query_with_metadata` interceptor. """ return response + def post_get_sample_query_with_metadata( + self, + response: sample_query.SampleQuery, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[sample_query.SampleQuery, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_sample_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_get_sample_query_with_metadata` + interceptor in new development instead of the `post_get_sample_query` interceptor. + When both interceptors are used, this `post_get_sample_query_with_metadata` interceptor runs after the + `post_get_sample_query` interceptor. The (possibly modified) response returned by + `post_get_sample_query` will be passed to + `post_get_sample_query_with_metadata`. + """ + return response, metadata + def pre_import_sample_queries( self, request: import_config.ImportSampleQueriesRequest, @@ -211,12 +257,35 @@ def post_import_sample_queries( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_sample_queries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_sample_queries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_import_sample_queries` interceptor runs + before the `post_import_sample_queries_with_metadata` interceptor. """ return response + def post_import_sample_queries_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_sample_queries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_import_sample_queries_with_metadata` + interceptor in new development instead of the `post_import_sample_queries` interceptor. + When both interceptors are used, this `post_import_sample_queries_with_metadata` interceptor runs after the + `post_import_sample_queries` interceptor. The (possibly modified) response returned by + `post_import_sample_queries` will be passed to + `post_import_sample_queries_with_metadata`. + """ + return response, metadata + def pre_list_sample_queries( self, request: sample_query_service.ListSampleQueriesRequest, @@ -237,12 +306,38 @@ def post_list_sample_queries( ) -> sample_query_service.ListSampleQueriesResponse: """Post-rpc interceptor for list_sample_queries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_sample_queries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_list_sample_queries` interceptor runs + before the `post_list_sample_queries_with_metadata` interceptor. """ return response + def post_list_sample_queries_with_metadata( + self, + response: sample_query_service.ListSampleQueriesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + sample_query_service.ListSampleQueriesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_sample_queries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_list_sample_queries_with_metadata` + interceptor in new development instead of the `post_list_sample_queries` interceptor. + When both interceptors are used, this `post_list_sample_queries_with_metadata` interceptor runs after the + `post_list_sample_queries` interceptor. The (possibly modified) response returned by + `post_list_sample_queries` will be passed to + `post_list_sample_queries_with_metadata`. + """ + return response, metadata + def pre_update_sample_query( self, request: sample_query_service.UpdateSampleQueryRequest, @@ -263,12 +358,35 @@ def post_update_sample_query( ) -> gcd_sample_query.SampleQuery: """Post-rpc interceptor for update_sample_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_sample_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_update_sample_query` interceptor runs + before the `post_update_sample_query_with_metadata` interceptor. """ return response + def post_update_sample_query_with_metadata( + self, + response: gcd_sample_query.SampleQuery, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_sample_query.SampleQuery, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_sample_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_update_sample_query_with_metadata` + interceptor in new development instead of the `post_update_sample_query` interceptor. + When both interceptors are used, this `post_update_sample_query_with_metadata` interceptor runs after the + `post_update_sample_query` interceptor. The (possibly modified) response returned by + `post_update_sample_query` will be passed to + `post_update_sample_query_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -733,6 +851,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_sample_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_sample_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -991,6 +1113,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_sample_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_sample_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1145,6 +1271,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_sample_queries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_sample_queries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1293,6 +1423,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_sample_queries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sample_queries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1448,6 +1582,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_sample_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_sample_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_set_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_set_service/client.py index 7c541642e547..8dba3e40cd20 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_set_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_set_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -516,6 +518,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1434,16 +1463,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1489,16 +1522,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_set_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_set_service/transports/rest.py index ce064e1bb6bd..19a90990d89d 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_set_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/sample_query_set_service/transports/rest.py @@ -137,12 +137,37 @@ def post_create_sample_query_set( ) -> gcd_sample_query_set.SampleQuerySet: """Post-rpc interceptor for create_sample_query_set - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_sample_query_set_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQuerySetService server but before - it is returned to user code. + it is returned to user code. This `post_create_sample_query_set` interceptor runs + before the `post_create_sample_query_set_with_metadata` interceptor. """ return response + def post_create_sample_query_set_with_metadata( + self, + response: gcd_sample_query_set.SampleQuerySet, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_sample_query_set.SampleQuerySet, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_sample_query_set + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQuerySetService server but before it is returned to user code. + + We recommend only using this `post_create_sample_query_set_with_metadata` + interceptor in new development instead of the `post_create_sample_query_set` interceptor. + When both interceptors are used, this `post_create_sample_query_set_with_metadata` interceptor runs after the + `post_create_sample_query_set` interceptor. The (possibly modified) response returned by + `post_create_sample_query_set` will be passed to + `post_create_sample_query_set_with_metadata`. + """ + return response, metadata + def pre_delete_sample_query_set( self, request: sample_query_set_service.DeleteSampleQuerySetRequest, @@ -178,12 +203,37 @@ def post_get_sample_query_set( ) -> sample_query_set.SampleQuerySet: """Post-rpc interceptor for get_sample_query_set - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_sample_query_set_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQuerySetService server but before - it is returned to user code. + it is returned to user code. This `post_get_sample_query_set` interceptor runs + before the `post_get_sample_query_set_with_metadata` interceptor. """ return response + def post_get_sample_query_set_with_metadata( + self, + response: sample_query_set.SampleQuerySet, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + sample_query_set.SampleQuerySet, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_sample_query_set + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQuerySetService server but before it is returned to user code. + + We recommend only using this `post_get_sample_query_set_with_metadata` + interceptor in new development instead of the `post_get_sample_query_set` interceptor. + When both interceptors are used, this `post_get_sample_query_set_with_metadata` interceptor runs after the + `post_get_sample_query_set` interceptor. The (possibly modified) response returned by + `post_get_sample_query_set` will be passed to + `post_get_sample_query_set_with_metadata`. + """ + return response, metadata + def pre_list_sample_query_sets( self, request: sample_query_set_service.ListSampleQuerySetsRequest, @@ -204,12 +254,38 @@ def post_list_sample_query_sets( ) -> sample_query_set_service.ListSampleQuerySetsResponse: """Post-rpc interceptor for list_sample_query_sets - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_sample_query_sets_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQuerySetService server but before - it is returned to user code. + it is returned to user code. This `post_list_sample_query_sets` interceptor runs + before the `post_list_sample_query_sets_with_metadata` interceptor. """ return response + def post_list_sample_query_sets_with_metadata( + self, + response: sample_query_set_service.ListSampleQuerySetsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + sample_query_set_service.ListSampleQuerySetsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_sample_query_sets + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQuerySetService server but before it is returned to user code. + + We recommend only using this `post_list_sample_query_sets_with_metadata` + interceptor in new development instead of the `post_list_sample_query_sets` interceptor. + When both interceptors are used, this `post_list_sample_query_sets_with_metadata` interceptor runs after the + `post_list_sample_query_sets` interceptor. The (possibly modified) response returned by + `post_list_sample_query_sets` will be passed to + `post_list_sample_query_sets_with_metadata`. + """ + return response, metadata + def pre_update_sample_query_set( self, request: sample_query_set_service.UpdateSampleQuerySetRequest, @@ -230,12 +306,37 @@ def post_update_sample_query_set( ) -> gcd_sample_query_set.SampleQuerySet: """Post-rpc interceptor for update_sample_query_set - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_sample_query_set_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQuerySetService server but before - it is returned to user code. + it is returned to user code. This `post_update_sample_query_set` interceptor runs + before the `post_update_sample_query_set_with_metadata` interceptor. """ return response + def post_update_sample_query_set_with_metadata( + self, + response: gcd_sample_query_set.SampleQuerySet, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_sample_query_set.SampleQuerySet, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_sample_query_set + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQuerySetService server but before it is returned to user code. + + We recommend only using this `post_update_sample_query_set_with_metadata` + interceptor in new development instead of the `post_update_sample_query_set` interceptor. + When both interceptors are used, this `post_update_sample_query_set_with_metadata` interceptor runs after the + `post_update_sample_query_set` interceptor. The (possibly modified) response returned by + `post_update_sample_query_set` will be passed to + `post_update_sample_query_set_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -531,6 +632,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_sample_query_set(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_sample_query_set_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -797,6 +902,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_sample_query_set(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_sample_query_set_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -947,6 +1056,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_sample_query_sets(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sample_query_sets_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1108,6 +1221,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_sample_query_set(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_sample_query_set_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/schema_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/schema_service/client.py index 49690a412cd7..bdd60bd0940a 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/schema_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/schema_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -517,6 +519,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1383,16 +1412,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1438,16 +1471,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/schema_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/schema_service/transports/rest.py index c162de309e52..cc807e2e2c8c 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/schema_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/schema_service/transports/rest.py @@ -135,12 +135,35 @@ def post_create_schema( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_create_schema` interceptor runs + before the `post_create_schema_with_metadata` interceptor. """ return response + def post_create_schema_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_create_schema_with_metadata` + interceptor in new development instead of the `post_create_schema` interceptor. + When both interceptors are used, this `post_create_schema_with_metadata` interceptor runs after the + `post_create_schema` interceptor. The (possibly modified) response returned by + `post_create_schema` will be passed to + `post_create_schema_with_metadata`. + """ + return response, metadata + def pre_delete_schema( self, request: schema_service.DeleteSchemaRequest, @@ -160,12 +183,35 @@ def post_delete_schema( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_delete_schema` interceptor runs + before the `post_delete_schema_with_metadata` interceptor. """ return response + def post_delete_schema_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_delete_schema_with_metadata` + interceptor in new development instead of the `post_delete_schema` interceptor. + When both interceptors are used, this `post_delete_schema_with_metadata` interceptor runs after the + `post_delete_schema` interceptor. The (possibly modified) response returned by + `post_delete_schema` will be passed to + `post_delete_schema_with_metadata`. + """ + return response, metadata + def pre_get_schema( self, request: schema_service.GetSchemaRequest, @@ -183,12 +229,33 @@ def pre_get_schema( def post_get_schema(self, response: schema.Schema) -> schema.Schema: """Post-rpc interceptor for get_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_get_schema` interceptor runs + before the `post_get_schema_with_metadata` interceptor. """ return response + def post_get_schema_with_metadata( + self, response: schema.Schema, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[schema.Schema, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_get_schema_with_metadata` + interceptor in new development instead of the `post_get_schema` interceptor. + When both interceptors are used, this `post_get_schema_with_metadata` interceptor runs after the + `post_get_schema` interceptor. The (possibly modified) response returned by + `post_get_schema` will be passed to + `post_get_schema_with_metadata`. + """ + return response, metadata + def pre_list_schemas( self, request: schema_service.ListSchemasRequest, @@ -208,12 +275,37 @@ def post_list_schemas( ) -> schema_service.ListSchemasResponse: """Post-rpc interceptor for list_schemas - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_schemas_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_list_schemas` interceptor runs + before the `post_list_schemas_with_metadata` interceptor. """ return response + def post_list_schemas_with_metadata( + self, + response: schema_service.ListSchemasResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + schema_service.ListSchemasResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_schemas + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_list_schemas_with_metadata` + interceptor in new development instead of the `post_list_schemas` interceptor. + When both interceptors are used, this `post_list_schemas_with_metadata` interceptor runs after the + `post_list_schemas` interceptor. The (possibly modified) response returned by + `post_list_schemas` will be passed to + `post_list_schemas_with_metadata`. + """ + return response, metadata + def pre_update_schema( self, request: schema_service.UpdateSchemaRequest, @@ -233,12 +325,35 @@ def post_update_schema( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_update_schema` interceptor runs + before the `post_update_schema_with_metadata` interceptor. """ return response + def post_update_schema_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_update_schema_with_metadata` + interceptor in new development instead of the `post_update_schema` interceptor. + When both interceptors are used, this `post_update_schema_with_metadata` interceptor runs after the + `post_update_schema` interceptor. The (possibly modified) response returned by + `post_update_schema` will be passed to + `post_update_schema_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -699,6 +814,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -842,6 +961,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -990,6 +1113,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1137,6 +1264,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_schemas(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_schemas_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1288,6 +1419,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_service/client.py index 9ab02e50d87d..62f31b196180 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -611,6 +613,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -967,16 +996,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1022,16 +1055,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_service/transports/rest.py index f192c9a4f4f1..81d8b3dcc3ae 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_service/transports/rest.py @@ -101,12 +101,35 @@ def post_search( ) -> search_service.SearchResponse: """Post-rpc interceptor for search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchService server but before - it is returned to user code. + it is returned to user code. This `post_search` interceptor runs + before the `post_search_with_metadata` interceptor. """ return response + def post_search_with_metadata( + self, + response: search_service.SearchResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[search_service.SearchResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchService server but before it is returned to user code. + + We recommend only using this `post_search_with_metadata` + interceptor in new development instead of the `post_search` interceptor. + When both interceptors are used, this `post_search_with_metadata` interceptor runs after the + `post_search` interceptor. The (possibly modified) response returned by + `post_search` will be passed to + `post_search_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -397,6 +420,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_tuning_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_tuning_service/client.py index be4d72c8e69e..3068ff9bdf8f 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_tuning_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_tuning_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -515,6 +517,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -968,16 +997,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1023,16 +1056,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_tuning_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_tuning_service/transports/rest.py index 22f51036803d..cdd5867f6aff 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_tuning_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/search_tuning_service/transports/rest.py @@ -112,12 +112,38 @@ def post_list_custom_models( ) -> search_tuning_service.ListCustomModelsResponse: """Post-rpc interceptor for list_custom_models - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_custom_models_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchTuningService server but before - it is returned to user code. + it is returned to user code. This `post_list_custom_models` interceptor runs + before the `post_list_custom_models_with_metadata` interceptor. """ return response + def post_list_custom_models_with_metadata( + self, + response: search_tuning_service.ListCustomModelsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + search_tuning_service.ListCustomModelsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_custom_models + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchTuningService server but before it is returned to user code. + + We recommend only using this `post_list_custom_models_with_metadata` + interceptor in new development instead of the `post_list_custom_models` interceptor. + When both interceptors are used, this `post_list_custom_models_with_metadata` interceptor runs after the + `post_list_custom_models` interceptor. The (possibly modified) response returned by + `post_list_custom_models` will be passed to + `post_list_custom_models_with_metadata`. + """ + return response, metadata + def pre_train_custom_model( self, request: search_tuning_service.TrainCustomModelRequest, @@ -138,12 +164,35 @@ def post_train_custom_model( ) -> operations_pb2.Operation: """Post-rpc interceptor for train_custom_model - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_train_custom_model_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchTuningService server but before - it is returned to user code. + it is returned to user code. This `post_train_custom_model` interceptor runs + before the `post_train_custom_model_with_metadata` interceptor. """ return response + def post_train_custom_model_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for train_custom_model + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchTuningService server but before it is returned to user code. + + We recommend only using this `post_train_custom_model_with_metadata` + interceptor in new development instead of the `post_train_custom_model` interceptor. + When both interceptors are used, this `post_train_custom_model_with_metadata` interceptor runs after the + `post_train_custom_model` interceptor. The (possibly modified) response returned by + `post_train_custom_model` will be passed to + `post_train_custom_model_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -602,6 +651,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_custom_models(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_custom_models_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -756,6 +809,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_train_custom_model(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_train_custom_model_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/serving_config_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/serving_config_service/client.py index 3d74a72d9aac..4a8b402e45e4 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/serving_config_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/serving_config_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -498,6 +500,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1128,16 +1157,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1183,16 +1216,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/serving_config_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/serving_config_service/transports/rest.py index a41d8c9d08d2..5a308a95b1cb 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/serving_config_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/serving_config_service/transports/rest.py @@ -124,12 +124,35 @@ def post_get_serving_config( ) -> serving_config.ServingConfig: """Post-rpc interceptor for get_serving_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_serving_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ServingConfigService server but before - it is returned to user code. + it is returned to user code. This `post_get_serving_config` interceptor runs + before the `post_get_serving_config_with_metadata` interceptor. """ return response + def post_get_serving_config_with_metadata( + self, + response: serving_config.ServingConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[serving_config.ServingConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_serving_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ServingConfigService server but before it is returned to user code. + + We recommend only using this `post_get_serving_config_with_metadata` + interceptor in new development instead of the `post_get_serving_config` interceptor. + When both interceptors are used, this `post_get_serving_config_with_metadata` interceptor runs after the + `post_get_serving_config` interceptor. The (possibly modified) response returned by + `post_get_serving_config` will be passed to + `post_get_serving_config_with_metadata`. + """ + return response, metadata + def pre_list_serving_configs( self, request: serving_config_service.ListServingConfigsRequest, @@ -150,12 +173,38 @@ def post_list_serving_configs( ) -> serving_config_service.ListServingConfigsResponse: """Post-rpc interceptor for list_serving_configs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_serving_configs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ServingConfigService server but before - it is returned to user code. + it is returned to user code. This `post_list_serving_configs` interceptor runs + before the `post_list_serving_configs_with_metadata` interceptor. """ return response + def post_list_serving_configs_with_metadata( + self, + response: serving_config_service.ListServingConfigsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + serving_config_service.ListServingConfigsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_serving_configs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ServingConfigService server but before it is returned to user code. + + We recommend only using this `post_list_serving_configs_with_metadata` + interceptor in new development instead of the `post_list_serving_configs` interceptor. + When both interceptors are used, this `post_list_serving_configs_with_metadata` interceptor runs after the + `post_list_serving_configs` interceptor. The (possibly modified) response returned by + `post_list_serving_configs` will be passed to + `post_list_serving_configs_with_metadata`. + """ + return response, metadata + def pre_update_serving_config( self, request: serving_config_service.UpdateServingConfigRequest, @@ -176,12 +225,37 @@ def post_update_serving_config( ) -> gcd_serving_config.ServingConfig: """Post-rpc interceptor for update_serving_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_serving_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ServingConfigService server but before - it is returned to user code. + it is returned to user code. This `post_update_serving_config` interceptor runs + before the `post_update_serving_config_with_metadata` interceptor. """ return response + def post_update_serving_config_with_metadata( + self, + response: gcd_serving_config.ServingConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_serving_config.ServingConfig, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_serving_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ServingConfigService server but before it is returned to user code. + + We recommend only using this `post_update_serving_config_with_metadata` + interceptor in new development instead of the `post_update_serving_config` interceptor. + When both interceptors are used, this `post_update_serving_config_with_metadata` interceptor runs after the + `post_update_serving_config` interceptor. The (possibly modified) response returned by + `post_update_serving_config` will be passed to + `post_update_serving_config_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -471,6 +545,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_serving_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_serving_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -619,6 +697,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_serving_configs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_serving_configs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -781,6 +863,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_serving_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_serving_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/site_search_engine_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/site_search_engine_service/client.py index be00111936d1..ca2f705cb6b5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/site_search_engine_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/site_search_engine_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -522,6 +524,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2441,16 +2470,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2496,16 +2529,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/site_search_engine_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/site_search_engine_service/transports/rest.py index 2ddcd8c300c5..a940b44e3030 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/site_search_engine_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/site_search_engine_service/transports/rest.py @@ -211,12 +211,35 @@ def post_batch_create_target_sites( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_create_target_sites - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_create_target_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_batch_create_target_sites` interceptor runs + before the `post_batch_create_target_sites_with_metadata` interceptor. """ return response + def post_batch_create_target_sites_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_create_target_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_batch_create_target_sites_with_metadata` + interceptor in new development instead of the `post_batch_create_target_sites` interceptor. + When both interceptors are used, this `post_batch_create_target_sites_with_metadata` interceptor runs after the + `post_batch_create_target_sites` interceptor. The (possibly modified) response returned by + `post_batch_create_target_sites` will be passed to + `post_batch_create_target_sites_with_metadata`. + """ + return response, metadata + def pre_batch_verify_target_sites( self, request: site_search_engine_service.BatchVerifyTargetSitesRequest, @@ -237,12 +260,35 @@ def post_batch_verify_target_sites( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_verify_target_sites - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_verify_target_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_batch_verify_target_sites` interceptor runs + before the `post_batch_verify_target_sites_with_metadata` interceptor. """ return response + def post_batch_verify_target_sites_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_verify_target_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_batch_verify_target_sites_with_metadata` + interceptor in new development instead of the `post_batch_verify_target_sites` interceptor. + When both interceptors are used, this `post_batch_verify_target_sites_with_metadata` interceptor runs after the + `post_batch_verify_target_sites` interceptor. The (possibly modified) response returned by + `post_batch_verify_target_sites` will be passed to + `post_batch_verify_target_sites_with_metadata`. + """ + return response, metadata + def pre_create_target_site( self, request: site_search_engine_service.CreateTargetSiteRequest, @@ -263,12 +309,35 @@ def post_create_target_site( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_create_target_site` interceptor runs + before the `post_create_target_site_with_metadata` interceptor. """ return response + def post_create_target_site_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_create_target_site_with_metadata` + interceptor in new development instead of the `post_create_target_site` interceptor. + When both interceptors are used, this `post_create_target_site_with_metadata` interceptor runs after the + `post_create_target_site` interceptor. The (possibly modified) response returned by + `post_create_target_site` will be passed to + `post_create_target_site_with_metadata`. + """ + return response, metadata + def pre_delete_target_site( self, request: site_search_engine_service.DeleteTargetSiteRequest, @@ -289,12 +358,35 @@ def post_delete_target_site( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_delete_target_site` interceptor runs + before the `post_delete_target_site_with_metadata` interceptor. """ return response + def post_delete_target_site_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_delete_target_site_with_metadata` + interceptor in new development instead of the `post_delete_target_site` interceptor. + When both interceptors are used, this `post_delete_target_site_with_metadata` interceptor runs after the + `post_delete_target_site` interceptor. The (possibly modified) response returned by + `post_delete_target_site` will be passed to + `post_delete_target_site_with_metadata`. + """ + return response, metadata + def pre_disable_advanced_site_search( self, request: site_search_engine_service.DisableAdvancedSiteSearchRequest, @@ -315,12 +407,35 @@ def post_disable_advanced_site_search( ) -> operations_pb2.Operation: """Post-rpc interceptor for disable_advanced_site_search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_disable_advanced_site_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_disable_advanced_site_search` interceptor runs + before the `post_disable_advanced_site_search_with_metadata` interceptor. """ return response + def post_disable_advanced_site_search_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for disable_advanced_site_search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_disable_advanced_site_search_with_metadata` + interceptor in new development instead of the `post_disable_advanced_site_search` interceptor. + When both interceptors are used, this `post_disable_advanced_site_search_with_metadata` interceptor runs after the + `post_disable_advanced_site_search` interceptor. The (possibly modified) response returned by + `post_disable_advanced_site_search` will be passed to + `post_disable_advanced_site_search_with_metadata`. + """ + return response, metadata + def pre_enable_advanced_site_search( self, request: site_search_engine_service.EnableAdvancedSiteSearchRequest, @@ -341,12 +456,35 @@ def post_enable_advanced_site_search( ) -> operations_pb2.Operation: """Post-rpc interceptor for enable_advanced_site_search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_enable_advanced_site_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_enable_advanced_site_search` interceptor runs + before the `post_enable_advanced_site_search_with_metadata` interceptor. """ return response + def post_enable_advanced_site_search_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for enable_advanced_site_search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_enable_advanced_site_search_with_metadata` + interceptor in new development instead of the `post_enable_advanced_site_search` interceptor. + When both interceptors are used, this `post_enable_advanced_site_search_with_metadata` interceptor runs after the + `post_enable_advanced_site_search` interceptor. The (possibly modified) response returned by + `post_enable_advanced_site_search` will be passed to + `post_enable_advanced_site_search_with_metadata`. + """ + return response, metadata + def pre_fetch_domain_verification_status( self, request: site_search_engine_service.FetchDomainVerificationStatusRequest, @@ -367,12 +505,38 @@ def post_fetch_domain_verification_status( ) -> site_search_engine_service.FetchDomainVerificationStatusResponse: """Post-rpc interceptor for fetch_domain_verification_status - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_domain_verification_status_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_fetch_domain_verification_status` interceptor runs + before the `post_fetch_domain_verification_status_with_metadata` interceptor. """ return response + def post_fetch_domain_verification_status_with_metadata( + self, + response: site_search_engine_service.FetchDomainVerificationStatusResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine_service.FetchDomainVerificationStatusResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for fetch_domain_verification_status + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_fetch_domain_verification_status_with_metadata` + interceptor in new development instead of the `post_fetch_domain_verification_status` interceptor. + When both interceptors are used, this `post_fetch_domain_verification_status_with_metadata` interceptor runs after the + `post_fetch_domain_verification_status` interceptor. The (possibly modified) response returned by + `post_fetch_domain_verification_status` will be passed to + `post_fetch_domain_verification_status_with_metadata`. + """ + return response, metadata + def pre_get_site_search_engine( self, request: site_search_engine_service.GetSiteSearchEngineRequest, @@ -393,12 +557,37 @@ def post_get_site_search_engine( ) -> site_search_engine.SiteSearchEngine: """Post-rpc interceptor for get_site_search_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_site_search_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_site_search_engine` interceptor runs + before the `post_get_site_search_engine_with_metadata` interceptor. """ return response + def post_get_site_search_engine_with_metadata( + self, + response: site_search_engine.SiteSearchEngine, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine.SiteSearchEngine, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_site_search_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_get_site_search_engine_with_metadata` + interceptor in new development instead of the `post_get_site_search_engine` interceptor. + When both interceptors are used, this `post_get_site_search_engine_with_metadata` interceptor runs after the + `post_get_site_search_engine` interceptor. The (possibly modified) response returned by + `post_get_site_search_engine` will be passed to + `post_get_site_search_engine_with_metadata`. + """ + return response, metadata + def pre_get_target_site( self, request: site_search_engine_service.GetTargetSiteRequest, @@ -419,12 +608,35 @@ def post_get_target_site( ) -> site_search_engine.TargetSite: """Post-rpc interceptor for get_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_target_site` interceptor runs + before the `post_get_target_site_with_metadata` interceptor. """ return response + def post_get_target_site_with_metadata( + self, + response: site_search_engine.TargetSite, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_search_engine.TargetSite, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_get_target_site_with_metadata` + interceptor in new development instead of the `post_get_target_site` interceptor. + When both interceptors are used, this `post_get_target_site_with_metadata` interceptor runs after the + `post_get_target_site` interceptor. The (possibly modified) response returned by + `post_get_target_site` will be passed to + `post_get_target_site_with_metadata`. + """ + return response, metadata + def pre_get_uri_pattern_document_data( self, request: site_search_engine_service.GetUriPatternDocumentDataRequest, @@ -445,12 +657,38 @@ def post_get_uri_pattern_document_data( ) -> site_search_engine_service.GetUriPatternDocumentDataResponse: """Post-rpc interceptor for get_uri_pattern_document_data - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_uri_pattern_document_data_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_uri_pattern_document_data` interceptor runs + before the `post_get_uri_pattern_document_data_with_metadata` interceptor. """ return response + def post_get_uri_pattern_document_data_with_metadata( + self, + response: site_search_engine_service.GetUriPatternDocumentDataResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine_service.GetUriPatternDocumentDataResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for get_uri_pattern_document_data + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_get_uri_pattern_document_data_with_metadata` + interceptor in new development instead of the `post_get_uri_pattern_document_data` interceptor. + When both interceptors are used, this `post_get_uri_pattern_document_data_with_metadata` interceptor runs after the + `post_get_uri_pattern_document_data` interceptor. The (possibly modified) response returned by + `post_get_uri_pattern_document_data` will be passed to + `post_get_uri_pattern_document_data_with_metadata`. + """ + return response, metadata + def pre_list_target_sites( self, request: site_search_engine_service.ListTargetSitesRequest, @@ -471,12 +709,38 @@ def post_list_target_sites( ) -> site_search_engine_service.ListTargetSitesResponse: """Post-rpc interceptor for list_target_sites - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_target_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_list_target_sites` interceptor runs + before the `post_list_target_sites_with_metadata` interceptor. """ return response + def post_list_target_sites_with_metadata( + self, + response: site_search_engine_service.ListTargetSitesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine_service.ListTargetSitesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_target_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_list_target_sites_with_metadata` + interceptor in new development instead of the `post_list_target_sites` interceptor. + When both interceptors are used, this `post_list_target_sites_with_metadata` interceptor runs after the + `post_list_target_sites` interceptor. The (possibly modified) response returned by + `post_list_target_sites` will be passed to + `post_list_target_sites_with_metadata`. + """ + return response, metadata + def pre_recrawl_uris( self, request: site_search_engine_service.RecrawlUrisRequest, @@ -497,12 +761,35 @@ def post_recrawl_uris( ) -> operations_pb2.Operation: """Post-rpc interceptor for recrawl_uris - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_recrawl_uris_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_recrawl_uris` interceptor runs + before the `post_recrawl_uris_with_metadata` interceptor. """ return response + def post_recrawl_uris_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for recrawl_uris + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_recrawl_uris_with_metadata` + interceptor in new development instead of the `post_recrawl_uris` interceptor. + When both interceptors are used, this `post_recrawl_uris_with_metadata` interceptor runs after the + `post_recrawl_uris` interceptor. The (possibly modified) response returned by + `post_recrawl_uris` will be passed to + `post_recrawl_uris_with_metadata`. + """ + return response, metadata + def pre_set_uri_pattern_document_data( self, request: site_search_engine_service.SetUriPatternDocumentDataRequest, @@ -523,12 +810,35 @@ def post_set_uri_pattern_document_data( ) -> operations_pb2.Operation: """Post-rpc interceptor for set_uri_pattern_document_data - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_set_uri_pattern_document_data_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_set_uri_pattern_document_data` interceptor runs + before the `post_set_uri_pattern_document_data_with_metadata` interceptor. """ return response + def post_set_uri_pattern_document_data_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for set_uri_pattern_document_data + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_set_uri_pattern_document_data_with_metadata` + interceptor in new development instead of the `post_set_uri_pattern_document_data` interceptor. + When both interceptors are used, this `post_set_uri_pattern_document_data_with_metadata` interceptor runs after the + `post_set_uri_pattern_document_data` interceptor. The (possibly modified) response returned by + `post_set_uri_pattern_document_data` will be passed to + `post_set_uri_pattern_document_data_with_metadata`. + """ + return response, metadata + def pre_update_target_site( self, request: site_search_engine_service.UpdateTargetSiteRequest, @@ -549,12 +859,35 @@ def post_update_target_site( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_update_target_site` interceptor runs + before the `post_update_target_site_with_metadata` interceptor. """ return response + def post_update_target_site_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_update_target_site_with_metadata` + interceptor in new development instead of the `post_update_target_site` interceptor. + When both interceptors are used, this `post_update_target_site_with_metadata` interceptor runs after the + `post_update_target_site` interceptor. The (possibly modified) response returned by + `post_update_target_site` will be passed to + `post_update_target_site_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -1017,6 +1350,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_create_target_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_target_sites_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1169,6 +1506,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_verify_target_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_verify_target_sites_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1323,6 +1664,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1471,6 +1816,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1626,6 +1975,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_disable_advanced_site_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_disable_advanced_site_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1779,6 +2132,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_enable_advanced_site_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_enable_advanced_site_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1934,6 +2291,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_domain_verification_status(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_fetch_domain_verification_status_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2087,6 +2451,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_site_search_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_site_search_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2236,6 +2604,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2389,6 +2761,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_uri_pattern_document_data(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_get_uri_pattern_document_data_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2541,6 +2920,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_target_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_target_sites_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2695,6 +3078,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_recrawl_uris(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_recrawl_uris_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2850,6 +3237,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_set_uri_pattern_document_data(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_set_uri_pattern_document_data_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3004,6 +3398,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/user_event_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/user_event_service/client.py index 3a83d17becd1..e9b23dcc52b9 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/user_event_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/user_event_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -549,6 +551,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1245,16 +1274,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1300,16 +1333,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/user_event_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/user_event_service/transports/rest.py index b77472f62a1e..d4d4a297d3d3 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/user_event_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1alpha/services/user_event_service/transports/rest.py @@ -134,12 +134,35 @@ def post_collect_user_event( ) -> httpbody_pb2.HttpBody: """Post-rpc interceptor for collect_user_event - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_collect_user_event_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_collect_user_event` interceptor runs + before the `post_collect_user_event_with_metadata` interceptor. """ return response + def post_collect_user_event_with_metadata( + self, + response: httpbody_pb2.HttpBody, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[httpbody_pb2.HttpBody, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for collect_user_event + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_collect_user_event_with_metadata` + interceptor in new development instead of the `post_collect_user_event` interceptor. + When both interceptors are used, this `post_collect_user_event_with_metadata` interceptor runs after the + `post_collect_user_event` interceptor. The (possibly modified) response returned by + `post_collect_user_event` will be passed to + `post_collect_user_event_with_metadata`. + """ + return response, metadata + def pre_import_user_events( self, request: import_config.ImportUserEventsRequest, @@ -159,12 +182,35 @@ def post_import_user_events( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_user_events - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_user_events_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_import_user_events` interceptor runs + before the `post_import_user_events_with_metadata` interceptor. """ return response + def post_import_user_events_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_user_events + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_import_user_events_with_metadata` + interceptor in new development instead of the `post_import_user_events` interceptor. + When both interceptors are used, this `post_import_user_events_with_metadata` interceptor runs after the + `post_import_user_events` interceptor. The (possibly modified) response returned by + `post_import_user_events` will be passed to + `post_import_user_events_with_metadata`. + """ + return response, metadata + def pre_purge_user_events( self, request: purge_config.PurgeUserEventsRequest, @@ -184,12 +230,35 @@ def post_purge_user_events( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_user_events - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_user_events_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_purge_user_events` interceptor runs + before the `post_purge_user_events_with_metadata` interceptor. """ return response + def post_purge_user_events_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_user_events + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_purge_user_events_with_metadata` + interceptor in new development instead of the `post_purge_user_events` interceptor. + When both interceptors are used, this `post_purge_user_events_with_metadata` interceptor runs after the + `post_purge_user_events` interceptor. The (possibly modified) response returned by + `post_purge_user_events` will be passed to + `post_purge_user_events_with_metadata`. + """ + return response, metadata + def pre_write_user_event( self, request: user_event_service.WriteUserEventRequest, @@ -210,12 +279,35 @@ def post_write_user_event( ) -> user_event.UserEvent: """Post-rpc interceptor for write_user_event - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_write_user_event_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_write_user_event` interceptor runs + before the `post_write_user_event_with_metadata` interceptor. """ return response + def post_write_user_event_with_metadata( + self, + response: user_event.UserEvent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[user_event.UserEvent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for write_user_event + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_write_user_event_with_metadata` + interceptor in new development instead of the `post_write_user_event` interceptor. + When both interceptors are used, this `post_write_user_event_with_metadata` interceptor runs after the + `post_write_user_event` interceptor. The (possibly modified) response returned by + `post_write_user_event` will be passed to + `post_write_user_event_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -720,6 +812,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_collect_user_event(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_collect_user_event_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -871,6 +967,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_user_events(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_user_events_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1022,6 +1122,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_user_events(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_purge_user_events_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1175,6 +1279,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_write_user_event(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_write_user_event_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/gapic_version.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/gapic_version.py index 458413f5c30f..558c8aab67c5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/gapic_version.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.13.5" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/completion_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/completion_service/client.py index b24f8435d2f7..dd11c714ebac 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/completion_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/completion_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -540,6 +542,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1419,16 +1448,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1474,16 +1507,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/completion_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/completion_service/transports/rest.py index b12df6e5c386..e059ef643e44 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/completion_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/completion_service/transports/rest.py @@ -148,12 +148,38 @@ def post_advanced_complete_query( ) -> completion_service.AdvancedCompleteQueryResponse: """Post-rpc interceptor for advanced_complete_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_advanced_complete_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_advanced_complete_query` interceptor runs + before the `post_advanced_complete_query_with_metadata` interceptor. """ return response + def post_advanced_complete_query_with_metadata( + self, + response: completion_service.AdvancedCompleteQueryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + completion_service.AdvancedCompleteQueryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for advanced_complete_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_advanced_complete_query_with_metadata` + interceptor in new development instead of the `post_advanced_complete_query` interceptor. + When both interceptors are used, this `post_advanced_complete_query_with_metadata` interceptor runs after the + `post_advanced_complete_query` interceptor. The (possibly modified) response returned by + `post_advanced_complete_query` will be passed to + `post_advanced_complete_query_with_metadata`. + """ + return response, metadata + def pre_complete_query( self, request: completion_service.CompleteQueryRequest, @@ -173,12 +199,38 @@ def post_complete_query( ) -> completion_service.CompleteQueryResponse: """Post-rpc interceptor for complete_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_complete_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_complete_query` interceptor runs + before the `post_complete_query_with_metadata` interceptor. """ return response + def post_complete_query_with_metadata( + self, + response: completion_service.CompleteQueryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + completion_service.CompleteQueryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for complete_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_complete_query_with_metadata` + interceptor in new development instead of the `post_complete_query` interceptor. + When both interceptors are used, this `post_complete_query_with_metadata` interceptor runs after the + `post_complete_query` interceptor. The (possibly modified) response returned by + `post_complete_query` will be passed to + `post_complete_query_with_metadata`. + """ + return response, metadata + def pre_import_completion_suggestions( self, request: import_config.ImportCompletionSuggestionsRequest, @@ -199,12 +251,35 @@ def post_import_completion_suggestions( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_completion_suggestions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_completion_suggestions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_import_completion_suggestions` interceptor runs + before the `post_import_completion_suggestions_with_metadata` interceptor. """ return response + def post_import_completion_suggestions_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_completion_suggestions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_import_completion_suggestions_with_metadata` + interceptor in new development instead of the `post_import_completion_suggestions` interceptor. + When both interceptors are used, this `post_import_completion_suggestions_with_metadata` interceptor runs after the + `post_import_completion_suggestions` interceptor. The (possibly modified) response returned by + `post_import_completion_suggestions` will be passed to + `post_import_completion_suggestions_with_metadata`. + """ + return response, metadata + def pre_import_suggestion_deny_list_entries( self, request: import_config.ImportSuggestionDenyListEntriesRequest, @@ -225,12 +300,35 @@ def post_import_suggestion_deny_list_entries( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_suggestion_deny_list_entries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_suggestion_deny_list_entries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_import_suggestion_deny_list_entries` interceptor runs + before the `post_import_suggestion_deny_list_entries_with_metadata` interceptor. """ return response + def post_import_suggestion_deny_list_entries_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_suggestion_deny_list_entries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_import_suggestion_deny_list_entries_with_metadata` + interceptor in new development instead of the `post_import_suggestion_deny_list_entries` interceptor. + When both interceptors are used, this `post_import_suggestion_deny_list_entries_with_metadata` interceptor runs after the + `post_import_suggestion_deny_list_entries` interceptor. The (possibly modified) response returned by + `post_import_suggestion_deny_list_entries` will be passed to + `post_import_suggestion_deny_list_entries_with_metadata`. + """ + return response, metadata + def pre_purge_completion_suggestions( self, request: purge_config.PurgeCompletionSuggestionsRequest, @@ -251,12 +349,35 @@ def post_purge_completion_suggestions( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_completion_suggestions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_completion_suggestions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_purge_completion_suggestions` interceptor runs + before the `post_purge_completion_suggestions_with_metadata` interceptor. """ return response + def post_purge_completion_suggestions_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_completion_suggestions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_purge_completion_suggestions_with_metadata` + interceptor in new development instead of the `post_purge_completion_suggestions` interceptor. + When both interceptors are used, this `post_purge_completion_suggestions_with_metadata` interceptor runs after the + `post_purge_completion_suggestions` interceptor. The (possibly modified) response returned by + `post_purge_completion_suggestions` will be passed to + `post_purge_completion_suggestions_with_metadata`. + """ + return response, metadata + def pre_purge_suggestion_deny_list_entries( self, request: purge_config.PurgeSuggestionDenyListEntriesRequest, @@ -277,12 +398,35 @@ def post_purge_suggestion_deny_list_entries( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_suggestion_deny_list_entries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_suggestion_deny_list_entries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the CompletionService server but before - it is returned to user code. + it is returned to user code. This `post_purge_suggestion_deny_list_entries` interceptor runs + before the `post_purge_suggestion_deny_list_entries_with_metadata` interceptor. """ return response + def post_purge_suggestion_deny_list_entries_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_suggestion_deny_list_entries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the CompletionService server but before it is returned to user code. + + We recommend only using this `post_purge_suggestion_deny_list_entries_with_metadata` + interceptor in new development instead of the `post_purge_suggestion_deny_list_entries` interceptor. + When both interceptors are used, this `post_purge_suggestion_deny_list_entries_with_metadata` interceptor runs after the + `post_purge_suggestion_deny_list_entries` interceptor. The (possibly modified) response returned by + `post_purge_suggestion_deny_list_entries` will be passed to + `post_purge_suggestion_deny_list_entries_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -741,6 +885,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_advanced_complete_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_advanced_complete_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -891,6 +1039,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_complete_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_complete_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1046,6 +1198,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_completion_suggestions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_import_completion_suggestions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1204,6 +1363,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_suggestion_deny_list_entries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_import_suggestion_deny_list_entries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1357,6 +1523,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_completion_suggestions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_purge_completion_suggestions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1513,6 +1683,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_suggestion_deny_list_entries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_purge_suggestion_deny_list_entries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/control_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/control_service/client.py index 7d8f75591dec..9ec6499c37ad 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/control_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/control_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -519,6 +521,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1379,16 +1408,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1434,16 +1467,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/control_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/control_service/transports/rest.py index e60174444857..c9efc66e0c96 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/control_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/control_service/transports/rest.py @@ -132,12 +132,35 @@ def pre_create_control( def post_create_control(self, response: gcd_control.Control) -> gcd_control.Control: """Post-rpc interceptor for create_control - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_control_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_create_control` interceptor runs + before the `post_create_control_with_metadata` interceptor. """ return response + def post_create_control_with_metadata( + self, + response: gcd_control.Control, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_control.Control, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_control + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_create_control_with_metadata` + interceptor in new development instead of the `post_create_control` interceptor. + When both interceptors are used, this `post_create_control_with_metadata` interceptor runs after the + `post_create_control` interceptor. The (possibly modified) response returned by + `post_create_control` will be passed to + `post_create_control_with_metadata`. + """ + return response, metadata + def pre_delete_control( self, request: control_service.DeleteControlRequest, @@ -169,12 +192,35 @@ def pre_get_control( def post_get_control(self, response: control.Control) -> control.Control: """Post-rpc interceptor for get_control - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_control_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_get_control` interceptor runs + before the `post_get_control_with_metadata` interceptor. """ return response + def post_get_control_with_metadata( + self, + response: control.Control, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[control.Control, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_control + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_get_control_with_metadata` + interceptor in new development instead of the `post_get_control` interceptor. + When both interceptors are used, this `post_get_control_with_metadata` interceptor runs after the + `post_get_control` interceptor. The (possibly modified) response returned by + `post_get_control` will be passed to + `post_get_control_with_metadata`. + """ + return response, metadata + def pre_list_controls( self, request: control_service.ListControlsRequest, @@ -194,12 +240,37 @@ def post_list_controls( ) -> control_service.ListControlsResponse: """Post-rpc interceptor for list_controls - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_controls_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_list_controls` interceptor runs + before the `post_list_controls_with_metadata` interceptor. """ return response + def post_list_controls_with_metadata( + self, + response: control_service.ListControlsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + control_service.ListControlsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_controls + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_list_controls_with_metadata` + interceptor in new development instead of the `post_list_controls` interceptor. + When both interceptors are used, this `post_list_controls_with_metadata` interceptor runs after the + `post_list_controls` interceptor. The (possibly modified) response returned by + `post_list_controls` will be passed to + `post_list_controls_with_metadata`. + """ + return response, metadata + def pre_update_control( self, request: control_service.UpdateControlRequest, @@ -217,12 +288,35 @@ def pre_update_control( def post_update_control(self, response: gcd_control.Control) -> gcd_control.Control: """Post-rpc interceptor for update_control - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_control_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ControlService server but before - it is returned to user code. + it is returned to user code. This `post_update_control` interceptor runs + before the `post_update_control_with_metadata` interceptor. """ return response + def post_update_control_with_metadata( + self, + response: gcd_control.Control, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_control.Control, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_control + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ControlService server but before it is returned to user code. + + We recommend only using this `post_update_control_with_metadata` + interceptor in new development instead of the `post_update_control` interceptor. + When both interceptors are used, this `post_update_control_with_metadata` interceptor runs after the + `post_update_control` interceptor. The (possibly modified) response returned by + `post_update_control` will be passed to + `post_update_control_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -514,6 +608,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_control(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_control_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -767,6 +865,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_control(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_control_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -907,6 +1009,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_controls(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_controls_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1060,6 +1166,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_control(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_control_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/conversational_search_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/conversational_search_service/client.py index 0be5f6265ed2..46d4349edf39 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/conversational_search_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/conversational_search_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -657,6 +659,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2392,16 +2421,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2447,16 +2480,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/conversational_search_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/conversational_search_service/transports/rest.py index 92909d7aeb25..8d02bdf0d96d 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/conversational_search_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/conversational_search_service/transports/rest.py @@ -198,12 +198,38 @@ def post_answer_query( ) -> conversational_search_service.AnswerQueryResponse: """Post-rpc interceptor for answer_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_answer_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_answer_query` interceptor runs + before the `post_answer_query_with_metadata` interceptor. """ return response + def post_answer_query_with_metadata( + self, + response: conversational_search_service.AnswerQueryResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.AnswerQueryResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for answer_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_answer_query_with_metadata` + interceptor in new development instead of the `post_answer_query` interceptor. + When both interceptors are used, this `post_answer_query_with_metadata` interceptor runs after the + `post_answer_query` interceptor. The (possibly modified) response returned by + `post_answer_query` will be passed to + `post_answer_query_with_metadata`. + """ + return response, metadata + def pre_converse_conversation( self, request: conversational_search_service.ConverseConversationRequest, @@ -224,12 +250,38 @@ def post_converse_conversation( ) -> conversational_search_service.ConverseConversationResponse: """Post-rpc interceptor for converse_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_converse_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_converse_conversation` interceptor runs + before the `post_converse_conversation_with_metadata` interceptor. """ return response + def post_converse_conversation_with_metadata( + self, + response: conversational_search_service.ConverseConversationResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.ConverseConversationResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for converse_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_converse_conversation_with_metadata` + interceptor in new development instead of the `post_converse_conversation` interceptor. + When both interceptors are used, this `post_converse_conversation_with_metadata` interceptor runs after the + `post_converse_conversation` interceptor. The (possibly modified) response returned by + `post_converse_conversation` will be passed to + `post_converse_conversation_with_metadata`. + """ + return response, metadata + def pre_create_conversation( self, request: conversational_search_service.CreateConversationRequest, @@ -250,12 +302,35 @@ def post_create_conversation( ) -> gcd_conversation.Conversation: """Post-rpc interceptor for create_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_create_conversation` interceptor runs + before the `post_create_conversation_with_metadata` interceptor. """ return response + def post_create_conversation_with_metadata( + self, + response: gcd_conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_create_conversation_with_metadata` + interceptor in new development instead of the `post_create_conversation` interceptor. + When both interceptors are used, this `post_create_conversation_with_metadata` interceptor runs after the + `post_create_conversation` interceptor. The (possibly modified) response returned by + `post_create_conversation` will be passed to + `post_create_conversation_with_metadata`. + """ + return response, metadata + def pre_create_session( self, request: conversational_search_service.CreateSessionRequest, @@ -274,12 +349,35 @@ def pre_create_session( def post_create_session(self, response: gcd_session.Session) -> gcd_session.Session: """Post-rpc interceptor for create_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_create_session` interceptor runs + before the `post_create_session_with_metadata` interceptor. """ return response + def post_create_session_with_metadata( + self, + response: gcd_session.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_session.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_create_session_with_metadata` + interceptor in new development instead of the `post_create_session` interceptor. + When both interceptors are used, this `post_create_session_with_metadata` interceptor runs after the + `post_create_session` interceptor. The (possibly modified) response returned by + `post_create_session` will be passed to + `post_create_session_with_metadata`. + """ + return response, metadata + def pre_delete_conversation( self, request: conversational_search_service.DeleteConversationRequest, @@ -328,12 +426,33 @@ def pre_get_answer( def post_get_answer(self, response: answer.Answer) -> answer.Answer: """Post-rpc interceptor for get_answer - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_answer_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_get_answer` interceptor runs + before the `post_get_answer_with_metadata` interceptor. """ return response + def post_get_answer_with_metadata( + self, response: answer.Answer, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[answer.Answer, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_answer + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_get_answer_with_metadata` + interceptor in new development instead of the `post_get_answer` interceptor. + When both interceptors are used, this `post_get_answer_with_metadata` interceptor runs after the + `post_get_answer` interceptor. The (possibly modified) response returned by + `post_get_answer` will be passed to + `post_get_answer_with_metadata`. + """ + return response, metadata + def pre_get_conversation( self, request: conversational_search_service.GetConversationRequest, @@ -354,12 +473,35 @@ def post_get_conversation( ) -> conversation.Conversation: """Post-rpc interceptor for get_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_get_conversation` interceptor runs + before the `post_get_conversation_with_metadata` interceptor. """ return response + def post_get_conversation_with_metadata( + self, + response: conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_get_conversation_with_metadata` + interceptor in new development instead of the `post_get_conversation` interceptor. + When both interceptors are used, this `post_get_conversation_with_metadata` interceptor runs after the + `post_get_conversation` interceptor. The (possibly modified) response returned by + `post_get_conversation` will be passed to + `post_get_conversation_with_metadata`. + """ + return response, metadata + def pre_get_session( self, request: conversational_search_service.GetSessionRequest, @@ -378,12 +520,35 @@ def pre_get_session( def post_get_session(self, response: session.Session) -> session.Session: """Post-rpc interceptor for get_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_get_session` interceptor runs + before the `post_get_session_with_metadata` interceptor. """ return response + def post_get_session_with_metadata( + self, + response: session.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[session.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_get_session_with_metadata` + interceptor in new development instead of the `post_get_session` interceptor. + When both interceptors are used, this `post_get_session_with_metadata` interceptor runs after the + `post_get_session` interceptor. The (possibly modified) response returned by + `post_get_session` will be passed to + `post_get_session_with_metadata`. + """ + return response, metadata + def pre_list_conversations( self, request: conversational_search_service.ListConversationsRequest, @@ -404,12 +569,38 @@ def post_list_conversations( ) -> conversational_search_service.ListConversationsResponse: """Post-rpc interceptor for list_conversations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_conversations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_list_conversations` interceptor runs + before the `post_list_conversations_with_metadata` interceptor. """ return response + def post_list_conversations_with_metadata( + self, + response: conversational_search_service.ListConversationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.ListConversationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_conversations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_list_conversations_with_metadata` + interceptor in new development instead of the `post_list_conversations` interceptor. + When both interceptors are used, this `post_list_conversations_with_metadata` interceptor runs after the + `post_list_conversations` interceptor. The (possibly modified) response returned by + `post_list_conversations` will be passed to + `post_list_conversations_with_metadata`. + """ + return response, metadata + def pre_list_sessions( self, request: conversational_search_service.ListSessionsRequest, @@ -430,12 +621,38 @@ def post_list_sessions( ) -> conversational_search_service.ListSessionsResponse: """Post-rpc interceptor for list_sessions - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_sessions_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_list_sessions` interceptor runs + before the `post_list_sessions_with_metadata` interceptor. """ return response + def post_list_sessions_with_metadata( + self, + response: conversational_search_service.ListSessionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + conversational_search_service.ListSessionsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_sessions + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_list_sessions_with_metadata` + interceptor in new development instead of the `post_list_sessions` interceptor. + When both interceptors are used, this `post_list_sessions_with_metadata` interceptor runs after the + `post_list_sessions` interceptor. The (possibly modified) response returned by + `post_list_sessions` will be passed to + `post_list_sessions_with_metadata`. + """ + return response, metadata + def pre_update_conversation( self, request: conversational_search_service.UpdateConversationRequest, @@ -456,12 +673,35 @@ def post_update_conversation( ) -> gcd_conversation.Conversation: """Post-rpc interceptor for update_conversation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_conversation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_update_conversation` interceptor runs + before the `post_update_conversation_with_metadata` interceptor. """ return response + def post_update_conversation_with_metadata( + self, + response: gcd_conversation.Conversation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_conversation.Conversation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_conversation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_update_conversation_with_metadata` + interceptor in new development instead of the `post_update_conversation` interceptor. + When both interceptors are used, this `post_update_conversation_with_metadata` interceptor runs after the + `post_update_conversation` interceptor. The (possibly modified) response returned by + `post_update_conversation` will be passed to + `post_update_conversation_with_metadata`. + """ + return response, metadata + def pre_update_session( self, request: conversational_search_service.UpdateSessionRequest, @@ -480,12 +720,35 @@ def pre_update_session( def post_update_session(self, response: gcd_session.Session) -> gcd_session.Session: """Post-rpc interceptor for update_session - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_session_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ConversationalSearchService server but before - it is returned to user code. + it is returned to user code. This `post_update_session` interceptor runs + before the `post_update_session_with_metadata` interceptor. """ return response + def post_update_session_with_metadata( + self, + response: gcd_session.Session, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_session.Session, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_session + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ConversationalSearchService server but before it is returned to user code. + + We recommend only using this `post_update_session_with_metadata` + interceptor in new development instead of the `post_update_session` interceptor. + When both interceptors are used, this `post_update_session_with_metadata` interceptor runs after the + `post_update_session` interceptor. The (possibly modified) response returned by + `post_update_session` will be passed to + `post_update_session_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -779,6 +1042,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_answer_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_answer_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -939,6 +1206,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_converse_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_converse_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1093,6 +1364,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1242,6 +1517,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1604,6 +1883,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_answer(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_answer_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1751,6 +2034,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1894,6 +2181,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2039,6 +2330,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_conversations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_conversations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2186,6 +2481,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_sessions(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sessions_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2342,6 +2641,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_conversation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_conversation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2491,6 +2794,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_session(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_session_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/data_store_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/data_store_service/client.py index daeae1ace236..c601957251e5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/data_store_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/data_store_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -572,6 +574,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1521,16 +1550,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1576,16 +1609,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/data_store_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/data_store_service/transports/rest.py index 0e35259551ed..1eaa80b45d62 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/data_store_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/data_store_service/transports/rest.py @@ -138,12 +138,35 @@ def post_create_data_store( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_create_data_store` interceptor runs + before the `post_create_data_store_with_metadata` interceptor. """ return response + def post_create_data_store_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_create_data_store_with_metadata` + interceptor in new development instead of the `post_create_data_store` interceptor. + When both interceptors are used, this `post_create_data_store_with_metadata` interceptor runs after the + `post_create_data_store` interceptor. The (possibly modified) response returned by + `post_create_data_store` will be passed to + `post_create_data_store_with_metadata`. + """ + return response, metadata + def pre_delete_data_store( self, request: data_store_service.DeleteDataStoreRequest, @@ -164,12 +187,35 @@ def post_delete_data_store( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_delete_data_store` interceptor runs + before the `post_delete_data_store_with_metadata` interceptor. """ return response + def post_delete_data_store_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_delete_data_store_with_metadata` + interceptor in new development instead of the `post_delete_data_store` interceptor. + When both interceptors are used, this `post_delete_data_store_with_metadata` interceptor runs after the + `post_delete_data_store` interceptor. The (possibly modified) response returned by + `post_delete_data_store` will be passed to + `post_delete_data_store_with_metadata`. + """ + return response, metadata + def pre_get_data_store( self, request: data_store_service.GetDataStoreRequest, @@ -189,12 +235,35 @@ def post_get_data_store( ) -> data_store.DataStore: """Post-rpc interceptor for get_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_get_data_store` interceptor runs + before the `post_get_data_store_with_metadata` interceptor. """ return response + def post_get_data_store_with_metadata( + self, + response: data_store.DataStore, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[data_store.DataStore, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_get_data_store_with_metadata` + interceptor in new development instead of the `post_get_data_store` interceptor. + When both interceptors are used, this `post_get_data_store_with_metadata` interceptor runs after the + `post_get_data_store` interceptor. The (possibly modified) response returned by + `post_get_data_store` will be passed to + `post_get_data_store_with_metadata`. + """ + return response, metadata + def pre_list_data_stores( self, request: data_store_service.ListDataStoresRequest, @@ -215,12 +284,38 @@ def post_list_data_stores( ) -> data_store_service.ListDataStoresResponse: """Post-rpc interceptor for list_data_stores - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_data_stores_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_list_data_stores` interceptor runs + before the `post_list_data_stores_with_metadata` interceptor. """ return response + def post_list_data_stores_with_metadata( + self, + response: data_store_service.ListDataStoresResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + data_store_service.ListDataStoresResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_data_stores + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_list_data_stores_with_metadata` + interceptor in new development instead of the `post_list_data_stores` interceptor. + When both interceptors are used, this `post_list_data_stores_with_metadata` interceptor runs after the + `post_list_data_stores` interceptor. The (possibly modified) response returned by + `post_list_data_stores` will be passed to + `post_list_data_stores_with_metadata`. + """ + return response, metadata + def pre_update_data_store( self, request: data_store_service.UpdateDataStoreRequest, @@ -241,12 +336,35 @@ def post_update_data_store( ) -> gcd_data_store.DataStore: """Post-rpc interceptor for update_data_store - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_data_store_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DataStoreService server but before - it is returned to user code. + it is returned to user code. This `post_update_data_store` interceptor runs + before the `post_update_data_store_with_metadata` interceptor. """ return response + def post_update_data_store_with_metadata( + self, + response: gcd_data_store.DataStore, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_data_store.DataStore, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_data_store + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DataStoreService server but before it is returned to user code. + + We recommend only using this `post_update_data_store_with_metadata` + interceptor in new development instead of the `post_update_data_store` interceptor. + When both interceptors are used, this `post_update_data_store_with_metadata` interceptor runs after the + `post_update_data_store` interceptor. The (possibly modified) response returned by + `post_update_data_store` will be passed to + `post_update_data_store_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -703,6 +821,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -849,6 +971,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -993,6 +1119,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1140,6 +1270,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_data_stores(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_data_stores_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1295,6 +1429,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_data_store(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_data_store_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/document_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/document_service/client.py index 78d2dbb375d7..e3c7d1609741 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/document_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/document_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -581,6 +583,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1817,16 +1846,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1872,16 +1905,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/document_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/document_service/transports/rest.py index 3818376f82dd..96556c75b02a 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/document_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/document_service/transports/rest.py @@ -163,12 +163,38 @@ def post_batch_get_documents_metadata( ) -> document_service.BatchGetDocumentsMetadataResponse: """Post-rpc interceptor for batch_get_documents_metadata - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_get_documents_metadata_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_batch_get_documents_metadata` interceptor runs + before the `post_batch_get_documents_metadata_with_metadata` interceptor. """ return response + def post_batch_get_documents_metadata_with_metadata( + self, + response: document_service.BatchGetDocumentsMetadataResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + document_service.BatchGetDocumentsMetadataResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for batch_get_documents_metadata + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_batch_get_documents_metadata_with_metadata` + interceptor in new development instead of the `post_batch_get_documents_metadata` interceptor. + When both interceptors are used, this `post_batch_get_documents_metadata_with_metadata` interceptor runs after the + `post_batch_get_documents_metadata` interceptor. The (possibly modified) response returned by + `post_batch_get_documents_metadata` will be passed to + `post_batch_get_documents_metadata_with_metadata`. + """ + return response, metadata + def pre_create_document( self, request: document_service.CreateDocumentRequest, @@ -188,12 +214,35 @@ def post_create_document( ) -> gcd_document.Document: """Post-rpc interceptor for create_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_create_document` interceptor runs + before the `post_create_document_with_metadata` interceptor. """ return response + def post_create_document_with_metadata( + self, + response: gcd_document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_create_document_with_metadata` + interceptor in new development instead of the `post_create_document` interceptor. + When both interceptors are used, this `post_create_document_with_metadata` interceptor runs after the + `post_create_document` interceptor. The (possibly modified) response returned by + `post_create_document` will be passed to + `post_create_document_with_metadata`. + """ + return response, metadata + def pre_delete_document( self, request: document_service.DeleteDocumentRequest, @@ -225,12 +274,35 @@ def pre_get_document( def post_get_document(self, response: document.Document) -> document.Document: """Post-rpc interceptor for get_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_get_document` interceptor runs + before the `post_get_document_with_metadata` interceptor. """ return response + def post_get_document_with_metadata( + self, + response: document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_get_document_with_metadata` + interceptor in new development instead of the `post_get_document` interceptor. + When both interceptors are used, this `post_get_document_with_metadata` interceptor runs after the + `post_get_document` interceptor. The (possibly modified) response returned by + `post_get_document` will be passed to + `post_get_document_with_metadata`. + """ + return response, metadata + def pre_import_documents( self, request: import_config.ImportDocumentsRequest, @@ -250,12 +322,35 @@ def post_import_documents( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_import_documents` interceptor runs + before the `post_import_documents_with_metadata` interceptor. """ return response + def post_import_documents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_import_documents_with_metadata` + interceptor in new development instead of the `post_import_documents` interceptor. + When both interceptors are used, this `post_import_documents_with_metadata` interceptor runs after the + `post_import_documents` interceptor. The (possibly modified) response returned by + `post_import_documents` will be passed to + `post_import_documents_with_metadata`. + """ + return response, metadata + def pre_list_documents( self, request: document_service.ListDocumentsRequest, @@ -275,12 +370,37 @@ def post_list_documents( ) -> document_service.ListDocumentsResponse: """Post-rpc interceptor for list_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_list_documents` interceptor runs + before the `post_list_documents_with_metadata` interceptor. """ return response + def post_list_documents_with_metadata( + self, + response: document_service.ListDocumentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + document_service.ListDocumentsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_list_documents_with_metadata` + interceptor in new development instead of the `post_list_documents` interceptor. + When both interceptors are used, this `post_list_documents_with_metadata` interceptor runs after the + `post_list_documents` interceptor. The (possibly modified) response returned by + `post_list_documents` will be passed to + `post_list_documents_with_metadata`. + """ + return response, metadata + def pre_purge_documents( self, request: purge_config.PurgeDocumentsRequest, @@ -300,12 +420,35 @@ def post_purge_documents( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_documents - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_documents_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_purge_documents` interceptor runs + before the `post_purge_documents_with_metadata` interceptor. """ return response + def post_purge_documents_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_documents + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_purge_documents_with_metadata` + interceptor in new development instead of the `post_purge_documents` interceptor. + When both interceptors are used, this `post_purge_documents_with_metadata` interceptor runs after the + `post_purge_documents` interceptor. The (possibly modified) response returned by + `post_purge_documents` will be passed to + `post_purge_documents_with_metadata`. + """ + return response, metadata + def pre_update_document( self, request: document_service.UpdateDocumentRequest, @@ -325,12 +468,35 @@ def post_update_document( ) -> gcd_document.Document: """Post-rpc interceptor for update_document - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_document_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DocumentService server but before - it is returned to user code. + it is returned to user code. This `post_update_document` interceptor runs + before the `post_update_document_with_metadata` interceptor. """ return response + def post_update_document_with_metadata( + self, + response: gcd_document.Document, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_document.Document, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_document + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DocumentService server but before it is returned to user code. + + We recommend only using this `post_update_document_with_metadata` + interceptor in new development instead of the `post_update_document` interceptor. + When both interceptors are used, this `post_update_document_with_metadata` interceptor runs after the + `post_update_document` interceptor. The (possibly modified) response returned by + `post_update_document` will be passed to + `post_update_document_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -786,6 +952,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_get_documents_metadata(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_get_documents_metadata_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -941,6 +1111,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1194,6 +1368,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1343,6 +1521,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1488,6 +1670,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1639,6 +1825,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_documents(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_purge_documents_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1790,6 +1980,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_document(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_document_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/engine_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/engine_service/client.py index bcd8087a94c0..349add7a2ffd 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/engine_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/engine_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -521,6 +523,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1778,16 +1807,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1833,16 +1866,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/engine_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/engine_service/transports/rest.py index 4457f32edcc4..8d83098395d9 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/engine_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/engine_service/transports/rest.py @@ -161,12 +161,35 @@ def post_create_engine( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_create_engine` interceptor runs + before the `post_create_engine_with_metadata` interceptor. """ return response + def post_create_engine_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_create_engine_with_metadata` + interceptor in new development instead of the `post_create_engine` interceptor. + When both interceptors are used, this `post_create_engine_with_metadata` interceptor runs after the + `post_create_engine` interceptor. The (possibly modified) response returned by + `post_create_engine` will be passed to + `post_create_engine_with_metadata`. + """ + return response, metadata + def pre_delete_engine( self, request: engine_service.DeleteEngineRequest, @@ -186,12 +209,35 @@ def post_delete_engine( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_delete_engine` interceptor runs + before the `post_delete_engine_with_metadata` interceptor. """ return response + def post_delete_engine_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_delete_engine_with_metadata` + interceptor in new development instead of the `post_delete_engine` interceptor. + When both interceptors are used, this `post_delete_engine_with_metadata` interceptor runs after the + `post_delete_engine` interceptor. The (possibly modified) response returned by + `post_delete_engine` will be passed to + `post_delete_engine_with_metadata`. + """ + return response, metadata + def pre_get_engine( self, request: engine_service.GetEngineRequest, @@ -209,12 +255,33 @@ def pre_get_engine( def post_get_engine(self, response: engine.Engine) -> engine.Engine: """Post-rpc interceptor for get_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_engine` interceptor runs + before the `post_get_engine_with_metadata` interceptor. """ return response + def post_get_engine_with_metadata( + self, response: engine.Engine, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_get_engine_with_metadata` + interceptor in new development instead of the `post_get_engine` interceptor. + When both interceptors are used, this `post_get_engine_with_metadata` interceptor runs after the + `post_get_engine` interceptor. The (possibly modified) response returned by + `post_get_engine` will be passed to + `post_get_engine_with_metadata`. + """ + return response, metadata + def pre_list_engines( self, request: engine_service.ListEnginesRequest, @@ -234,12 +301,37 @@ def post_list_engines( ) -> engine_service.ListEnginesResponse: """Post-rpc interceptor for list_engines - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_engines_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_list_engines` interceptor runs + before the `post_list_engines_with_metadata` interceptor. """ return response + def post_list_engines_with_metadata( + self, + response: engine_service.ListEnginesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + engine_service.ListEnginesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_engines + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_list_engines_with_metadata` + interceptor in new development instead of the `post_list_engines` interceptor. + When both interceptors are used, this `post_list_engines_with_metadata` interceptor runs after the + `post_list_engines` interceptor. The (possibly modified) response returned by + `post_list_engines` will be passed to + `post_list_engines_with_metadata`. + """ + return response, metadata + def pre_pause_engine( self, request: engine_service.PauseEngineRequest, @@ -257,12 +349,33 @@ def pre_pause_engine( def post_pause_engine(self, response: engine.Engine) -> engine.Engine: """Post-rpc interceptor for pause_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_pause_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_pause_engine` interceptor runs + before the `post_pause_engine_with_metadata` interceptor. """ return response + def post_pause_engine_with_metadata( + self, response: engine.Engine, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for pause_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_pause_engine_with_metadata` + interceptor in new development instead of the `post_pause_engine` interceptor. + When both interceptors are used, this `post_pause_engine_with_metadata` interceptor runs after the + `post_pause_engine` interceptor. The (possibly modified) response returned by + `post_pause_engine` will be passed to + `post_pause_engine_with_metadata`. + """ + return response, metadata + def pre_resume_engine( self, request: engine_service.ResumeEngineRequest, @@ -280,12 +393,33 @@ def pre_resume_engine( def post_resume_engine(self, response: engine.Engine) -> engine.Engine: """Post-rpc interceptor for resume_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_resume_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_resume_engine` interceptor runs + before the `post_resume_engine_with_metadata` interceptor. """ return response + def post_resume_engine_with_metadata( + self, response: engine.Engine, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for resume_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_resume_engine_with_metadata` + interceptor in new development instead of the `post_resume_engine` interceptor. + When both interceptors are used, this `post_resume_engine_with_metadata` interceptor runs after the + `post_resume_engine` interceptor. The (possibly modified) response returned by + `post_resume_engine` will be passed to + `post_resume_engine_with_metadata`. + """ + return response, metadata + def pre_tune_engine( self, request: engine_service.TuneEngineRequest, @@ -305,12 +439,35 @@ def post_tune_engine( ) -> operations_pb2.Operation: """Post-rpc interceptor for tune_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_tune_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_tune_engine` interceptor runs + before the `post_tune_engine_with_metadata` interceptor. """ return response + def post_tune_engine_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for tune_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_tune_engine_with_metadata` + interceptor in new development instead of the `post_tune_engine` interceptor. + When both interceptors are used, this `post_tune_engine_with_metadata` interceptor runs after the + `post_tune_engine` interceptor. The (possibly modified) response returned by + `post_tune_engine` will be passed to + `post_tune_engine_with_metadata`. + """ + return response, metadata + def pre_update_engine( self, request: engine_service.UpdateEngineRequest, @@ -328,12 +485,35 @@ def pre_update_engine( def post_update_engine(self, response: gcd_engine.Engine) -> gcd_engine.Engine: """Post-rpc interceptor for update_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EngineService server but before - it is returned to user code. + it is returned to user code. This `post_update_engine` interceptor runs + before the `post_update_engine_with_metadata` interceptor. """ return response + def post_update_engine_with_metadata( + self, + response: gcd_engine.Engine, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_engine.Engine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EngineService server but before it is returned to user code. + + We recommend only using this `post_update_engine_with_metadata` + interceptor in new development instead of the `post_update_engine` interceptor. + When both interceptors are used, this `post_update_engine_with_metadata` interceptor runs after the + `post_update_engine` interceptor. The (possibly modified) response returned by + `post_update_engine` will be passed to + `post_update_engine_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -786,6 +966,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -929,6 +1113,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1078,6 +1266,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1225,6 +1417,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_engines(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_engines_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1381,6 +1577,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_pause_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_pause_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1531,6 +1731,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_resume_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_resume_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1687,6 +1891,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_tune_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_tune_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1838,6 +2046,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/evaluation_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/evaluation_service/client.py index 023fd8fc2c42..6c05e376e4a9 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/evaluation_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/evaluation_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -654,6 +656,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1438,16 +1467,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1493,16 +1526,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/evaluation_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/evaluation_service/transports/rest.py index df57fcb5b490..eb2bd54e24c8 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/evaluation_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/evaluation_service/transports/rest.py @@ -128,12 +128,35 @@ def post_create_evaluation( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_evaluation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_evaluation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EvaluationService server but before - it is returned to user code. + it is returned to user code. This `post_create_evaluation` interceptor runs + before the `post_create_evaluation_with_metadata` interceptor. """ return response + def post_create_evaluation_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_evaluation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_create_evaluation_with_metadata` + interceptor in new development instead of the `post_create_evaluation` interceptor. + When both interceptors are used, this `post_create_evaluation_with_metadata` interceptor runs after the + `post_create_evaluation` interceptor. The (possibly modified) response returned by + `post_create_evaluation` will be passed to + `post_create_evaluation_with_metadata`. + """ + return response, metadata + def pre_get_evaluation( self, request: evaluation_service.GetEvaluationRequest, @@ -153,12 +176,35 @@ def post_get_evaluation( ) -> evaluation.Evaluation: """Post-rpc interceptor for get_evaluation - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_evaluation_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EvaluationService server but before - it is returned to user code. + it is returned to user code. This `post_get_evaluation` interceptor runs + before the `post_get_evaluation_with_metadata` interceptor. """ return response + def post_get_evaluation_with_metadata( + self, + response: evaluation.Evaluation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[evaluation.Evaluation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_evaluation + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_get_evaluation_with_metadata` + interceptor in new development instead of the `post_get_evaluation` interceptor. + When both interceptors are used, this `post_get_evaluation_with_metadata` interceptor runs after the + `post_get_evaluation` interceptor. The (possibly modified) response returned by + `post_get_evaluation` will be passed to + `post_get_evaluation_with_metadata`. + """ + return response, metadata + def pre_list_evaluation_results( self, request: evaluation_service.ListEvaluationResultsRequest, @@ -179,12 +225,38 @@ def post_list_evaluation_results( ) -> evaluation_service.ListEvaluationResultsResponse: """Post-rpc interceptor for list_evaluation_results - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_evaluation_results_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EvaluationService server but before - it is returned to user code. + it is returned to user code. This `post_list_evaluation_results` interceptor runs + before the `post_list_evaluation_results_with_metadata` interceptor. """ return response + def post_list_evaluation_results_with_metadata( + self, + response: evaluation_service.ListEvaluationResultsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + evaluation_service.ListEvaluationResultsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_evaluation_results + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_list_evaluation_results_with_metadata` + interceptor in new development instead of the `post_list_evaluation_results` interceptor. + When both interceptors are used, this `post_list_evaluation_results_with_metadata` interceptor runs after the + `post_list_evaluation_results` interceptor. The (possibly modified) response returned by + `post_list_evaluation_results` will be passed to + `post_list_evaluation_results_with_metadata`. + """ + return response, metadata + def pre_list_evaluations( self, request: evaluation_service.ListEvaluationsRequest, @@ -205,12 +277,38 @@ def post_list_evaluations( ) -> evaluation_service.ListEvaluationsResponse: """Post-rpc interceptor for list_evaluations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_evaluations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EvaluationService server but before - it is returned to user code. + it is returned to user code. This `post_list_evaluations` interceptor runs + before the `post_list_evaluations_with_metadata` interceptor. """ return response + def post_list_evaluations_with_metadata( + self, + response: evaluation_service.ListEvaluationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + evaluation_service.ListEvaluationsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_evaluations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EvaluationService server but before it is returned to user code. + + We recommend only using this `post_list_evaluations_with_metadata` + interceptor in new development instead of the `post_list_evaluations` interceptor. + When both interceptors are used, this `post_list_evaluations_with_metadata` interceptor runs after the + `post_list_evaluations` interceptor. The (possibly modified) response returned by + `post_list_evaluations` will be passed to + `post_list_evaluations_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -666,6 +764,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_evaluation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_evaluation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -813,6 +915,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_evaluation(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_evaluation_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -963,6 +1069,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_evaluation_results(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_evaluation_results_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1115,6 +1225,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_evaluations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_evaluations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/grounded_generation_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/grounded_generation_service/client.py index 35f8e2c35eb6..cfc79955f1cb 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/grounded_generation_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/grounded_generation_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -534,6 +536,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1064,16 +1093,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1119,16 +1152,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/grounded_generation_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/grounded_generation_service/transports/rest.py index c3d7ede2fd68..859a8cbc4f7e 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/grounded_generation_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/grounded_generation_service/transports/rest.py @@ -112,12 +112,38 @@ def post_check_grounding( ) -> grounded_generation_service.CheckGroundingResponse: """Post-rpc interceptor for check_grounding - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_check_grounding_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the GroundedGenerationService server but before - it is returned to user code. + it is returned to user code. This `post_check_grounding` interceptor runs + before the `post_check_grounding_with_metadata` interceptor. """ return response + def post_check_grounding_with_metadata( + self, + response: grounded_generation_service.CheckGroundingResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grounded_generation_service.CheckGroundingResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for check_grounding + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the GroundedGenerationService server but before it is returned to user code. + + We recommend only using this `post_check_grounding_with_metadata` + interceptor in new development instead of the `post_check_grounding` interceptor. + When both interceptors are used, this `post_check_grounding_with_metadata` interceptor runs after the + `post_check_grounding` interceptor. The (possibly modified) response returned by + `post_check_grounding` will be passed to + `post_check_grounding_with_metadata`. + """ + return response, metadata + def pre_generate_grounded_content( self, request: grounded_generation_service.GenerateGroundedContentRequest, @@ -138,12 +164,38 @@ def post_generate_grounded_content( ) -> grounded_generation_service.GenerateGroundedContentResponse: """Post-rpc interceptor for generate_grounded_content - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_generate_grounded_content_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the GroundedGenerationService server but before - it is returned to user code. + it is returned to user code. This `post_generate_grounded_content` interceptor runs + before the `post_generate_grounded_content_with_metadata` interceptor. """ return response + def post_generate_grounded_content_with_metadata( + self, + response: grounded_generation_service.GenerateGroundedContentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + grounded_generation_service.GenerateGroundedContentResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for generate_grounded_content + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the GroundedGenerationService server but before it is returned to user code. + + We recommend only using this `post_generate_grounded_content_with_metadata` + interceptor in new development instead of the `post_generate_grounded_content` interceptor. + When both interceptors are used, this `post_generate_grounded_content_with_metadata` interceptor runs after the + `post_generate_grounded_content` interceptor. The (possibly modified) response returned by + `post_generate_grounded_content` will be passed to + `post_generate_grounded_content_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -437,6 +489,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_check_grounding(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_check_grounding_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -595,6 +651,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_generate_grounded_content(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_generate_grounded_content_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/project_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/project_service/client.py index 369b68f41e0f..8ec1200ae477 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/project_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/project_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -483,6 +485,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -867,16 +896,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -922,16 +955,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/project_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/project_service/transports/rest.py index c8a8b9231e9f..34d79de7c32f 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/project_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/project_service/transports/rest.py @@ -103,12 +103,35 @@ def post_provision_project( ) -> operations_pb2.Operation: """Post-rpc interceptor for provision_project - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_provision_project_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ProjectService server but before - it is returned to user code. + it is returned to user code. This `post_provision_project` interceptor runs + before the `post_provision_project_with_metadata` interceptor. """ return response + def post_provision_project_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for provision_project + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ProjectService server but before it is returned to user code. + + We recommend only using this `post_provision_project_with_metadata` + interceptor in new development instead of the `post_provision_project` interceptor. + When both interceptors are used, this `post_provision_project_with_metadata` interceptor runs after the + `post_provision_project` interceptor. The (possibly modified) response returned by + `post_provision_project` will be passed to + `post_provision_project_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -563,6 +586,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_provision_project(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_provision_project_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/rank_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/rank_service/client.py index 472456d31cda..c768562a8466 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/rank_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/rank_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -484,6 +486,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -823,16 +852,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -878,16 +911,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/rank_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/rank_service/transports/rest.py index fc5c1b60ce30..5bc33308cca5 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/rank_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/rank_service/transports/rest.py @@ -101,12 +101,35 @@ def post_rank( ) -> rank_service.RankResponse: """Post-rpc interceptor for rank - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_rank_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the RankService server but before - it is returned to user code. + it is returned to user code. This `post_rank` interceptor runs + before the `post_rank_with_metadata` interceptor. """ return response + def post_rank_with_metadata( + self, + response: rank_service.RankResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[rank_service.RankResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for rank + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the RankService server but before it is returned to user code. + + We recommend only using this `post_rank_with_metadata` + interceptor in new development instead of the `post_rank` interceptor. + When both interceptors are used, this `post_rank_with_metadata` interceptor runs after the + `post_rank` interceptor. The (possibly modified) response returned by + `post_rank` will be passed to + `post_rank_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -395,6 +418,8 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_rank(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_rank_with_metadata(resp, response_metadata) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/recommendation_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/recommendation_service/client.py index 93efc2d0bb0d..3f84e6471637 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/recommendation_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/recommendation_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -562,6 +564,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -911,16 +940,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -966,16 +999,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/recommendation_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/recommendation_service/transports/rest.py index ff298830189b..a192875982a0 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/recommendation_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/recommendation_service/transports/rest.py @@ -103,12 +103,38 @@ def post_recommend( ) -> recommendation_service.RecommendResponse: """Post-rpc interceptor for recommend - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_recommend_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the RecommendationService server but before - it is returned to user code. + it is returned to user code. This `post_recommend` interceptor runs + before the `post_recommend_with_metadata` interceptor. """ return response + def post_recommend_with_metadata( + self, + response: recommendation_service.RecommendResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + recommendation_service.RecommendResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for recommend + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the RecommendationService server but before it is returned to user code. + + We recommend only using this `post_recommend_with_metadata` + interceptor in new development instead of the `post_recommend` interceptor. + When both interceptors are used, this `post_recommend_with_metadata` interceptor runs after the + `post_recommend` interceptor. The (possibly modified) response returned by + `post_recommend` will be passed to + `post_recommend_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -395,6 +421,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_recommend(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_recommend_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_service/client.py index aa76fdfc8f2c..4b33b0a4d68d 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -520,6 +522,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1540,16 +1569,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1595,16 +1628,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_service/transports/rest.py index 65604dea9693..98d752825c34 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_service/transports/rest.py @@ -144,12 +144,35 @@ def post_create_sample_query( ) -> gcd_sample_query.SampleQuery: """Post-rpc interceptor for create_sample_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_sample_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_create_sample_query` interceptor runs + before the `post_create_sample_query_with_metadata` interceptor. """ return response + def post_create_sample_query_with_metadata( + self, + response: gcd_sample_query.SampleQuery, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_sample_query.SampleQuery, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_sample_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_create_sample_query_with_metadata` + interceptor in new development instead of the `post_create_sample_query` interceptor. + When both interceptors are used, this `post_create_sample_query_with_metadata` interceptor runs after the + `post_create_sample_query` interceptor. The (possibly modified) response returned by + `post_create_sample_query` will be passed to + `post_create_sample_query_with_metadata`. + """ + return response, metadata + def pre_delete_sample_query( self, request: sample_query_service.DeleteSampleQueryRequest, @@ -185,12 +208,35 @@ def post_get_sample_query( ) -> sample_query.SampleQuery: """Post-rpc interceptor for get_sample_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_sample_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_get_sample_query` interceptor runs + before the `post_get_sample_query_with_metadata` interceptor. """ return response + def post_get_sample_query_with_metadata( + self, + response: sample_query.SampleQuery, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[sample_query.SampleQuery, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_sample_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_get_sample_query_with_metadata` + interceptor in new development instead of the `post_get_sample_query` interceptor. + When both interceptors are used, this `post_get_sample_query_with_metadata` interceptor runs after the + `post_get_sample_query` interceptor. The (possibly modified) response returned by + `post_get_sample_query` will be passed to + `post_get_sample_query_with_metadata`. + """ + return response, metadata + def pre_import_sample_queries( self, request: import_config.ImportSampleQueriesRequest, @@ -211,12 +257,35 @@ def post_import_sample_queries( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_sample_queries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_sample_queries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_import_sample_queries` interceptor runs + before the `post_import_sample_queries_with_metadata` interceptor. """ return response + def post_import_sample_queries_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_sample_queries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_import_sample_queries_with_metadata` + interceptor in new development instead of the `post_import_sample_queries` interceptor. + When both interceptors are used, this `post_import_sample_queries_with_metadata` interceptor runs after the + `post_import_sample_queries` interceptor. The (possibly modified) response returned by + `post_import_sample_queries` will be passed to + `post_import_sample_queries_with_metadata`. + """ + return response, metadata + def pre_list_sample_queries( self, request: sample_query_service.ListSampleQueriesRequest, @@ -237,12 +306,38 @@ def post_list_sample_queries( ) -> sample_query_service.ListSampleQueriesResponse: """Post-rpc interceptor for list_sample_queries - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_sample_queries_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_list_sample_queries` interceptor runs + before the `post_list_sample_queries_with_metadata` interceptor. """ return response + def post_list_sample_queries_with_metadata( + self, + response: sample_query_service.ListSampleQueriesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + sample_query_service.ListSampleQueriesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_sample_queries + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_list_sample_queries_with_metadata` + interceptor in new development instead of the `post_list_sample_queries` interceptor. + When both interceptors are used, this `post_list_sample_queries_with_metadata` interceptor runs after the + `post_list_sample_queries` interceptor. The (possibly modified) response returned by + `post_list_sample_queries` will be passed to + `post_list_sample_queries_with_metadata`. + """ + return response, metadata + def pre_update_sample_query( self, request: sample_query_service.UpdateSampleQueryRequest, @@ -263,12 +358,35 @@ def post_update_sample_query( ) -> gcd_sample_query.SampleQuery: """Post-rpc interceptor for update_sample_query - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_sample_query_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQueryService server but before - it is returned to user code. + it is returned to user code. This `post_update_sample_query` interceptor runs + before the `post_update_sample_query_with_metadata` interceptor. """ return response + def post_update_sample_query_with_metadata( + self, + response: gcd_sample_query.SampleQuery, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[gcd_sample_query.SampleQuery, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_sample_query + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQueryService server but before it is returned to user code. + + We recommend only using this `post_update_sample_query_with_metadata` + interceptor in new development instead of the `post_update_sample_query` interceptor. + When both interceptors are used, this `post_update_sample_query_with_metadata` interceptor runs after the + `post_update_sample_query` interceptor. The (possibly modified) response returned by + `post_update_sample_query` will be passed to + `post_update_sample_query_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -725,6 +843,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_sample_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_sample_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -983,6 +1105,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_sample_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_sample_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1137,6 +1263,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_sample_queries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_sample_queries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1285,6 +1415,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_sample_queries(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sample_queries_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1440,6 +1574,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_sample_query(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_sample_query_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_set_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_set_service/client.py index 79d1433af75a..1ebc5a3350dd 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_set_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_set_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -514,6 +516,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1432,16 +1461,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1487,16 +1520,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_set_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_set_service/transports/rest.py index 71d6ec3172ab..045bebe076a8 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_set_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/sample_query_set_service/transports/rest.py @@ -137,12 +137,37 @@ def post_create_sample_query_set( ) -> gcd_sample_query_set.SampleQuerySet: """Post-rpc interceptor for create_sample_query_set - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_sample_query_set_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQuerySetService server but before - it is returned to user code. + it is returned to user code. This `post_create_sample_query_set` interceptor runs + before the `post_create_sample_query_set_with_metadata` interceptor. """ return response + def post_create_sample_query_set_with_metadata( + self, + response: gcd_sample_query_set.SampleQuerySet, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_sample_query_set.SampleQuerySet, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_sample_query_set + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQuerySetService server but before it is returned to user code. + + We recommend only using this `post_create_sample_query_set_with_metadata` + interceptor in new development instead of the `post_create_sample_query_set` interceptor. + When both interceptors are used, this `post_create_sample_query_set_with_metadata` interceptor runs after the + `post_create_sample_query_set` interceptor. The (possibly modified) response returned by + `post_create_sample_query_set` will be passed to + `post_create_sample_query_set_with_metadata`. + """ + return response, metadata + def pre_delete_sample_query_set( self, request: sample_query_set_service.DeleteSampleQuerySetRequest, @@ -178,12 +203,37 @@ def post_get_sample_query_set( ) -> sample_query_set.SampleQuerySet: """Post-rpc interceptor for get_sample_query_set - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_sample_query_set_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQuerySetService server but before - it is returned to user code. + it is returned to user code. This `post_get_sample_query_set` interceptor runs + before the `post_get_sample_query_set_with_metadata` interceptor. """ return response + def post_get_sample_query_set_with_metadata( + self, + response: sample_query_set.SampleQuerySet, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + sample_query_set.SampleQuerySet, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_sample_query_set + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQuerySetService server but before it is returned to user code. + + We recommend only using this `post_get_sample_query_set_with_metadata` + interceptor in new development instead of the `post_get_sample_query_set` interceptor. + When both interceptors are used, this `post_get_sample_query_set_with_metadata` interceptor runs after the + `post_get_sample_query_set` interceptor. The (possibly modified) response returned by + `post_get_sample_query_set` will be passed to + `post_get_sample_query_set_with_metadata`. + """ + return response, metadata + def pre_list_sample_query_sets( self, request: sample_query_set_service.ListSampleQuerySetsRequest, @@ -204,12 +254,38 @@ def post_list_sample_query_sets( ) -> sample_query_set_service.ListSampleQuerySetsResponse: """Post-rpc interceptor for list_sample_query_sets - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_sample_query_sets_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQuerySetService server but before - it is returned to user code. + it is returned to user code. This `post_list_sample_query_sets` interceptor runs + before the `post_list_sample_query_sets_with_metadata` interceptor. """ return response + def post_list_sample_query_sets_with_metadata( + self, + response: sample_query_set_service.ListSampleQuerySetsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + sample_query_set_service.ListSampleQuerySetsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_sample_query_sets + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQuerySetService server but before it is returned to user code. + + We recommend only using this `post_list_sample_query_sets_with_metadata` + interceptor in new development instead of the `post_list_sample_query_sets` interceptor. + When both interceptors are used, this `post_list_sample_query_sets_with_metadata` interceptor runs after the + `post_list_sample_query_sets` interceptor. The (possibly modified) response returned by + `post_list_sample_query_sets` will be passed to + `post_list_sample_query_sets_with_metadata`. + """ + return response, metadata + def pre_update_sample_query_set( self, request: sample_query_set_service.UpdateSampleQuerySetRequest, @@ -230,12 +306,37 @@ def post_update_sample_query_set( ) -> gcd_sample_query_set.SampleQuerySet: """Post-rpc interceptor for update_sample_query_set - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_sample_query_set_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SampleQuerySetService server but before - it is returned to user code. + it is returned to user code. This `post_update_sample_query_set` interceptor runs + before the `post_update_sample_query_set_with_metadata` interceptor. """ return response + def post_update_sample_query_set_with_metadata( + self, + response: gcd_sample_query_set.SampleQuerySet, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_sample_query_set.SampleQuerySet, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_sample_query_set + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SampleQuerySetService server but before it is returned to user code. + + We recommend only using this `post_update_sample_query_set_with_metadata` + interceptor in new development instead of the `post_update_sample_query_set` interceptor. + When both interceptors are used, this `post_update_sample_query_set_with_metadata` interceptor runs after the + `post_update_sample_query_set` interceptor. The (possibly modified) response returned by + `post_update_sample_query_set` will be passed to + `post_update_sample_query_set_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -531,6 +632,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_sample_query_set(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_sample_query_set_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -797,6 +902,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_sample_query_set(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_sample_query_set_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -947,6 +1056,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_sample_query_sets(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_sample_query_sets_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1108,6 +1221,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_sample_query_set(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_sample_query_set_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/schema_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/schema_service/client.py index d470edadbe9d..b3aaa38ccfb0 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/schema_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/schema_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -517,6 +519,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1383,16 +1412,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1438,16 +1471,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/schema_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/schema_service/transports/rest.py index 367ac4f6da22..e23b28f44a51 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/schema_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/schema_service/transports/rest.py @@ -135,12 +135,35 @@ def post_create_schema( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_create_schema` interceptor runs + before the `post_create_schema_with_metadata` interceptor. """ return response + def post_create_schema_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_create_schema_with_metadata` + interceptor in new development instead of the `post_create_schema` interceptor. + When both interceptors are used, this `post_create_schema_with_metadata` interceptor runs after the + `post_create_schema` interceptor. The (possibly modified) response returned by + `post_create_schema` will be passed to + `post_create_schema_with_metadata`. + """ + return response, metadata + def pre_delete_schema( self, request: schema_service.DeleteSchemaRequest, @@ -160,12 +183,35 @@ def post_delete_schema( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_delete_schema` interceptor runs + before the `post_delete_schema_with_metadata` interceptor. """ return response + def post_delete_schema_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_delete_schema_with_metadata` + interceptor in new development instead of the `post_delete_schema` interceptor. + When both interceptors are used, this `post_delete_schema_with_metadata` interceptor runs after the + `post_delete_schema` interceptor. The (possibly modified) response returned by + `post_delete_schema` will be passed to + `post_delete_schema_with_metadata`. + """ + return response, metadata + def pre_get_schema( self, request: schema_service.GetSchemaRequest, @@ -183,12 +229,33 @@ def pre_get_schema( def post_get_schema(self, response: schema.Schema) -> schema.Schema: """Post-rpc interceptor for get_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_get_schema` interceptor runs + before the `post_get_schema_with_metadata` interceptor. """ return response + def post_get_schema_with_metadata( + self, response: schema.Schema, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[schema.Schema, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_get_schema_with_metadata` + interceptor in new development instead of the `post_get_schema` interceptor. + When both interceptors are used, this `post_get_schema_with_metadata` interceptor runs after the + `post_get_schema` interceptor. The (possibly modified) response returned by + `post_get_schema` will be passed to + `post_get_schema_with_metadata`. + """ + return response, metadata + def pre_list_schemas( self, request: schema_service.ListSchemasRequest, @@ -208,12 +275,37 @@ def post_list_schemas( ) -> schema_service.ListSchemasResponse: """Post-rpc interceptor for list_schemas - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_schemas_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_list_schemas` interceptor runs + before the `post_list_schemas_with_metadata` interceptor. """ return response + def post_list_schemas_with_metadata( + self, + response: schema_service.ListSchemasResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + schema_service.ListSchemasResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_schemas + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_list_schemas_with_metadata` + interceptor in new development instead of the `post_list_schemas` interceptor. + When both interceptors are used, this `post_list_schemas_with_metadata` interceptor runs after the + `post_list_schemas` interceptor. The (possibly modified) response returned by + `post_list_schemas` will be passed to + `post_list_schemas_with_metadata`. + """ + return response, metadata + def pre_update_schema( self, request: schema_service.UpdateSchemaRequest, @@ -233,12 +325,35 @@ def post_update_schema( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_schema - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_schema_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SchemaService server but before - it is returned to user code. + it is returned to user code. This `post_update_schema` interceptor runs + before the `post_update_schema_with_metadata` interceptor. """ return response + def post_update_schema_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_schema + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SchemaService server but before it is returned to user code. + + We recommend only using this `post_update_schema_with_metadata` + interceptor in new development instead of the `post_update_schema` interceptor. + When both interceptors are used, this `post_update_schema_with_metadata` interceptor runs after the + `post_update_schema` interceptor. The (possibly modified) response returned by + `post_update_schema` will be passed to + `post_update_schema_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -691,6 +806,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -834,6 +953,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -982,6 +1105,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1129,6 +1256,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_schemas(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_schemas_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1280,6 +1411,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_schema(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_schema_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_service/client.py index 7fc4c027965c..d92f58cd021b 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -611,6 +613,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1084,16 +1113,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1139,16 +1172,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_service/transports/rest.py index 8d4cb105fd0b..8ffbd9f89c3b 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_service/transports/rest.py @@ -109,12 +109,35 @@ def post_search( ) -> search_service.SearchResponse: """Post-rpc interceptor for search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchService server but before - it is returned to user code. + it is returned to user code. This `post_search` interceptor runs + before the `post_search_with_metadata` interceptor. """ return response + def post_search_with_metadata( + self, + response: search_service.SearchResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[search_service.SearchResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchService server but before it is returned to user code. + + We recommend only using this `post_search_with_metadata` + interceptor in new development instead of the `post_search` interceptor. + When both interceptors are used, this `post_search_with_metadata` interceptor runs after the + `post_search` interceptor. The (possibly modified) response returned by + `post_search` will be passed to + `post_search_with_metadata`. + """ + return response, metadata + def pre_search_lite( self, request: search_service.SearchRequest, @@ -132,12 +155,35 @@ def post_search_lite( ) -> search_service.SearchResponse: """Post-rpc interceptor for search_lite - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_lite_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchService server but before - it is returned to user code. + it is returned to user code. This `post_search_lite` interceptor runs + before the `post_search_lite_with_metadata` interceptor. """ return response + def post_search_lite_with_metadata( + self, + response: search_service.SearchResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[search_service.SearchResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search_lite + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchService server but before it is returned to user code. + + We recommend only using this `post_search_lite_with_metadata` + interceptor in new development instead of the `post_search_lite` interceptor. + When both interceptors are used, this `post_search_lite_with_metadata` interceptor runs after the + `post_search_lite` interceptor. The (possibly modified) response returned by + `post_search_lite` will be passed to + `post_search_lite_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -428,6 +474,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -585,6 +635,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_lite(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_lite_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_tuning_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_tuning_service/client.py index 6f111fe8fc34..94e200d0f0e7 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_tuning_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_tuning_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -515,6 +517,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -968,16 +997,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1023,16 +1056,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_tuning_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_tuning_service/transports/rest.py index 63696693afe4..01479945d7a7 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_tuning_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/search_tuning_service/transports/rest.py @@ -112,12 +112,38 @@ def post_list_custom_models( ) -> search_tuning_service.ListCustomModelsResponse: """Post-rpc interceptor for list_custom_models - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_custom_models_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchTuningService server but before - it is returned to user code. + it is returned to user code. This `post_list_custom_models` interceptor runs + before the `post_list_custom_models_with_metadata` interceptor. """ return response + def post_list_custom_models_with_metadata( + self, + response: search_tuning_service.ListCustomModelsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + search_tuning_service.ListCustomModelsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_custom_models + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchTuningService server but before it is returned to user code. + + We recommend only using this `post_list_custom_models_with_metadata` + interceptor in new development instead of the `post_list_custom_models` interceptor. + When both interceptors are used, this `post_list_custom_models_with_metadata` interceptor runs after the + `post_list_custom_models` interceptor. The (possibly modified) response returned by + `post_list_custom_models` will be passed to + `post_list_custom_models_with_metadata`. + """ + return response, metadata + def pre_train_custom_model( self, request: search_tuning_service.TrainCustomModelRequest, @@ -138,12 +164,35 @@ def post_train_custom_model( ) -> operations_pb2.Operation: """Post-rpc interceptor for train_custom_model - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_train_custom_model_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SearchTuningService server but before - it is returned to user code. + it is returned to user code. This `post_train_custom_model` interceptor runs + before the `post_train_custom_model_with_metadata` interceptor. """ return response + def post_train_custom_model_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for train_custom_model + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SearchTuningService server but before it is returned to user code. + + We recommend only using this `post_train_custom_model_with_metadata` + interceptor in new development instead of the `post_train_custom_model` interceptor. + When both interceptors are used, this `post_train_custom_model_with_metadata` interceptor runs after the + `post_train_custom_model` interceptor. The (possibly modified) response returned by + `post_train_custom_model` will be passed to + `post_train_custom_model_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -594,6 +643,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_custom_models(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_custom_models_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -748,6 +801,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_train_custom_model(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_train_custom_model_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/serving_config_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/serving_config_service/client.py index 320a24c75476..4d9a2e4a7855 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/serving_config_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/serving_config_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -498,6 +500,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1128,16 +1157,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1183,16 +1216,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/serving_config_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/serving_config_service/transports/rest.py index 61757debef56..4dd5b791d672 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/serving_config_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/serving_config_service/transports/rest.py @@ -124,12 +124,35 @@ def post_get_serving_config( ) -> serving_config.ServingConfig: """Post-rpc interceptor for get_serving_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_serving_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ServingConfigService server but before - it is returned to user code. + it is returned to user code. This `post_get_serving_config` interceptor runs + before the `post_get_serving_config_with_metadata` interceptor. """ return response + def post_get_serving_config_with_metadata( + self, + response: serving_config.ServingConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[serving_config.ServingConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_serving_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ServingConfigService server but before it is returned to user code. + + We recommend only using this `post_get_serving_config_with_metadata` + interceptor in new development instead of the `post_get_serving_config` interceptor. + When both interceptors are used, this `post_get_serving_config_with_metadata` interceptor runs after the + `post_get_serving_config` interceptor. The (possibly modified) response returned by + `post_get_serving_config` will be passed to + `post_get_serving_config_with_metadata`. + """ + return response, metadata + def pre_list_serving_configs( self, request: serving_config_service.ListServingConfigsRequest, @@ -150,12 +173,38 @@ def post_list_serving_configs( ) -> serving_config_service.ListServingConfigsResponse: """Post-rpc interceptor for list_serving_configs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_serving_configs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ServingConfigService server but before - it is returned to user code. + it is returned to user code. This `post_list_serving_configs` interceptor runs + before the `post_list_serving_configs_with_metadata` interceptor. """ return response + def post_list_serving_configs_with_metadata( + self, + response: serving_config_service.ListServingConfigsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + serving_config_service.ListServingConfigsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_serving_configs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ServingConfigService server but before it is returned to user code. + + We recommend only using this `post_list_serving_configs_with_metadata` + interceptor in new development instead of the `post_list_serving_configs` interceptor. + When both interceptors are used, this `post_list_serving_configs_with_metadata` interceptor runs after the + `post_list_serving_configs` interceptor. The (possibly modified) response returned by + `post_list_serving_configs` will be passed to + `post_list_serving_configs_with_metadata`. + """ + return response, metadata + def pre_update_serving_config( self, request: serving_config_service.UpdateServingConfigRequest, @@ -176,12 +225,37 @@ def post_update_serving_config( ) -> gcd_serving_config.ServingConfig: """Post-rpc interceptor for update_serving_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_serving_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the ServingConfigService server but before - it is returned to user code. + it is returned to user code. This `post_update_serving_config` interceptor runs + before the `post_update_serving_config_with_metadata` interceptor. """ return response + def post_update_serving_config_with_metadata( + self, + response: gcd_serving_config.ServingConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + gcd_serving_config.ServingConfig, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for update_serving_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the ServingConfigService server but before it is returned to user code. + + We recommend only using this `post_update_serving_config_with_metadata` + interceptor in new development instead of the `post_update_serving_config` interceptor. + When both interceptors are used, this `post_update_serving_config_with_metadata` interceptor runs after the + `post_update_serving_config` interceptor. The (possibly modified) response returned by + `post_update_serving_config` will be passed to + `post_update_serving_config_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -471,6 +545,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_serving_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_serving_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -619,6 +697,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_serving_configs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_serving_configs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -781,6 +863,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_serving_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_serving_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/site_search_engine_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/site_search_engine_service/client.py index 0f7530f5eaa3..63a884053a38 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/site_search_engine_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/site_search_engine_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -546,6 +548,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -2652,16 +2681,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -2707,16 +2740,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/site_search_engine_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/site_search_engine_service/transports/rest.py index f3e51c0403a7..1a8e6a8cf6f4 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/site_search_engine_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/site_search_engine_service/transports/rest.py @@ -219,12 +219,35 @@ def post_batch_create_target_sites( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_create_target_sites - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_create_target_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_batch_create_target_sites` interceptor runs + before the `post_batch_create_target_sites_with_metadata` interceptor. """ return response + def post_batch_create_target_sites_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_create_target_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_batch_create_target_sites_with_metadata` + interceptor in new development instead of the `post_batch_create_target_sites` interceptor. + When both interceptors are used, this `post_batch_create_target_sites_with_metadata` interceptor runs after the + `post_batch_create_target_sites` interceptor. The (possibly modified) response returned by + `post_batch_create_target_sites` will be passed to + `post_batch_create_target_sites_with_metadata`. + """ + return response, metadata + def pre_batch_verify_target_sites( self, request: site_search_engine_service.BatchVerifyTargetSitesRequest, @@ -245,12 +268,35 @@ def post_batch_verify_target_sites( ) -> operations_pb2.Operation: """Post-rpc interceptor for batch_verify_target_sites - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_batch_verify_target_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_batch_verify_target_sites` interceptor runs + before the `post_batch_verify_target_sites_with_metadata` interceptor. """ return response + def post_batch_verify_target_sites_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for batch_verify_target_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_batch_verify_target_sites_with_metadata` + interceptor in new development instead of the `post_batch_verify_target_sites` interceptor. + When both interceptors are used, this `post_batch_verify_target_sites_with_metadata` interceptor runs after the + `post_batch_verify_target_sites` interceptor. The (possibly modified) response returned by + `post_batch_verify_target_sites` will be passed to + `post_batch_verify_target_sites_with_metadata`. + """ + return response, metadata + def pre_create_sitemap( self, request: site_search_engine_service.CreateSitemapRequest, @@ -271,12 +317,35 @@ def post_create_sitemap( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_sitemap - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_sitemap_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_create_sitemap` interceptor runs + before the `post_create_sitemap_with_metadata` interceptor. """ return response + def post_create_sitemap_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_sitemap + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_create_sitemap_with_metadata` + interceptor in new development instead of the `post_create_sitemap` interceptor. + When both interceptors are used, this `post_create_sitemap_with_metadata` interceptor runs after the + `post_create_sitemap` interceptor. The (possibly modified) response returned by + `post_create_sitemap` will be passed to + `post_create_sitemap_with_metadata`. + """ + return response, metadata + def pre_create_target_site( self, request: site_search_engine_service.CreateTargetSiteRequest, @@ -297,12 +366,35 @@ def post_create_target_site( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_create_target_site` interceptor runs + before the `post_create_target_site_with_metadata` interceptor. """ return response + def post_create_target_site_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_create_target_site_with_metadata` + interceptor in new development instead of the `post_create_target_site` interceptor. + When both interceptors are used, this `post_create_target_site_with_metadata` interceptor runs after the + `post_create_target_site` interceptor. The (possibly modified) response returned by + `post_create_target_site` will be passed to + `post_create_target_site_with_metadata`. + """ + return response, metadata + def pre_delete_sitemap( self, request: site_search_engine_service.DeleteSitemapRequest, @@ -323,12 +415,35 @@ def post_delete_sitemap( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_sitemap - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_sitemap_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_delete_sitemap` interceptor runs + before the `post_delete_sitemap_with_metadata` interceptor. """ return response + def post_delete_sitemap_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_sitemap + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_delete_sitemap_with_metadata` + interceptor in new development instead of the `post_delete_sitemap` interceptor. + When both interceptors are used, this `post_delete_sitemap_with_metadata` interceptor runs after the + `post_delete_sitemap` interceptor. The (possibly modified) response returned by + `post_delete_sitemap` will be passed to + `post_delete_sitemap_with_metadata`. + """ + return response, metadata + def pre_delete_target_site( self, request: site_search_engine_service.DeleteTargetSiteRequest, @@ -349,12 +464,35 @@ def post_delete_target_site( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_delete_target_site` interceptor runs + before the `post_delete_target_site_with_metadata` interceptor. """ return response + def post_delete_target_site_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_delete_target_site_with_metadata` + interceptor in new development instead of the `post_delete_target_site` interceptor. + When both interceptors are used, this `post_delete_target_site_with_metadata` interceptor runs after the + `post_delete_target_site` interceptor. The (possibly modified) response returned by + `post_delete_target_site` will be passed to + `post_delete_target_site_with_metadata`. + """ + return response, metadata + def pre_disable_advanced_site_search( self, request: site_search_engine_service.DisableAdvancedSiteSearchRequest, @@ -375,12 +513,35 @@ def post_disable_advanced_site_search( ) -> operations_pb2.Operation: """Post-rpc interceptor for disable_advanced_site_search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_disable_advanced_site_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_disable_advanced_site_search` interceptor runs + before the `post_disable_advanced_site_search_with_metadata` interceptor. """ return response + def post_disable_advanced_site_search_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for disable_advanced_site_search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_disable_advanced_site_search_with_metadata` + interceptor in new development instead of the `post_disable_advanced_site_search` interceptor. + When both interceptors are used, this `post_disable_advanced_site_search_with_metadata` interceptor runs after the + `post_disable_advanced_site_search` interceptor. The (possibly modified) response returned by + `post_disable_advanced_site_search` will be passed to + `post_disable_advanced_site_search_with_metadata`. + """ + return response, metadata + def pre_enable_advanced_site_search( self, request: site_search_engine_service.EnableAdvancedSiteSearchRequest, @@ -401,12 +562,35 @@ def post_enable_advanced_site_search( ) -> operations_pb2.Operation: """Post-rpc interceptor for enable_advanced_site_search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_enable_advanced_site_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_enable_advanced_site_search` interceptor runs + before the `post_enable_advanced_site_search_with_metadata` interceptor. """ return response + def post_enable_advanced_site_search_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for enable_advanced_site_search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_enable_advanced_site_search_with_metadata` + interceptor in new development instead of the `post_enable_advanced_site_search` interceptor. + When both interceptors are used, this `post_enable_advanced_site_search_with_metadata` interceptor runs after the + `post_enable_advanced_site_search` interceptor. The (possibly modified) response returned by + `post_enable_advanced_site_search` will be passed to + `post_enable_advanced_site_search_with_metadata`. + """ + return response, metadata + def pre_fetch_domain_verification_status( self, request: site_search_engine_service.FetchDomainVerificationStatusRequest, @@ -427,12 +611,38 @@ def post_fetch_domain_verification_status( ) -> site_search_engine_service.FetchDomainVerificationStatusResponse: """Post-rpc interceptor for fetch_domain_verification_status - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_domain_verification_status_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_fetch_domain_verification_status` interceptor runs + before the `post_fetch_domain_verification_status_with_metadata` interceptor. """ return response + def post_fetch_domain_verification_status_with_metadata( + self, + response: site_search_engine_service.FetchDomainVerificationStatusResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine_service.FetchDomainVerificationStatusResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for fetch_domain_verification_status + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_fetch_domain_verification_status_with_metadata` + interceptor in new development instead of the `post_fetch_domain_verification_status` interceptor. + When both interceptors are used, this `post_fetch_domain_verification_status_with_metadata` interceptor runs after the + `post_fetch_domain_verification_status` interceptor. The (possibly modified) response returned by + `post_fetch_domain_verification_status` will be passed to + `post_fetch_domain_verification_status_with_metadata`. + """ + return response, metadata + def pre_fetch_sitemaps( self, request: site_search_engine_service.FetchSitemapsRequest, @@ -453,12 +663,38 @@ def post_fetch_sitemaps( ) -> site_search_engine_service.FetchSitemapsResponse: """Post-rpc interceptor for fetch_sitemaps - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_fetch_sitemaps_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_fetch_sitemaps` interceptor runs + before the `post_fetch_sitemaps_with_metadata` interceptor. """ return response + def post_fetch_sitemaps_with_metadata( + self, + response: site_search_engine_service.FetchSitemapsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine_service.FetchSitemapsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for fetch_sitemaps + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_fetch_sitemaps_with_metadata` + interceptor in new development instead of the `post_fetch_sitemaps` interceptor. + When both interceptors are used, this `post_fetch_sitemaps_with_metadata` interceptor runs after the + `post_fetch_sitemaps` interceptor. The (possibly modified) response returned by + `post_fetch_sitemaps` will be passed to + `post_fetch_sitemaps_with_metadata`. + """ + return response, metadata + def pre_get_site_search_engine( self, request: site_search_engine_service.GetSiteSearchEngineRequest, @@ -479,12 +715,37 @@ def post_get_site_search_engine( ) -> site_search_engine.SiteSearchEngine: """Post-rpc interceptor for get_site_search_engine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_site_search_engine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_site_search_engine` interceptor runs + before the `post_get_site_search_engine_with_metadata` interceptor. """ return response + def post_get_site_search_engine_with_metadata( + self, + response: site_search_engine.SiteSearchEngine, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine.SiteSearchEngine, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_site_search_engine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_get_site_search_engine_with_metadata` + interceptor in new development instead of the `post_get_site_search_engine` interceptor. + When both interceptors are used, this `post_get_site_search_engine_with_metadata` interceptor runs after the + `post_get_site_search_engine` interceptor. The (possibly modified) response returned by + `post_get_site_search_engine` will be passed to + `post_get_site_search_engine_with_metadata`. + """ + return response, metadata + def pre_get_target_site( self, request: site_search_engine_service.GetTargetSiteRequest, @@ -505,12 +766,35 @@ def post_get_target_site( ) -> site_search_engine.TargetSite: """Post-rpc interceptor for get_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_get_target_site` interceptor runs + before the `post_get_target_site_with_metadata` interceptor. """ return response + def post_get_target_site_with_metadata( + self, + response: site_search_engine.TargetSite, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[site_search_engine.TargetSite, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_get_target_site_with_metadata` + interceptor in new development instead of the `post_get_target_site` interceptor. + When both interceptors are used, this `post_get_target_site_with_metadata` interceptor runs after the + `post_get_target_site` interceptor. The (possibly modified) response returned by + `post_get_target_site` will be passed to + `post_get_target_site_with_metadata`. + """ + return response, metadata + def pre_list_target_sites( self, request: site_search_engine_service.ListTargetSitesRequest, @@ -531,12 +815,38 @@ def post_list_target_sites( ) -> site_search_engine_service.ListTargetSitesResponse: """Post-rpc interceptor for list_target_sites - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_target_sites_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_list_target_sites` interceptor runs + before the `post_list_target_sites_with_metadata` interceptor. """ return response + def post_list_target_sites_with_metadata( + self, + response: site_search_engine_service.ListTargetSitesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + site_search_engine_service.ListTargetSitesResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_target_sites + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_list_target_sites_with_metadata` + interceptor in new development instead of the `post_list_target_sites` interceptor. + When both interceptors are used, this `post_list_target_sites_with_metadata` interceptor runs after the + `post_list_target_sites` interceptor. The (possibly modified) response returned by + `post_list_target_sites` will be passed to + `post_list_target_sites_with_metadata`. + """ + return response, metadata + def pre_recrawl_uris( self, request: site_search_engine_service.RecrawlUrisRequest, @@ -557,12 +867,35 @@ def post_recrawl_uris( ) -> operations_pb2.Operation: """Post-rpc interceptor for recrawl_uris - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_recrawl_uris_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_recrawl_uris` interceptor runs + before the `post_recrawl_uris_with_metadata` interceptor. """ return response + def post_recrawl_uris_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for recrawl_uris + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_recrawl_uris_with_metadata` + interceptor in new development instead of the `post_recrawl_uris` interceptor. + When both interceptors are used, this `post_recrawl_uris_with_metadata` interceptor runs after the + `post_recrawl_uris` interceptor. The (possibly modified) response returned by + `post_recrawl_uris` will be passed to + `post_recrawl_uris_with_metadata`. + """ + return response, metadata + def pre_update_target_site( self, request: site_search_engine_service.UpdateTargetSiteRequest, @@ -583,12 +916,35 @@ def post_update_target_site( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_target_site - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_target_site_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the SiteSearchEngineService server but before - it is returned to user code. + it is returned to user code. This `post_update_target_site` interceptor runs + before the `post_update_target_site_with_metadata` interceptor. """ return response + def post_update_target_site_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_target_site + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the SiteSearchEngineService server but before it is returned to user code. + + We recommend only using this `post_update_target_site_with_metadata` + interceptor in new development instead of the `post_update_target_site` interceptor. + When both interceptors are used, this `post_update_target_site_with_metadata` interceptor runs after the + `post_update_target_site` interceptor. The (possibly modified) response returned by + `post_update_target_site` will be passed to + `post_update_target_site_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -1043,6 +1399,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_create_target_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_create_target_sites_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1195,6 +1555,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_batch_verify_target_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_batch_verify_target_sites_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1347,6 +1711,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_sitemap(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_sitemap_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1501,6 +1869,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1647,6 +2019,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_sitemap(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_sitemap_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1795,6 +2171,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1950,6 +2330,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_disable_advanced_site_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_disable_advanced_site_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2103,6 +2487,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_enable_advanced_site_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_enable_advanced_site_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2258,6 +2646,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_domain_verification_status(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_fetch_domain_verification_status_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2408,6 +2803,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_fetch_sitemaps(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_fetch_sitemaps_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2563,6 +2962,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_site_search_engine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_site_search_engine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2712,6 +3115,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2862,6 +3269,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_target_sites(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_target_sites_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3016,6 +3427,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_recrawl_uris(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_recrawl_uris_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3170,6 +3585,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_target_site(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_target_site_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_event_service/client.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_event_service/client.py index 3cab989ead94..2bbf91a98e7c 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_event_service/client.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_event_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -549,6 +551,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -1245,16 +1274,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -1300,16 +1333,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def cancel_operation( self, diff --git a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_event_service/transports/rest.py b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_event_service/transports/rest.py index c7b1e70e05cc..f91b390a3f30 100644 --- a/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_event_service/transports/rest.py +++ b/packages/google-cloud-discoveryengine/google/cloud/discoveryengine_v1beta/services/user_event_service/transports/rest.py @@ -134,12 +134,35 @@ def post_collect_user_event( ) -> httpbody_pb2.HttpBody: """Post-rpc interceptor for collect_user_event - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_collect_user_event_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_collect_user_event` interceptor runs + before the `post_collect_user_event_with_metadata` interceptor. """ return response + def post_collect_user_event_with_metadata( + self, + response: httpbody_pb2.HttpBody, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[httpbody_pb2.HttpBody, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for collect_user_event + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_collect_user_event_with_metadata` + interceptor in new development instead of the `post_collect_user_event` interceptor. + When both interceptors are used, this `post_collect_user_event_with_metadata` interceptor runs after the + `post_collect_user_event` interceptor. The (possibly modified) response returned by + `post_collect_user_event` will be passed to + `post_collect_user_event_with_metadata`. + """ + return response, metadata + def pre_import_user_events( self, request: import_config.ImportUserEventsRequest, @@ -159,12 +182,35 @@ def post_import_user_events( ) -> operations_pb2.Operation: """Post-rpc interceptor for import_user_events - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_import_user_events_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_import_user_events` interceptor runs + before the `post_import_user_events_with_metadata` interceptor. """ return response + def post_import_user_events_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for import_user_events + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_import_user_events_with_metadata` + interceptor in new development instead of the `post_import_user_events` interceptor. + When both interceptors are used, this `post_import_user_events_with_metadata` interceptor runs after the + `post_import_user_events` interceptor. The (possibly modified) response returned by + `post_import_user_events` will be passed to + `post_import_user_events_with_metadata`. + """ + return response, metadata + def pre_purge_user_events( self, request: purge_config.PurgeUserEventsRequest, @@ -184,12 +230,35 @@ def post_purge_user_events( ) -> operations_pb2.Operation: """Post-rpc interceptor for purge_user_events - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_purge_user_events_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_purge_user_events` interceptor runs + before the `post_purge_user_events_with_metadata` interceptor. """ return response + def post_purge_user_events_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for purge_user_events + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_purge_user_events_with_metadata` + interceptor in new development instead of the `post_purge_user_events` interceptor. + When both interceptors are used, this `post_purge_user_events_with_metadata` interceptor runs after the + `post_purge_user_events` interceptor. The (possibly modified) response returned by + `post_purge_user_events` will be passed to + `post_purge_user_events_with_metadata`. + """ + return response, metadata + def pre_write_user_event( self, request: user_event_service.WriteUserEventRequest, @@ -210,12 +279,35 @@ def post_write_user_event( ) -> user_event.UserEvent: """Post-rpc interceptor for write_user_event - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_write_user_event_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the UserEventService server but before - it is returned to user code. + it is returned to user code. This `post_write_user_event` interceptor runs + before the `post_write_user_event_with_metadata` interceptor. """ return response + def post_write_user_event_with_metadata( + self, + response: user_event.UserEvent, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[user_event.UserEvent, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for write_user_event + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the UserEventService server but before it is returned to user code. + + We recommend only using this `post_write_user_event_with_metadata` + interceptor in new development instead of the `post_write_user_event` interceptor. + When both interceptors are used, this `post_write_user_event_with_metadata` interceptor runs after the + `post_write_user_event` interceptor. The (possibly modified) response returned by + `post_write_user_event` will be passed to + `post_write_user_event_with_metadata`. + """ + return response, metadata + def pre_cancel_operation( self, request: operations_pb2.CancelOperationRequest, @@ -712,6 +804,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_collect_user_event(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_collect_user_event_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -863,6 +959,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_import_user_events(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_import_user_events_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1014,6 +1114,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_purge_user_events(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_purge_user_events_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1167,6 +1271,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_write_user_event(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_write_user_event_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1.json b/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1.json index 558b61c7883b..ab278ebe1339 100644 --- a/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1.json +++ b/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-discoveryengine", - "version": "0.13.5" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1alpha.json b/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1alpha.json index f23bdf041eb2..2d471998b925 100644 --- a/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1alpha.json +++ b/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1alpha.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-discoveryengine", - "version": "0.13.5" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1beta.json b/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1beta.json index 1dc95a67874e..e964eacc59eb 100644 --- a/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1beta.json +++ b/packages/google-cloud-discoveryengine/samples/generated_samples/snippet_metadata_google.cloud.discoveryengine.v1beta.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-discoveryengine", - "version": "0.13.5" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_completion_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_completion_service.py index 3d66399da10d..6a5e2854bdd3 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_completion_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_completion_service.py @@ -76,6 +76,13 @@ purge_config, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = CompletionServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = CompletionServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3538,10 +3588,13 @@ def test_complete_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CompletionServiceRestInterceptor, "post_complete_query" ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, "post_complete_query_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_complete_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = completion_service.CompleteQueryRequest.pb( completion_service.CompleteQueryRequest() ) @@ -3567,6 +3620,10 @@ def test_complete_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = completion_service.CompleteQueryResponse() + post_with_metadata.return_value = ( + completion_service.CompleteQueryResponse(), + metadata, + ) client.complete_query( request, @@ -3578,6 +3635,7 @@ def test_complete_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_suggestion_deny_list_entries_rest_bad_request( @@ -3663,11 +3721,15 @@ def test_import_suggestion_deny_list_entries_rest_interceptors(null_interceptor) transports.CompletionServiceRestInterceptor, "post_import_suggestion_deny_list_entries", ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_import_suggestion_deny_list_entries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_import_suggestion_deny_list_entries", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportSuggestionDenyListEntriesRequest.pb( import_config.ImportSuggestionDenyListEntriesRequest() ) @@ -3691,6 +3753,7 @@ def test_import_suggestion_deny_list_entries_rest_interceptors(null_interceptor) ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_suggestion_deny_list_entries( request, @@ -3702,6 +3765,7 @@ def test_import_suggestion_deny_list_entries_rest_interceptors(null_interceptor) pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_suggestion_deny_list_entries_rest_bad_request( @@ -3787,11 +3851,15 @@ def test_purge_suggestion_deny_list_entries_rest_interceptors(null_interceptor): transports.CompletionServiceRestInterceptor, "post_purge_suggestion_deny_list_entries", ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_purge_suggestion_deny_list_entries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_purge_suggestion_deny_list_entries", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeSuggestionDenyListEntriesRequest.pb( purge_config.PurgeSuggestionDenyListEntriesRequest() ) @@ -3815,6 +3883,7 @@ def test_purge_suggestion_deny_list_entries_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_suggestion_deny_list_entries( request, @@ -3826,6 +3895,7 @@ def test_purge_suggestion_deny_list_entries_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_completion_suggestions_rest_bad_request( @@ -3911,10 +3981,14 @@ def test_import_completion_suggestions_rest_interceptors(null_interceptor): transports.CompletionServiceRestInterceptor, "post_import_completion_suggestions", ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_import_completion_suggestions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_import_completion_suggestions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportCompletionSuggestionsRequest.pb( import_config.ImportCompletionSuggestionsRequest() ) @@ -3938,6 +4012,7 @@ def test_import_completion_suggestions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_completion_suggestions( request, @@ -3949,6 +4024,7 @@ def test_import_completion_suggestions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_completion_suggestions_rest_bad_request( @@ -4033,10 +4109,14 @@ def test_purge_completion_suggestions_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CompletionServiceRestInterceptor, "post_purge_completion_suggestions" ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_purge_completion_suggestions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_purge_completion_suggestions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeCompletionSuggestionsRequest.pb( purge_config.PurgeCompletionSuggestionsRequest() ) @@ -4060,6 +4140,7 @@ def test_purge_completion_suggestions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_completion_suggestions( request, @@ -4071,6 +4152,7 @@ def test_purge_completion_suggestions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_control_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_control_service.py index 1c69a48b17f3..762e2480c1b7 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_control_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_control_service.py @@ -67,6 +67,13 @@ from google.cloud.discoveryengine_v1.types import control as gcd_control from google.cloud.discoveryengine_v1.types import control_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -325,6 +332,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ControlServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ControlServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4545,10 +4595,13 @@ def test_create_control_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_create_control" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_create_control_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_create_control" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.CreateControlRequest.pb( control_service.CreateControlRequest() ) @@ -4572,6 +4625,7 @@ def test_create_control_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_control.Control() + post_with_metadata.return_value = gcd_control.Control(), metadata client.create_control( request, @@ -4583,6 +4637,7 @@ def test_create_control_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_control_rest_bad_request( @@ -4892,10 +4947,13 @@ def test_update_control_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_update_control" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_update_control_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_update_control" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.UpdateControlRequest.pb( control_service.UpdateControlRequest() ) @@ -4919,6 +4977,7 @@ def test_update_control_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_control.Control() + post_with_metadata.return_value = gcd_control.Control(), metadata client.update_control( request, @@ -4930,6 +4989,7 @@ def test_update_control_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_control_rest_bad_request(request_type=control_service.GetControlRequest): @@ -5026,10 +5086,13 @@ def test_get_control_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_get_control" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_get_control_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_get_control" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.GetControlRequest.pb( control_service.GetControlRequest() ) @@ -5053,6 +5116,7 @@ def test_get_control_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = control.Control() + post_with_metadata.return_value = control.Control(), metadata client.get_control( request, @@ -5064,6 +5128,7 @@ def test_get_control_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_controls_rest_bad_request( @@ -5148,10 +5213,13 @@ def test_list_controls_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_list_controls" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_list_controls_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_list_controls" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.ListControlsRequest.pb( control_service.ListControlsRequest() ) @@ -5177,6 +5245,10 @@ def test_list_controls_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = control_service.ListControlsResponse() + post_with_metadata.return_value = ( + control_service.ListControlsResponse(), + metadata, + ) client.list_controls( request, @@ -5188,6 +5260,7 @@ def test_list_controls_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_conversational_search_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_conversational_search_service.py index b0894d71fab3..a126189e51b5 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_conversational_search_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_conversational_search_service.py @@ -72,6 +72,13 @@ from google.cloud.discoveryengine_v1.types import session from google.cloud.discoveryengine_v1.types import session as gcd_session +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -355,6 +362,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationalSearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationalSearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -9253,11 +9303,15 @@ def test_converse_conversation_rest_interceptors(null_interceptor): transports.ConversationalSearchServiceRestInterceptor, "post_converse_conversation", ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_converse_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_converse_conversation", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.ConverseConversationRequest.pb( conversational_search_service.ConverseConversationRequest() ) @@ -9285,6 +9339,10 @@ def test_converse_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.ConverseConversationResponse() + post_with_metadata.return_value = ( + conversational_search_service.ConverseConversationResponse(), + metadata, + ) client.converse_conversation( request, @@ -9296,6 +9354,7 @@ def test_converse_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_conversation_rest_bad_request( @@ -9511,10 +9570,14 @@ def test_create_conversation_rest_interceptors(null_interceptor): transports.ConversationalSearchServiceRestInterceptor, "post_create_conversation", ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_create_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_create_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.CreateConversationRequest.pb( conversational_search_service.CreateConversationRequest() ) @@ -9540,6 +9603,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.Conversation() + post_with_metadata.return_value = gcd_conversation.Conversation(), metadata client.create_conversation( request, @@ -9551,6 +9615,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_conversation_rest_bad_request( @@ -9887,10 +9952,14 @@ def test_update_conversation_rest_interceptors(null_interceptor): transports.ConversationalSearchServiceRestInterceptor, "post_update_conversation", ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_update_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_update_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.UpdateConversationRequest.pb( conversational_search_service.UpdateConversationRequest() ) @@ -9916,6 +9985,7 @@ def test_update_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.Conversation() + post_with_metadata.return_value = gcd_conversation.Conversation(), metadata client.update_conversation( request, @@ -9927,6 +9997,7 @@ def test_update_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_rest_bad_request( @@ -10019,10 +10090,14 @@ def test_get_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_get_conversation" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_get_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_get_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.GetConversationRequest.pb( conversational_search_service.GetConversationRequest() ) @@ -10046,6 +10121,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.Conversation() + post_with_metadata.return_value = conversation.Conversation(), metadata client.get_conversation( request, @@ -10057,6 +10133,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_conversations_rest_bad_request( @@ -10143,10 +10220,14 @@ def test_list_conversations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_list_conversations" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_list_conversations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_list_conversations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.ListConversationsRequest.pb( conversational_search_service.ListConversationsRequest() ) @@ -10172,6 +10253,10 @@ def test_list_conversations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.ListConversationsResponse() + post_with_metadata.return_value = ( + conversational_search_service.ListConversationsResponse(), + metadata, + ) client.list_conversations( request, @@ -10183,6 +10268,7 @@ def test_list_conversations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_answer_query_rest_bad_request( @@ -10273,10 +10359,14 @@ def test_answer_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_answer_query" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_answer_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_answer_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.AnswerQueryRequest.pb( conversational_search_service.AnswerQueryRequest() ) @@ -10302,6 +10392,10 @@ def test_answer_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.AnswerQueryResponse() + post_with_metadata.return_value = ( + conversational_search_service.AnswerQueryResponse(), + metadata, + ) client.answer_query( request, @@ -10313,6 +10407,7 @@ def test_answer_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_answer_rest_bad_request( @@ -10413,10 +10508,14 @@ def test_get_answer_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_get_answer" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_get_answer_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_get_answer" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.GetAnswerRequest.pb( conversational_search_service.GetAnswerRequest() ) @@ -10440,6 +10539,7 @@ def test_get_answer_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = answer.Answer() + post_with_metadata.return_value = answer.Answer(), metadata client.get_answer( request, @@ -10451,6 +10551,7 @@ def test_get_answer_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_session_rest_bad_request( @@ -10621,10 +10722,14 @@ def test_create_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_create_session" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_create_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_create_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.CreateSessionRequest.pb( conversational_search_service.CreateSessionRequest() ) @@ -10648,6 +10753,7 @@ def test_create_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session.Session() + post_with_metadata.return_value = gcd_session.Session(), metadata client.create_session( request, @@ -10659,6 +10765,7 @@ def test_create_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_session_rest_bad_request( @@ -10950,10 +11057,14 @@ def test_update_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_update_session" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_update_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_update_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.UpdateSessionRequest.pb( conversational_search_service.UpdateSessionRequest() ) @@ -10977,6 +11088,7 @@ def test_update_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session.Session() + post_with_metadata.return_value = gcd_session.Session(), metadata client.update_session( request, @@ -10988,6 +11100,7 @@ def test_update_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_session_rest_bad_request( @@ -11080,10 +11193,14 @@ def test_get_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_get_session" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_get_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_get_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.GetSessionRequest.pb( conversational_search_service.GetSessionRequest() ) @@ -11107,6 +11224,7 @@ def test_get_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.Session() + post_with_metadata.return_value = session.Session(), metadata client.get_session( request, @@ -11118,6 +11236,7 @@ def test_get_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_sessions_rest_bad_request( @@ -11204,10 +11323,14 @@ def test_list_sessions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_list_sessions" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_list_sessions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_list_sessions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.ListSessionsRequest.pb( conversational_search_service.ListSessionsRequest() ) @@ -11233,6 +11356,10 @@ def test_list_sessions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.ListSessionsResponse() + post_with_metadata.return_value = ( + conversational_search_service.ListSessionsResponse(), + metadata, + ) client.list_sessions( request, @@ -11244,6 +11371,7 @@ def test_list_sessions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_data_store_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_data_store_service.py index 11bf2a84feee..26aad45e31ec 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_data_store_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_data_store_service.py @@ -82,6 +82,13 @@ from google.cloud.discoveryengine_v1.types import data_store from google.cloud.discoveryengine_v1.types import data_store as gcd_data_store +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -341,6 +348,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataStoreServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataStoreServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4655,10 +4705,14 @@ def test_create_data_store_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_create_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_create_data_store_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_create_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.CreateDataStoreRequest.pb( data_store_service.CreateDataStoreRequest() ) @@ -4682,6 +4736,7 @@ def test_create_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_data_store( request, @@ -4693,6 +4748,7 @@ def test_create_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_data_store_rest_bad_request( @@ -4787,10 +4843,13 @@ def test_get_data_store_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_get_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, "post_get_data_store_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_get_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.GetDataStoreRequest.pb( data_store_service.GetDataStoreRequest() ) @@ -4814,6 +4873,7 @@ def test_get_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = data_store.DataStore() + post_with_metadata.return_value = data_store.DataStore(), metadata client.get_data_store( request, @@ -4825,6 +4885,7 @@ def test_get_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_data_stores_rest_bad_request( @@ -4909,10 +4970,14 @@ def test_list_data_stores_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_list_data_stores" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_list_data_stores_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_list_data_stores" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.ListDataStoresRequest.pb( data_store_service.ListDataStoresRequest() ) @@ -4938,6 +5003,10 @@ def test_list_data_stores_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = data_store_service.ListDataStoresResponse() + post_with_metadata.return_value = ( + data_store_service.ListDataStoresResponse(), + metadata, + ) client.list_data_stores( request, @@ -4949,6 +5018,7 @@ def test_list_data_stores_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_data_store_rest_bad_request( @@ -5029,10 +5099,14 @@ def test_delete_data_store_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_delete_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_delete_data_store_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_delete_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.DeleteDataStoreRequest.pb( data_store_service.DeleteDataStoreRequest() ) @@ -5056,6 +5130,7 @@ def test_delete_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_data_store( request, @@ -5067,6 +5142,7 @@ def test_delete_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_data_store_rest_bad_request( @@ -5281,10 +5357,14 @@ def test_update_data_store_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_update_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_update_data_store_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_update_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.UpdateDataStoreRequest.pb( data_store_service.UpdateDataStoreRequest() ) @@ -5308,6 +5388,7 @@ def test_update_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_data_store.DataStore() + post_with_metadata.return_value = gcd_data_store.DataStore(), metadata client.update_data_store( request, @@ -5319,6 +5400,7 @@ def test_update_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_document_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_document_service.py index cfd86eff0c52..b827f3658547 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_document_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_document_service.py @@ -83,6 +83,13 @@ from google.cloud.discoveryengine_v1.types import document from google.cloud.discoveryengine_v1.types import document as gcd_document +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -341,6 +348,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DocumentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DocumentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6013,10 +6063,13 @@ def test_get_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_get_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_get_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_get_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.GetDocumentRequest.pb( document_service.GetDocumentRequest() ) @@ -6040,6 +6093,7 @@ def test_get_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document.Document() + post_with_metadata.return_value = document.Document(), metadata client.get_document( request, @@ -6051,6 +6105,7 @@ def test_get_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_documents_rest_bad_request( @@ -6139,10 +6194,13 @@ def test_list_documents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_list_documents" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_list_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_list_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.ListDocumentsRequest.pb( document_service.ListDocumentsRequest() ) @@ -6168,6 +6226,10 @@ def test_list_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document_service.ListDocumentsResponse() + post_with_metadata.return_value = ( + document_service.ListDocumentsResponse(), + metadata, + ) client.list_documents( request, @@ -6179,6 +6241,7 @@ def test_list_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_document_rest_bad_request( @@ -6371,10 +6434,13 @@ def test_create_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_create_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_create_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_create_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.CreateDocumentRequest.pb( document_service.CreateDocumentRequest() ) @@ -6398,6 +6464,7 @@ def test_create_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_document.Document() + post_with_metadata.return_value = gcd_document.Document(), metadata client.create_document( request, @@ -6409,6 +6476,7 @@ def test_create_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_document_rest_bad_request( @@ -6605,10 +6673,13 @@ def test_update_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_update_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_update_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_update_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.UpdateDocumentRequest.pb( document_service.UpdateDocumentRequest() ) @@ -6632,6 +6703,7 @@ def test_update_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_document.Document() + post_with_metadata.return_value = gcd_document.Document(), metadata client.update_document( request, @@ -6643,6 +6715,7 @@ def test_update_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_document_rest_bad_request( @@ -6840,10 +6913,13 @@ def test_import_documents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentServiceRestInterceptor, "post_import_documents" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_import_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_import_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportDocumentsRequest.pb( import_config.ImportDocumentsRequest() ) @@ -6867,6 +6943,7 @@ def test_import_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_documents( request, @@ -6878,6 +6955,7 @@ def test_import_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_documents_rest_bad_request( @@ -6962,10 +7040,13 @@ def test_purge_documents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentServiceRestInterceptor, "post_purge_documents" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_purge_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_purge_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeDocumentsRequest.pb( purge_config.PurgeDocumentsRequest() ) @@ -6989,6 +7070,7 @@ def test_purge_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_documents( request, @@ -7000,6 +7082,7 @@ def test_purge_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_get_documents_metadata_rest_bad_request( @@ -7087,10 +7170,14 @@ def test_batch_get_documents_metadata_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_batch_get_documents_metadata" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, + "post_batch_get_documents_metadata_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_batch_get_documents_metadata" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.BatchGetDocumentsMetadataRequest.pb( document_service.BatchGetDocumentsMetadataRequest() ) @@ -7116,6 +7203,10 @@ def test_batch_get_documents_metadata_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document_service.BatchGetDocumentsMetadataResponse() + post_with_metadata.return_value = ( + document_service.BatchGetDocumentsMetadataResponse(), + metadata, + ) client.batch_get_documents_metadata( request, @@ -7127,6 +7218,7 @@ def test_batch_get_documents_metadata_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_engine_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_engine_service.py index ca2de3026666..282af8a5bd44 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_engine_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_engine_service.py @@ -77,6 +77,13 @@ from google.cloud.discoveryengine_v1.types import engine as gcd_engine from google.cloud.discoveryengine_v1.types import engine_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -331,6 +338,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4597,10 +4647,13 @@ def test_create_engine_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EngineServiceRestInterceptor, "post_create_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_create_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_create_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.CreateEngineRequest.pb( engine_service.CreateEngineRequest() ) @@ -4624,6 +4677,7 @@ def test_create_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_engine( request, @@ -4635,6 +4689,7 @@ def test_create_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_engine_rest_bad_request( @@ -4719,10 +4774,13 @@ def test_delete_engine_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EngineServiceRestInterceptor, "post_delete_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_delete_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_delete_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.DeleteEngineRequest.pb( engine_service.DeleteEngineRequest() ) @@ -4746,6 +4804,7 @@ def test_delete_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_engine( request, @@ -4757,6 +4816,7 @@ def test_delete_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_engine_rest_bad_request( @@ -4948,10 +5008,13 @@ def test_update_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_update_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_update_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_update_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.UpdateEngineRequest.pb( engine_service.UpdateEngineRequest() ) @@ -4975,6 +5038,7 @@ def test_update_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_engine.Engine() + post_with_metadata.return_value = gcd_engine.Engine(), metadata client.update_engine( request, @@ -4986,6 +5050,7 @@ def test_update_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_engine_rest_bad_request(request_type=engine_service.GetEngineRequest): @@ -5082,10 +5147,13 @@ def test_get_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_get_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_get_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_get_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.GetEngineRequest.pb( engine_service.GetEngineRequest() ) @@ -5109,6 +5177,7 @@ def test_get_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine.Engine() + post_with_metadata.return_value = engine.Engine(), metadata client.get_engine( request, @@ -5120,6 +5189,7 @@ def test_get_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_engines_rest_bad_request(request_type=engine_service.ListEnginesRequest): @@ -5202,10 +5272,13 @@ def test_list_engines_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_list_engines" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_list_engines_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_list_engines" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.ListEnginesRequest.pb( engine_service.ListEnginesRequest() ) @@ -5231,6 +5304,7 @@ def test_list_engines_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine_service.ListEnginesResponse() + post_with_metadata.return_value = engine_service.ListEnginesResponse(), metadata client.list_engines( request, @@ -5242,6 +5316,7 @@ def test_list_engines_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_grounded_generation_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_grounded_generation_service.py index 0d1cf496db15..53d7497fda5b 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_grounded_generation_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_grounded_generation_service.py @@ -61,6 +61,13 @@ ) from google.cloud.discoveryengine_v1.types import grounded_generation_service, grounding +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -340,6 +347,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = GroundedGenerationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = GroundedGenerationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2393,11 +2443,15 @@ def test_generate_grounded_content_rest_interceptors(null_interceptor): transports.GroundedGenerationServiceRestInterceptor, "post_generate_grounded_content", ) as post, mock.patch.object( + transports.GroundedGenerationServiceRestInterceptor, + "post_generate_grounded_content_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.GroundedGenerationServiceRestInterceptor, "pre_generate_grounded_content", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = grounded_generation_service.GenerateGroundedContentRequest.pb( grounded_generation_service.GenerateGroundedContentRequest() ) @@ -2427,6 +2481,10 @@ def test_generate_grounded_content_rest_interceptors(null_interceptor): post.return_value = ( grounded_generation_service.GenerateGroundedContentResponse() ) + post_with_metadata.return_value = ( + grounded_generation_service.GenerateGroundedContentResponse(), + metadata, + ) client.generate_grounded_content( request, @@ -2438,6 +2496,7 @@ def test_generate_grounded_content_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_check_grounding_rest_bad_request( @@ -2528,10 +2587,14 @@ def test_check_grounding_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GroundedGenerationServiceRestInterceptor, "post_check_grounding" ) as post, mock.patch.object( + transports.GroundedGenerationServiceRestInterceptor, + "post_check_grounding_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.GroundedGenerationServiceRestInterceptor, "pre_check_grounding" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = grounded_generation_service.CheckGroundingRequest.pb( grounded_generation_service.CheckGroundingRequest() ) @@ -2557,6 +2620,10 @@ def test_check_grounding_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = grounded_generation_service.CheckGroundingResponse() + post_with_metadata.return_value = ( + grounded_generation_service.CheckGroundingResponse(), + metadata, + ) client.check_grounding( request, @@ -2568,6 +2635,7 @@ def test_check_grounding_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_project_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_project_service.py index 53292f403612..5b515f2539ab 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_project_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_project_service.py @@ -70,6 +70,13 @@ ) from google.cloud.discoveryengine_v1.types import project, project_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -328,6 +335,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ProjectServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ProjectServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1866,10 +1916,13 @@ def test_provision_project_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ProjectServiceRestInterceptor, "post_provision_project" ) as post, mock.patch.object( + transports.ProjectServiceRestInterceptor, "post_provision_project_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ProjectServiceRestInterceptor, "pre_provision_project" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = project_service.ProvisionProjectRequest.pb( project_service.ProvisionProjectRequest() ) @@ -1893,6 +1946,7 @@ def test_provision_project_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.provision_project( request, @@ -1904,6 +1958,7 @@ def test_provision_project_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_rank_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_rank_service.py index 5e446f3a7bf3..87fe0b150723 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_rank_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_rank_service.py @@ -61,6 +61,13 @@ ) from google.cloud.discoveryengine_v1.types import rank_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -300,6 +307,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = RankServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = RankServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1641,10 +1691,13 @@ def test_rank_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.RankServiceRestInterceptor, "post_rank" ) as post, mock.patch.object( + transports.RankServiceRestInterceptor, "post_rank_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.RankServiceRestInterceptor, "pre_rank" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = rank_service.RankRequest.pb(rank_service.RankRequest()) transcode.return_value = { "method": "post", @@ -1666,6 +1719,7 @@ def test_rank_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = rank_service.RankResponse() + post_with_metadata.return_value = rank_service.RankResponse(), metadata client.rank( request, @@ -1677,6 +1731,7 @@ def test_rank_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_recommendation_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_recommendation_service.py index 9c854fe0cab4..16a1cdda4bdc 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_recommendation_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_recommendation_service.py @@ -68,6 +68,13 @@ user_event, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = RecommendationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = RecommendationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1776,10 +1826,13 @@ def test_recommend_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.RecommendationServiceRestInterceptor, "post_recommend" ) as post, mock.patch.object( + transports.RecommendationServiceRestInterceptor, "post_recommend_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.RecommendationServiceRestInterceptor, "pre_recommend" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = recommendation_service.RecommendRequest.pb( recommendation_service.RecommendRequest() ) @@ -1805,6 +1858,10 @@ def test_recommend_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = recommendation_service.RecommendResponse() + post_with_metadata.return_value = ( + recommendation_service.RecommendResponse(), + metadata, + ) client.recommend( request, @@ -1816,6 +1873,7 @@ def test_recommend_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_schema_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_schema_service.py index 17025bf91f2c..4cd86d2e0e77 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_schema_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_schema_service.py @@ -75,6 +75,13 @@ from google.cloud.discoveryengine_v1.types import schema as gcd_schema from google.cloud.discoveryengine_v1.types import schema_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -329,6 +336,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SchemaServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SchemaServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4279,10 +4329,13 @@ def test_get_schema_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_get_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_get_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_get_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.GetSchemaRequest.pb( schema_service.GetSchemaRequest() ) @@ -4306,6 +4359,7 @@ def test_get_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema.Schema() + post_with_metadata.return_value = schema.Schema(), metadata client.get_schema( request, @@ -4317,6 +4371,7 @@ def test_get_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_schemas_rest_bad_request(request_type=schema_service.ListSchemasRequest): @@ -4399,10 +4454,13 @@ def test_list_schemas_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_list_schemas" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_list_schemas_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_list_schemas" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.ListSchemasRequest.pb( schema_service.ListSchemasRequest() ) @@ -4428,6 +4486,7 @@ def test_list_schemas_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema_service.ListSchemasResponse() + post_with_metadata.return_value = schema_service.ListSchemasResponse(), metadata client.list_schemas( request, @@ -4439,6 +4498,7 @@ def test_list_schemas_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_schema_rest_bad_request( @@ -4591,10 +4651,13 @@ def test_create_schema_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SchemaServiceRestInterceptor, "post_create_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_create_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_create_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.CreateSchemaRequest.pb( schema_service.CreateSchemaRequest() ) @@ -4618,6 +4681,7 @@ def test_create_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_schema( request, @@ -4629,6 +4693,7 @@ def test_create_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_schema_rest_bad_request( @@ -4789,10 +4854,13 @@ def test_update_schema_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SchemaServiceRestInterceptor, "post_update_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_update_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_update_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.UpdateSchemaRequest.pb( schema_service.UpdateSchemaRequest() ) @@ -4816,6 +4884,7 @@ def test_update_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_schema( request, @@ -4827,6 +4896,7 @@ def test_update_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_schema_rest_bad_request( @@ -4911,10 +4981,13 @@ def test_delete_schema_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SchemaServiceRestInterceptor, "post_delete_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_delete_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_delete_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.DeleteSchemaRequest.pb( schema_service.DeleteSchemaRequest() ) @@ -4938,6 +5011,7 @@ def test_delete_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_schema( request, @@ -4949,6 +5023,7 @@ def test_delete_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_search_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_search_service.py index f3b5c71d262f..3c5b33b5fcdf 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_search_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_search_service.py @@ -63,6 +63,13 @@ ) from google.cloud.discoveryengine_v1.types import common, search_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -317,6 +324,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2692,10 +2742,13 @@ def test_search_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SearchServiceRestInterceptor, "post_search" ) as post, mock.patch.object( + transports.SearchServiceRestInterceptor, "post_search_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SearchServiceRestInterceptor, "pre_search" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_service.SearchRequest.pb(search_service.SearchRequest()) transcode.return_value = { "method": "post", @@ -2719,6 +2772,7 @@ def test_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = search_service.SearchResponse() + post_with_metadata.return_value = search_service.SearchResponse(), metadata client.search( request, @@ -2730,6 +2784,7 @@ def test_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_search_lite_rest_bad_request(request_type=search_service.SearchRequest): @@ -2824,10 +2879,13 @@ def test_search_lite_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SearchServiceRestInterceptor, "post_search_lite" ) as post, mock.patch.object( + transports.SearchServiceRestInterceptor, "post_search_lite_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SearchServiceRestInterceptor, "pre_search_lite" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_service.SearchRequest.pb(search_service.SearchRequest()) transcode.return_value = { "method": "post", @@ -2851,6 +2909,7 @@ def test_search_lite_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = search_service.SearchResponse() + post_with_metadata.return_value = search_service.SearchResponse(), metadata client.search_lite( request, @@ -2862,6 +2921,7 @@ def test_search_lite_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_search_tuning_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_search_tuning_service.py index 6e20c9d9a6c3..a5bce0bacb9c 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_search_tuning_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_search_tuning_service.py @@ -74,6 +74,13 @@ search_tuning_service, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -347,6 +354,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SearchTuningServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SearchTuningServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2209,10 +2259,14 @@ def test_train_custom_model_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SearchTuningServiceRestInterceptor, "post_train_custom_model" ) as post, mock.patch.object( + transports.SearchTuningServiceRestInterceptor, + "post_train_custom_model_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SearchTuningServiceRestInterceptor, "pre_train_custom_model" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_tuning_service.TrainCustomModelRequest.pb( search_tuning_service.TrainCustomModelRequest() ) @@ -2236,6 +2290,7 @@ def test_train_custom_model_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.train_custom_model( request, @@ -2247,6 +2302,7 @@ def test_train_custom_model_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_custom_models_rest_bad_request( @@ -2332,10 +2388,14 @@ def test_list_custom_models_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SearchTuningServiceRestInterceptor, "post_list_custom_models" ) as post, mock.patch.object( + transports.SearchTuningServiceRestInterceptor, + "post_list_custom_models_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SearchTuningServiceRestInterceptor, "pre_list_custom_models" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_tuning_service.ListCustomModelsRequest.pb( search_tuning_service.ListCustomModelsRequest() ) @@ -2361,6 +2421,10 @@ def test_list_custom_models_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = search_tuning_service.ListCustomModelsResponse() + post_with_metadata.return_value = ( + search_tuning_service.ListCustomModelsResponse(), + metadata, + ) client.list_custom_models( request, @@ -2372,6 +2436,7 @@ def test_list_custom_models_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_site_search_engine_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_site_search_engine_service.py index 8e5abfd09483..f8d0fd78b211 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_site_search_engine_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_site_search_engine_service.py @@ -76,6 +76,13 @@ site_search_engine_service, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -351,6 +358,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SiteSearchEngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SiteSearchEngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -8069,10 +8119,14 @@ def test_get_site_search_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_get_site_search_engine" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_get_site_search_engine_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_get_site_search_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.GetSiteSearchEngineRequest.pb( site_search_engine_service.GetSiteSearchEngineRequest() ) @@ -8098,6 +8152,10 @@ def test_get_site_search_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine.SiteSearchEngine() + post_with_metadata.return_value = ( + site_search_engine.SiteSearchEngine(), + metadata, + ) client.get_site_search_engine( request, @@ -8109,6 +8167,7 @@ def test_get_site_search_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_target_site_rest_bad_request( @@ -8277,10 +8336,14 @@ def test_create_target_site_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_create_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_create_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_create_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.CreateTargetSiteRequest.pb( site_search_engine_service.CreateTargetSiteRequest() ) @@ -8304,6 +8367,7 @@ def test_create_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_target_site( request, @@ -8315,6 +8379,7 @@ def test_create_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_create_target_sites_rest_bad_request( @@ -8400,11 +8465,15 @@ def test_batch_create_target_sites_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_batch_create_target_sites", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_batch_create_target_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_batch_create_target_sites", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.BatchCreateTargetSitesRequest.pb( site_search_engine_service.BatchCreateTargetSitesRequest() ) @@ -8428,6 +8497,7 @@ def test_batch_create_target_sites_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_create_target_sites( request, @@ -8439,6 +8509,7 @@ def test_batch_create_target_sites_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_target_site_rest_bad_request( @@ -8541,10 +8612,14 @@ def test_get_target_site_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_get_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_get_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_get_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.GetTargetSiteRequest.pb( site_search_engine_service.GetTargetSiteRequest() ) @@ -8570,6 +8645,7 @@ def test_get_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine.TargetSite() + post_with_metadata.return_value = site_search_engine.TargetSite(), metadata client.get_target_site( request, @@ -8581,6 +8657,7 @@ def test_get_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_target_site_rest_bad_request( @@ -8753,10 +8830,14 @@ def test_update_target_site_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_update_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_update_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_update_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.UpdateTargetSiteRequest.pb( site_search_engine_service.UpdateTargetSiteRequest() ) @@ -8780,6 +8861,7 @@ def test_update_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_target_site( request, @@ -8791,6 +8873,7 @@ def test_update_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_target_site_rest_bad_request( @@ -8875,10 +8958,14 @@ def test_delete_target_site_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_delete_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_delete_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_delete_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.DeleteTargetSiteRequest.pb( site_search_engine_service.DeleteTargetSiteRequest() ) @@ -8902,6 +8989,7 @@ def test_delete_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_target_site( request, @@ -8913,6 +9001,7 @@ def test_delete_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_target_sites_rest_bad_request( @@ -9005,10 +9094,14 @@ def test_list_target_sites_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_list_target_sites" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_list_target_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_list_target_sites" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.ListTargetSitesRequest.pb( site_search_engine_service.ListTargetSitesRequest() ) @@ -9034,6 +9127,10 @@ def test_list_target_sites_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine_service.ListTargetSitesResponse() + post_with_metadata.return_value = ( + site_search_engine_service.ListTargetSitesResponse(), + metadata, + ) client.list_target_sites( request, @@ -9045,6 +9142,7 @@ def test_list_target_sites_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_enable_advanced_site_search_rest_bad_request( @@ -9130,11 +9228,15 @@ def test_enable_advanced_site_search_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_enable_advanced_site_search", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_enable_advanced_site_search_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_enable_advanced_site_search", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.EnableAdvancedSiteSearchRequest.pb( site_search_engine_service.EnableAdvancedSiteSearchRequest() ) @@ -9158,6 +9260,7 @@ def test_enable_advanced_site_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.enable_advanced_site_search( request, @@ -9169,6 +9272,7 @@ def test_enable_advanced_site_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_disable_advanced_site_search_rest_bad_request( @@ -9254,11 +9358,15 @@ def test_disable_advanced_site_search_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_disable_advanced_site_search", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_disable_advanced_site_search_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_disable_advanced_site_search", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.DisableAdvancedSiteSearchRequest.pb( site_search_engine_service.DisableAdvancedSiteSearchRequest() ) @@ -9282,6 +9390,7 @@ def test_disable_advanced_site_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.disable_advanced_site_search( request, @@ -9293,6 +9402,7 @@ def test_disable_advanced_site_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_recrawl_uris_rest_bad_request( @@ -9377,10 +9487,14 @@ def test_recrawl_uris_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_recrawl_uris" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_recrawl_uris_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_recrawl_uris" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.RecrawlUrisRequest.pb( site_search_engine_service.RecrawlUrisRequest() ) @@ -9404,6 +9518,7 @@ def test_recrawl_uris_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.recrawl_uris( request, @@ -9415,6 +9530,7 @@ def test_recrawl_uris_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_verify_target_sites_rest_bad_request( @@ -9500,11 +9616,15 @@ def test_batch_verify_target_sites_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_batch_verify_target_sites", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_batch_verify_target_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_batch_verify_target_sites", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.BatchVerifyTargetSitesRequest.pb( site_search_engine_service.BatchVerifyTargetSitesRequest() ) @@ -9528,6 +9648,7 @@ def test_batch_verify_target_sites_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_verify_target_sites( request, @@ -9539,6 +9660,7 @@ def test_batch_verify_target_sites_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_domain_verification_status_rest_bad_request( @@ -9634,11 +9756,15 @@ def test_fetch_domain_verification_status_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_fetch_domain_verification_status", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_fetch_domain_verification_status_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_fetch_domain_verification_status", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.FetchDomainVerificationStatusRequest.pb( site_search_engine_service.FetchDomainVerificationStatusRequest() ) @@ -9668,6 +9794,10 @@ def test_fetch_domain_verification_status_rest_interceptors(null_interceptor): post.return_value = ( site_search_engine_service.FetchDomainVerificationStatusResponse() ) + post_with_metadata.return_value = ( + site_search_engine_service.FetchDomainVerificationStatusResponse(), + metadata, + ) client.fetch_domain_verification_status( request, @@ -9679,6 +9809,7 @@ def test_fetch_domain_verification_status_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_user_event_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_user_event_service.py index 213b446b8237..775fdc8af782 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_user_event_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1/test_user_event_service.py @@ -81,6 +81,13 @@ user_event_service, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -340,6 +347,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = UserEventServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = UserEventServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3287,10 +3337,14 @@ def test_write_user_event_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.UserEventServiceRestInterceptor, "post_write_user_event" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_write_user_event_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_write_user_event" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = user_event_service.WriteUserEventRequest.pb( user_event_service.WriteUserEventRequest() ) @@ -3314,6 +3368,7 @@ def test_write_user_event_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = user_event.UserEvent() + post_with_metadata.return_value = user_event.UserEvent(), metadata client.write_user_event( request, @@ -3325,6 +3380,7 @@ def test_write_user_event_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_collect_user_event_rest_bad_request( @@ -3408,10 +3464,14 @@ def test_collect_user_event_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.UserEventServiceRestInterceptor, "post_collect_user_event" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_collect_user_event_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_collect_user_event" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = user_event_service.CollectUserEventRequest.pb( user_event_service.CollectUserEventRequest() ) @@ -3435,6 +3495,7 @@ def test_collect_user_event_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = httpbody_pb2.HttpBody() + post_with_metadata.return_value = httpbody_pb2.HttpBody(), metadata client.collect_user_event( request, @@ -3446,6 +3507,7 @@ def test_collect_user_event_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_user_events_rest_bad_request( @@ -3526,10 +3588,14 @@ def test_purge_user_events_rest_interceptors(null_interceptor): ), mock.patch.object( transports.UserEventServiceRestInterceptor, "post_purge_user_events" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_purge_user_events_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_purge_user_events" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeUserEventsRequest.pb( purge_config.PurgeUserEventsRequest() ) @@ -3553,6 +3619,7 @@ def test_purge_user_events_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_user_events( request, @@ -3564,6 +3631,7 @@ def test_purge_user_events_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_user_events_rest_bad_request( @@ -3644,10 +3712,14 @@ def test_import_user_events_rest_interceptors(null_interceptor): ), mock.patch.object( transports.UserEventServiceRestInterceptor, "post_import_user_events" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_import_user_events_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_import_user_events" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportUserEventsRequest.pb( import_config.ImportUserEventsRequest() ) @@ -3671,6 +3743,7 @@ def test_import_user_events_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_user_events( request, @@ -3682,6 +3755,7 @@ def test_import_user_events_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_acl_config_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_acl_config_service.py index e863108bf2a9..0fb4b08a0443 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_acl_config_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_acl_config_service.py @@ -65,6 +65,13 @@ common, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -324,6 +331,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = AclConfigServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = AclConfigServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2351,10 +2401,14 @@ def test_update_acl_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AclConfigServiceRestInterceptor, "post_update_acl_config" ) as post, mock.patch.object( + transports.AclConfigServiceRestInterceptor, + "post_update_acl_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.AclConfigServiceRestInterceptor, "pre_update_acl_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = acl_config_service.UpdateAclConfigRequest.pb( acl_config_service.UpdateAclConfigRequest() ) @@ -2378,6 +2432,7 @@ def test_update_acl_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = acl_config.AclConfig() + post_with_metadata.return_value = acl_config.AclConfig(), metadata client.update_acl_config( request, @@ -2389,6 +2444,7 @@ def test_update_acl_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_acl_config_rest_bad_request( @@ -2473,10 +2529,13 @@ def test_get_acl_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.AclConfigServiceRestInterceptor, "post_get_acl_config" ) as post, mock.patch.object( + transports.AclConfigServiceRestInterceptor, "post_get_acl_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.AclConfigServiceRestInterceptor, "pre_get_acl_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = acl_config_service.GetAclConfigRequest.pb( acl_config_service.GetAclConfigRequest() ) @@ -2500,6 +2559,7 @@ def test_get_acl_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = acl_config.AclConfig() + post_with_metadata.return_value = acl_config.AclConfig(), metadata client.get_acl_config( request, @@ -2511,6 +2571,7 @@ def test_get_acl_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_chunk_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_chunk_service.py index f39e961c6f4d..bf0e71f98009 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_chunk_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_chunk_service.py @@ -63,6 +63,13 @@ ) from google.cloud.discoveryengine_v1alpha.types import chunk, chunk_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -306,6 +313,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ChunkServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ChunkServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2638,10 +2688,13 @@ def test_get_chunk_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ChunkServiceRestInterceptor, "post_get_chunk" ) as post, mock.patch.object( + transports.ChunkServiceRestInterceptor, "post_get_chunk_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ChunkServiceRestInterceptor, "pre_get_chunk" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = chunk_service.GetChunkRequest.pb(chunk_service.GetChunkRequest()) transcode.return_value = { "method": "post", @@ -2663,6 +2716,7 @@ def test_get_chunk_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = chunk.Chunk() + post_with_metadata.return_value = chunk.Chunk(), metadata client.get_chunk( request, @@ -2674,6 +2728,7 @@ def test_get_chunk_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_chunks_rest_bad_request(request_type=chunk_service.ListChunksRequest): @@ -2760,10 +2815,13 @@ def test_list_chunks_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ChunkServiceRestInterceptor, "post_list_chunks" ) as post, mock.patch.object( + transports.ChunkServiceRestInterceptor, "post_list_chunks_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ChunkServiceRestInterceptor, "pre_list_chunks" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = chunk_service.ListChunksRequest.pb( chunk_service.ListChunksRequest() ) @@ -2789,6 +2847,7 @@ def test_list_chunks_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = chunk_service.ListChunksResponse() + post_with_metadata.return_value = chunk_service.ListChunksResponse(), metadata client.list_chunks( request, @@ -2800,6 +2859,7 @@ def test_list_chunks_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_completion_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_completion_service.py index 4ac78f140bdb..e04d1b81df03 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_completion_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_completion_service.py @@ -76,6 +76,13 @@ purge_config, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = CompletionServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = CompletionServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3538,10 +3588,13 @@ def test_complete_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CompletionServiceRestInterceptor, "post_complete_query" ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, "post_complete_query_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_complete_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = completion_service.CompleteQueryRequest.pb( completion_service.CompleteQueryRequest() ) @@ -3567,6 +3620,10 @@ def test_complete_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = completion_service.CompleteQueryResponse() + post_with_metadata.return_value = ( + completion_service.CompleteQueryResponse(), + metadata, + ) client.complete_query( request, @@ -3578,6 +3635,7 @@ def test_complete_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_suggestion_deny_list_entries_rest_bad_request( @@ -3663,11 +3721,15 @@ def test_import_suggestion_deny_list_entries_rest_interceptors(null_interceptor) transports.CompletionServiceRestInterceptor, "post_import_suggestion_deny_list_entries", ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_import_suggestion_deny_list_entries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_import_suggestion_deny_list_entries", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportSuggestionDenyListEntriesRequest.pb( import_config.ImportSuggestionDenyListEntriesRequest() ) @@ -3691,6 +3753,7 @@ def test_import_suggestion_deny_list_entries_rest_interceptors(null_interceptor) ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_suggestion_deny_list_entries( request, @@ -3702,6 +3765,7 @@ def test_import_suggestion_deny_list_entries_rest_interceptors(null_interceptor) pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_suggestion_deny_list_entries_rest_bad_request( @@ -3787,11 +3851,15 @@ def test_purge_suggestion_deny_list_entries_rest_interceptors(null_interceptor): transports.CompletionServiceRestInterceptor, "post_purge_suggestion_deny_list_entries", ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_purge_suggestion_deny_list_entries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_purge_suggestion_deny_list_entries", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeSuggestionDenyListEntriesRequest.pb( purge_config.PurgeSuggestionDenyListEntriesRequest() ) @@ -3815,6 +3883,7 @@ def test_purge_suggestion_deny_list_entries_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_suggestion_deny_list_entries( request, @@ -3826,6 +3895,7 @@ def test_purge_suggestion_deny_list_entries_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_completion_suggestions_rest_bad_request( @@ -3911,10 +3981,14 @@ def test_import_completion_suggestions_rest_interceptors(null_interceptor): transports.CompletionServiceRestInterceptor, "post_import_completion_suggestions", ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_import_completion_suggestions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_import_completion_suggestions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportCompletionSuggestionsRequest.pb( import_config.ImportCompletionSuggestionsRequest() ) @@ -3938,6 +4012,7 @@ def test_import_completion_suggestions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_completion_suggestions( request, @@ -3949,6 +4024,7 @@ def test_import_completion_suggestions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_completion_suggestions_rest_bad_request( @@ -4033,10 +4109,14 @@ def test_purge_completion_suggestions_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CompletionServiceRestInterceptor, "post_purge_completion_suggestions" ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_purge_completion_suggestions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_purge_completion_suggestions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeCompletionSuggestionsRequest.pb( purge_config.PurgeCompletionSuggestionsRequest() ) @@ -4060,6 +4140,7 @@ def test_purge_completion_suggestions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_completion_suggestions( request, @@ -4071,6 +4152,7 @@ def test_purge_completion_suggestions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_control_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_control_service.py index 6104722ee1dd..c1095ac5eb90 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_control_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_control_service.py @@ -67,6 +67,13 @@ from google.cloud.discoveryengine_v1alpha.types import control as gcd_control from google.cloud.discoveryengine_v1alpha.types import control_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -325,6 +332,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ControlServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ControlServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4544,10 +4594,13 @@ def test_create_control_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_create_control" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_create_control_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_create_control" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.CreateControlRequest.pb( control_service.CreateControlRequest() ) @@ -4571,6 +4624,7 @@ def test_create_control_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_control.Control() + post_with_metadata.return_value = gcd_control.Control(), metadata client.create_control( request, @@ -4582,6 +4636,7 @@ def test_create_control_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_control_rest_bad_request( @@ -4890,10 +4945,13 @@ def test_update_control_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_update_control" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_update_control_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_update_control" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.UpdateControlRequest.pb( control_service.UpdateControlRequest() ) @@ -4917,6 +4975,7 @@ def test_update_control_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_control.Control() + post_with_metadata.return_value = gcd_control.Control(), metadata client.update_control( request, @@ -4928,6 +4987,7 @@ def test_update_control_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_control_rest_bad_request(request_type=control_service.GetControlRequest): @@ -5024,10 +5084,13 @@ def test_get_control_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_get_control" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_get_control_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_get_control" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.GetControlRequest.pb( control_service.GetControlRequest() ) @@ -5051,6 +5114,7 @@ def test_get_control_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = control.Control() + post_with_metadata.return_value = control.Control(), metadata client.get_control( request, @@ -5062,6 +5126,7 @@ def test_get_control_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_controls_rest_bad_request( @@ -5146,10 +5211,13 @@ def test_list_controls_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_list_controls" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_list_controls_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_list_controls" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.ListControlsRequest.pb( control_service.ListControlsRequest() ) @@ -5175,6 +5243,10 @@ def test_list_controls_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = control_service.ListControlsResponse() + post_with_metadata.return_value = ( + control_service.ListControlsResponse(), + metadata, + ) client.list_controls( request, @@ -5186,6 +5258,7 @@ def test_list_controls_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_conversational_search_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_conversational_search_service.py index 217e8e57d1f6..500c1b1bdc34 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_conversational_search_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_conversational_search_service.py @@ -72,6 +72,13 @@ from google.cloud.discoveryengine_v1alpha.types import session from google.cloud.discoveryengine_v1alpha.types import session as gcd_session +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -355,6 +362,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationalSearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationalSearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -9264,11 +9314,15 @@ def test_converse_conversation_rest_interceptors(null_interceptor): transports.ConversationalSearchServiceRestInterceptor, "post_converse_conversation", ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_converse_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_converse_conversation", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.ConverseConversationRequest.pb( conversational_search_service.ConverseConversationRequest() ) @@ -9296,6 +9350,10 @@ def test_converse_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.ConverseConversationResponse() + post_with_metadata.return_value = ( + conversational_search_service.ConverseConversationResponse(), + metadata, + ) client.converse_conversation( request, @@ -9307,6 +9365,7 @@ def test_converse_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_conversation_rest_bad_request( @@ -9531,10 +9590,14 @@ def test_create_conversation_rest_interceptors(null_interceptor): transports.ConversationalSearchServiceRestInterceptor, "post_create_conversation", ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_create_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_create_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.CreateConversationRequest.pb( conversational_search_service.CreateConversationRequest() ) @@ -9560,6 +9623,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.Conversation() + post_with_metadata.return_value = gcd_conversation.Conversation(), metadata client.create_conversation( request, @@ -9571,6 +9635,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_conversation_rest_bad_request( @@ -9916,10 +9981,14 @@ def test_update_conversation_rest_interceptors(null_interceptor): transports.ConversationalSearchServiceRestInterceptor, "post_update_conversation", ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_update_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_update_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.UpdateConversationRequest.pb( conversational_search_service.UpdateConversationRequest() ) @@ -9945,6 +10014,7 @@ def test_update_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.Conversation() + post_with_metadata.return_value = gcd_conversation.Conversation(), metadata client.update_conversation( request, @@ -9956,6 +10026,7 @@ def test_update_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_rest_bad_request( @@ -10048,10 +10119,14 @@ def test_get_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_get_conversation" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_get_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_get_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.GetConversationRequest.pb( conversational_search_service.GetConversationRequest() ) @@ -10075,6 +10150,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.Conversation() + post_with_metadata.return_value = conversation.Conversation(), metadata client.get_conversation( request, @@ -10086,6 +10162,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_conversations_rest_bad_request( @@ -10172,10 +10249,14 @@ def test_list_conversations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_list_conversations" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_list_conversations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_list_conversations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.ListConversationsRequest.pb( conversational_search_service.ListConversationsRequest() ) @@ -10201,6 +10282,10 @@ def test_list_conversations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.ListConversationsResponse() + post_with_metadata.return_value = ( + conversational_search_service.ListConversationsResponse(), + metadata, + ) client.list_conversations( request, @@ -10212,6 +10297,7 @@ def test_list_conversations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_answer_query_rest_bad_request( @@ -10302,10 +10388,14 @@ def test_answer_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_answer_query" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_answer_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_answer_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.AnswerQueryRequest.pb( conversational_search_service.AnswerQueryRequest() ) @@ -10331,6 +10421,10 @@ def test_answer_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.AnswerQueryResponse() + post_with_metadata.return_value = ( + conversational_search_service.AnswerQueryResponse(), + metadata, + ) client.answer_query( request, @@ -10342,6 +10436,7 @@ def test_answer_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_answer_rest_bad_request( @@ -10442,10 +10537,14 @@ def test_get_answer_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_get_answer" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_get_answer_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_get_answer" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.GetAnswerRequest.pb( conversational_search_service.GetAnswerRequest() ) @@ -10469,6 +10568,7 @@ def test_get_answer_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = answer.Answer() + post_with_metadata.return_value = answer.Answer(), metadata client.get_answer( request, @@ -10480,6 +10580,7 @@ def test_get_answer_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_session_rest_bad_request( @@ -10650,10 +10751,14 @@ def test_create_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_create_session" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_create_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_create_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.CreateSessionRequest.pb( conversational_search_service.CreateSessionRequest() ) @@ -10677,6 +10782,7 @@ def test_create_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session.Session() + post_with_metadata.return_value = gcd_session.Session(), metadata client.create_session( request, @@ -10688,6 +10794,7 @@ def test_create_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_session_rest_bad_request( @@ -10979,10 +11086,14 @@ def test_update_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_update_session" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_update_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_update_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.UpdateSessionRequest.pb( conversational_search_service.UpdateSessionRequest() ) @@ -11006,6 +11117,7 @@ def test_update_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session.Session() + post_with_metadata.return_value = gcd_session.Session(), metadata client.update_session( request, @@ -11017,6 +11129,7 @@ def test_update_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_session_rest_bad_request( @@ -11109,10 +11222,14 @@ def test_get_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_get_session" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_get_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_get_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.GetSessionRequest.pb( conversational_search_service.GetSessionRequest() ) @@ -11136,6 +11253,7 @@ def test_get_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.Session() + post_with_metadata.return_value = session.Session(), metadata client.get_session( request, @@ -11147,6 +11265,7 @@ def test_get_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_sessions_rest_bad_request( @@ -11233,10 +11352,14 @@ def test_list_sessions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_list_sessions" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_list_sessions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_list_sessions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.ListSessionsRequest.pb( conversational_search_service.ListSessionsRequest() ) @@ -11262,6 +11385,10 @@ def test_list_sessions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.ListSessionsResponse() + post_with_metadata.return_value = ( + conversational_search_service.ListSessionsResponse(), + metadata, + ) client.list_sessions( request, @@ -11273,6 +11400,7 @@ def test_list_sessions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_data_store_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_data_store_service.py index 8e958e81ea40..5fdecaef364e 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_data_store_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_data_store_service.py @@ -83,6 +83,13 @@ from google.cloud.discoveryengine_v1alpha.types import data_store_service from google.cloud.discoveryengine_v1alpha.types import schema +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -342,6 +349,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataStoreServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataStoreServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -5889,10 +5939,14 @@ def test_create_data_store_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_create_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_create_data_store_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_create_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.CreateDataStoreRequest.pb( data_store_service.CreateDataStoreRequest() ) @@ -5916,6 +5970,7 @@ def test_create_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_data_store( request, @@ -5927,6 +5982,7 @@ def test_create_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_data_store_rest_bad_request( @@ -6023,10 +6079,13 @@ def test_get_data_store_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_get_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, "post_get_data_store_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_get_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.GetDataStoreRequest.pb( data_store_service.GetDataStoreRequest() ) @@ -6050,6 +6109,7 @@ def test_get_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = data_store.DataStore() + post_with_metadata.return_value = data_store.DataStore(), metadata client.get_data_store( request, @@ -6061,6 +6121,7 @@ def test_get_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_data_stores_rest_bad_request( @@ -6145,10 +6206,14 @@ def test_list_data_stores_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_list_data_stores" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_list_data_stores_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_list_data_stores" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.ListDataStoresRequest.pb( data_store_service.ListDataStoresRequest() ) @@ -6174,6 +6239,10 @@ def test_list_data_stores_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = data_store_service.ListDataStoresResponse() + post_with_metadata.return_value = ( + data_store_service.ListDataStoresResponse(), + metadata, + ) client.list_data_stores( request, @@ -6185,6 +6254,7 @@ def test_list_data_stores_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_data_store_rest_bad_request( @@ -6265,10 +6335,14 @@ def test_delete_data_store_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_delete_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_delete_data_store_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_delete_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.DeleteDataStoreRequest.pb( data_store_service.DeleteDataStoreRequest() ) @@ -6292,6 +6366,7 @@ def test_delete_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_data_store( request, @@ -6303,6 +6378,7 @@ def test_delete_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_data_store_rest_bad_request( @@ -6538,10 +6614,14 @@ def test_update_data_store_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_update_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_update_data_store_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_update_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.UpdateDataStoreRequest.pb( data_store_service.UpdateDataStoreRequest() ) @@ -6565,6 +6645,7 @@ def test_update_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_data_store.DataStore() + post_with_metadata.return_value = gcd_data_store.DataStore(), metadata client.update_data_store( request, @@ -6576,6 +6657,7 @@ def test_update_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_document_processing_config_rest_bad_request( @@ -6667,10 +6749,14 @@ def test_get_document_processing_config_rest_interceptors(null_interceptor): transports.DataStoreServiceRestInterceptor, "post_get_document_processing_config", ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_get_document_processing_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_get_document_processing_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.GetDocumentProcessingConfigRequest.pb( data_store_service.GetDocumentProcessingConfigRequest() ) @@ -6696,6 +6782,10 @@ def test_get_document_processing_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document_processing_config.DocumentProcessingConfig() + post_with_metadata.return_value = ( + document_processing_config.DocumentProcessingConfig(), + metadata, + ) client.get_document_processing_config( request, @@ -6707,6 +6797,7 @@ def test_get_document_processing_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_document_processing_config_rest_bad_request( @@ -6896,11 +6987,15 @@ def test_update_document_processing_config_rest_interceptors(null_interceptor): transports.DataStoreServiceRestInterceptor, "post_update_document_processing_config", ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_update_document_processing_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_update_document_processing_config", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.UpdateDocumentProcessingConfigRequest.pb( data_store_service.UpdateDocumentProcessingConfigRequest() ) @@ -6926,6 +7021,10 @@ def test_update_document_processing_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_document_processing_config.DocumentProcessingConfig() + post_with_metadata.return_value = ( + gcd_document_processing_config.DocumentProcessingConfig(), + metadata, + ) client.update_document_processing_config( request, @@ -6937,6 +7036,7 @@ def test_update_document_processing_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_document_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_document_service.py index 1750f8d53480..5abf0a13f646 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_document_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_document_service.py @@ -84,6 +84,13 @@ from google.cloud.discoveryengine_v1alpha.types import document from google.cloud.discoveryengine_v1alpha.types import document as gcd_document +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -342,6 +349,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DocumentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DocumentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6615,10 +6665,13 @@ def test_get_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_get_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_get_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_get_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.GetDocumentRequest.pb( document_service.GetDocumentRequest() ) @@ -6642,6 +6695,7 @@ def test_get_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document.Document() + post_with_metadata.return_value = document.Document(), metadata client.get_document( request, @@ -6653,6 +6707,7 @@ def test_get_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_documents_rest_bad_request( @@ -6741,10 +6796,13 @@ def test_list_documents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_list_documents" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_list_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_list_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.ListDocumentsRequest.pb( document_service.ListDocumentsRequest() ) @@ -6770,6 +6828,10 @@ def test_list_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document_service.ListDocumentsResponse() + post_with_metadata.return_value = ( + document_service.ListDocumentsResponse(), + metadata, + ) client.list_documents( request, @@ -6781,6 +6843,7 @@ def test_list_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_document_rest_bad_request( @@ -6983,10 +7046,13 @@ def test_create_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_create_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_create_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_create_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.CreateDocumentRequest.pb( document_service.CreateDocumentRequest() ) @@ -7010,6 +7076,7 @@ def test_create_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_document.Document() + post_with_metadata.return_value = gcd_document.Document(), metadata client.create_document( request, @@ -7021,6 +7088,7 @@ def test_create_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_document_rest_bad_request( @@ -7227,10 +7295,13 @@ def test_update_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_update_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_update_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_update_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.UpdateDocumentRequest.pb( document_service.UpdateDocumentRequest() ) @@ -7254,6 +7325,7 @@ def test_update_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_document.Document() + post_with_metadata.return_value = gcd_document.Document(), metadata client.update_document( request, @@ -7265,6 +7337,7 @@ def test_update_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_document_rest_bad_request( @@ -7462,10 +7535,13 @@ def test_import_documents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentServiceRestInterceptor, "post_import_documents" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_import_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_import_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportDocumentsRequest.pb( import_config.ImportDocumentsRequest() ) @@ -7489,6 +7565,7 @@ def test_import_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_documents( request, @@ -7500,6 +7577,7 @@ def test_import_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_documents_rest_bad_request( @@ -7584,10 +7662,13 @@ def test_purge_documents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentServiceRestInterceptor, "post_purge_documents" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_purge_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_purge_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeDocumentsRequest.pb( purge_config.PurgeDocumentsRequest() ) @@ -7611,6 +7692,7 @@ def test_purge_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_documents( request, @@ -7622,6 +7704,7 @@ def test_purge_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_processed_document_rest_bad_request( @@ -7711,10 +7794,14 @@ def test_get_processed_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_get_processed_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, + "post_get_processed_document_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_get_processed_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.GetProcessedDocumentRequest.pb( document_service.GetProcessedDocumentRequest() ) @@ -7738,6 +7825,7 @@ def test_get_processed_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document.ProcessedDocument() + post_with_metadata.return_value = document.ProcessedDocument(), metadata client.get_processed_document( request, @@ -7749,6 +7837,7 @@ def test_get_processed_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_get_documents_metadata_rest_bad_request( @@ -7836,10 +7925,14 @@ def test_batch_get_documents_metadata_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_batch_get_documents_metadata" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, + "post_batch_get_documents_metadata_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_batch_get_documents_metadata" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.BatchGetDocumentsMetadataRequest.pb( document_service.BatchGetDocumentsMetadataRequest() ) @@ -7865,6 +7958,10 @@ def test_batch_get_documents_metadata_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document_service.BatchGetDocumentsMetadataResponse() + post_with_metadata.return_value = ( + document_service.BatchGetDocumentsMetadataResponse(), + metadata, + ) client.batch_get_documents_metadata( request, @@ -7876,6 +7973,7 @@ def test_batch_get_documents_metadata_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_engine_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_engine_service.py index 8a47c5b87a19..be4470be1ac4 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_engine_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_engine_service.py @@ -77,6 +77,13 @@ from google.cloud.discoveryengine_v1alpha.types import engine as gcd_engine from google.cloud.discoveryengine_v1alpha.types import engine_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -331,6 +338,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6195,10 +6245,13 @@ def test_create_engine_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EngineServiceRestInterceptor, "post_create_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_create_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_create_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.CreateEngineRequest.pb( engine_service.CreateEngineRequest() ) @@ -6222,6 +6275,7 @@ def test_create_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_engine( request, @@ -6233,6 +6287,7 @@ def test_create_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_engine_rest_bad_request( @@ -6317,10 +6372,13 @@ def test_delete_engine_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EngineServiceRestInterceptor, "post_delete_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_delete_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_delete_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.DeleteEngineRequest.pb( engine_service.DeleteEngineRequest() ) @@ -6344,6 +6402,7 @@ def test_delete_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_engine( request, @@ -6355,6 +6414,7 @@ def test_delete_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_engine_rest_bad_request( @@ -6559,10 +6619,13 @@ def test_update_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_update_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_update_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_update_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.UpdateEngineRequest.pb( engine_service.UpdateEngineRequest() ) @@ -6586,6 +6649,7 @@ def test_update_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_engine.Engine() + post_with_metadata.return_value = gcd_engine.Engine(), metadata client.update_engine( request, @@ -6597,6 +6661,7 @@ def test_update_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_engine_rest_bad_request(request_type=engine_service.GetEngineRequest): @@ -6691,10 +6756,13 @@ def test_get_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_get_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_get_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_get_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.GetEngineRequest.pb( engine_service.GetEngineRequest() ) @@ -6718,6 +6786,7 @@ def test_get_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine.Engine() + post_with_metadata.return_value = engine.Engine(), metadata client.get_engine( request, @@ -6729,6 +6798,7 @@ def test_get_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_engines_rest_bad_request(request_type=engine_service.ListEnginesRequest): @@ -6811,10 +6881,13 @@ def test_list_engines_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_list_engines" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_list_engines_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_list_engines" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.ListEnginesRequest.pb( engine_service.ListEnginesRequest() ) @@ -6840,6 +6913,7 @@ def test_list_engines_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine_service.ListEnginesResponse() + post_with_metadata.return_value = engine_service.ListEnginesResponse(), metadata client.list_engines( request, @@ -6851,6 +6925,7 @@ def test_list_engines_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_pause_engine_rest_bad_request(request_type=engine_service.PauseEngineRequest): @@ -6945,10 +7020,13 @@ def test_pause_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_pause_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_pause_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_pause_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.PauseEngineRequest.pb( engine_service.PauseEngineRequest() ) @@ -6972,6 +7050,7 @@ def test_pause_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine.Engine() + post_with_metadata.return_value = engine.Engine(), metadata client.pause_engine( request, @@ -6983,6 +7062,7 @@ def test_pause_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_resume_engine_rest_bad_request( @@ -7079,10 +7159,13 @@ def test_resume_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_resume_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_resume_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_resume_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.ResumeEngineRequest.pb( engine_service.ResumeEngineRequest() ) @@ -7106,6 +7189,7 @@ def test_resume_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine.Engine() + post_with_metadata.return_value = engine.Engine(), metadata client.resume_engine( request, @@ -7117,6 +7201,7 @@ def test_resume_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_tune_engine_rest_bad_request(request_type=engine_service.TuneEngineRequest): @@ -7199,10 +7284,13 @@ def test_tune_engine_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EngineServiceRestInterceptor, "post_tune_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_tune_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_tune_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.TuneEngineRequest.pb( engine_service.TuneEngineRequest() ) @@ -7226,6 +7314,7 @@ def test_tune_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.tune_engine( request, @@ -7237,6 +7326,7 @@ def test_tune_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_estimate_billing_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_estimate_billing_service.py index 554a71d31cb7..f2603322c67b 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_estimate_billing_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_estimate_billing_service.py @@ -74,6 +74,13 @@ import_config, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -349,6 +356,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EstimateBillingServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EstimateBillingServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1779,10 +1829,14 @@ def test_estimate_data_size_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EstimateBillingServiceRestInterceptor, "post_estimate_data_size" ) as post, mock.patch.object( + transports.EstimateBillingServiceRestInterceptor, + "post_estimate_data_size_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EstimateBillingServiceRestInterceptor, "pre_estimate_data_size" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = estimate_billing_service.EstimateDataSizeRequest.pb( estimate_billing_service.EstimateDataSizeRequest() ) @@ -1806,6 +1860,7 @@ def test_estimate_data_size_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.estimate_data_size( request, @@ -1817,6 +1872,7 @@ def test_estimate_data_size_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_evaluation_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_evaluation_service.py index 161c3f0fae67..015a243bdb52 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_evaluation_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_evaluation_service.py @@ -81,6 +81,13 @@ from google.cloud.discoveryengine_v1alpha.types import common from google.cloud.discoveryengine_v1alpha.types import evaluation +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -348,6 +355,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EvaluationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EvaluationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4191,10 +4241,13 @@ def test_get_evaluation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, "post_get_evaluation" ) as post, mock.patch.object( + transports.EvaluationServiceRestInterceptor, "post_get_evaluation_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, "pre_get_evaluation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = evaluation_service.GetEvaluationRequest.pb( evaluation_service.GetEvaluationRequest() ) @@ -4218,6 +4271,7 @@ def test_get_evaluation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = evaluation.Evaluation() + post_with_metadata.return_value = evaluation.Evaluation(), metadata client.get_evaluation( request, @@ -4229,6 +4283,7 @@ def test_get_evaluation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_evaluations_rest_bad_request( @@ -4313,10 +4368,14 @@ def test_list_evaluations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, "post_list_evaluations" ) as post, mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_list_evaluations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, "pre_list_evaluations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = evaluation_service.ListEvaluationsRequest.pb( evaluation_service.ListEvaluationsRequest() ) @@ -4342,6 +4401,10 @@ def test_list_evaluations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = evaluation_service.ListEvaluationsResponse() + post_with_metadata.return_value = ( + evaluation_service.ListEvaluationsResponse(), + metadata, + ) client.list_evaluations( request, @@ -4353,6 +4416,7 @@ def test_list_evaluations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_evaluation_rest_bad_request( @@ -4659,10 +4723,14 @@ def test_create_evaluation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EvaluationServiceRestInterceptor, "post_create_evaluation" ) as post, mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_create_evaluation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, "pre_create_evaluation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = evaluation_service.CreateEvaluationRequest.pb( evaluation_service.CreateEvaluationRequest() ) @@ -4686,6 +4754,7 @@ def test_create_evaluation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_evaluation( request, @@ -4697,6 +4766,7 @@ def test_create_evaluation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_evaluation_results_rest_bad_request( @@ -4785,10 +4855,14 @@ def test_list_evaluation_results_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, "post_list_evaluation_results" ) as post, mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_list_evaluation_results_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, "pre_list_evaluation_results" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = evaluation_service.ListEvaluationResultsRequest.pb( evaluation_service.ListEvaluationResultsRequest() ) @@ -4814,6 +4888,10 @@ def test_list_evaluation_results_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = evaluation_service.ListEvaluationResultsResponse() + post_with_metadata.return_value = ( + evaluation_service.ListEvaluationResultsResponse(), + metadata, + ) client.list_evaluation_results( request, @@ -4825,6 +4903,7 @@ def test_list_evaluation_results_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_grounded_generation_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_grounded_generation_service.py index 720cd375b33d..c466c8932b8c 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_grounded_generation_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_grounded_generation_service.py @@ -64,6 +64,13 @@ grounding, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = GroundedGenerationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = GroundedGenerationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1770,10 +1820,14 @@ def test_check_grounding_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GroundedGenerationServiceRestInterceptor, "post_check_grounding" ) as post, mock.patch.object( + transports.GroundedGenerationServiceRestInterceptor, + "post_check_grounding_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.GroundedGenerationServiceRestInterceptor, "pre_check_grounding" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = grounded_generation_service.CheckGroundingRequest.pb( grounded_generation_service.CheckGroundingRequest() ) @@ -1799,6 +1853,10 @@ def test_check_grounding_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = grounded_generation_service.CheckGroundingResponse() + post_with_metadata.return_value = ( + grounded_generation_service.CheckGroundingResponse(), + metadata, + ) client.check_grounding( request, @@ -1810,6 +1868,7 @@ def test_check_grounding_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_project_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_project_service.py index 6b0d67012a6d..0e0dd84cdccb 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_project_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_project_service.py @@ -73,6 +73,13 @@ from google.cloud.discoveryengine_v1alpha.types import project as gcd_project from google.cloud.discoveryengine_v1alpha.types import project_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -331,6 +338,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ProjectServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ProjectServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3047,10 +3097,13 @@ def test_get_project_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ProjectServiceRestInterceptor, "post_get_project" ) as post, mock.patch.object( + transports.ProjectServiceRestInterceptor, "post_get_project_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ProjectServiceRestInterceptor, "pre_get_project" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = project_service.GetProjectRequest.pb( project_service.GetProjectRequest() ) @@ -3074,6 +3127,7 @@ def test_get_project_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = project.Project() + post_with_metadata.return_value = project.Project(), metadata client.get_project( request, @@ -3085,6 +3139,7 @@ def test_get_project_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_provision_project_rest_bad_request( @@ -3165,10 +3220,13 @@ def test_provision_project_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ProjectServiceRestInterceptor, "post_provision_project" ) as post, mock.patch.object( + transports.ProjectServiceRestInterceptor, "post_provision_project_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ProjectServiceRestInterceptor, "pre_provision_project" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = project_service.ProvisionProjectRequest.pb( project_service.ProvisionProjectRequest() ) @@ -3192,6 +3250,7 @@ def test_provision_project_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.provision_project( request, @@ -3203,6 +3262,7 @@ def test_provision_project_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_report_consent_change_rest_bad_request( @@ -3287,10 +3347,14 @@ def test_report_consent_change_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ProjectServiceRestInterceptor, "post_report_consent_change" ) as post, mock.patch.object( + transports.ProjectServiceRestInterceptor, + "post_report_consent_change_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ProjectServiceRestInterceptor, "pre_report_consent_change" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = project_service.ReportConsentChangeRequest.pb( project_service.ReportConsentChangeRequest() ) @@ -3314,6 +3378,7 @@ def test_report_consent_change_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_project.Project() + post_with_metadata.return_value = gcd_project.Project(), metadata client.report_consent_change( request, @@ -3325,6 +3390,7 @@ def test_report_consent_change_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_rank_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_rank_service.py index 321c64930ac6..7f90ab420f2a 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_rank_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_rank_service.py @@ -61,6 +61,13 @@ ) from google.cloud.discoveryengine_v1alpha.types import rank_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -300,6 +307,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = RankServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = RankServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1641,10 +1691,13 @@ def test_rank_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.RankServiceRestInterceptor, "post_rank" ) as post, mock.patch.object( + transports.RankServiceRestInterceptor, "post_rank_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.RankServiceRestInterceptor, "pre_rank" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = rank_service.RankRequest.pb(rank_service.RankRequest()) transcode.return_value = { "method": "post", @@ -1666,6 +1719,7 @@ def test_rank_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = rank_service.RankResponse() + post_with_metadata.return_value = rank_service.RankResponse(), metadata client.rank( request, @@ -1677,6 +1731,7 @@ def test_rank_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_recommendation_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_recommendation_service.py index 3c6cff8b1248..93a646558da4 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_recommendation_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_recommendation_service.py @@ -68,6 +68,13 @@ user_event, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = RecommendationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = RecommendationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1776,10 +1826,13 @@ def test_recommend_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.RecommendationServiceRestInterceptor, "post_recommend" ) as post, mock.patch.object( + transports.RecommendationServiceRestInterceptor, "post_recommend_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.RecommendationServiceRestInterceptor, "pre_recommend" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = recommendation_service.RecommendRequest.pb( recommendation_service.RecommendRequest() ) @@ -1805,6 +1858,10 @@ def test_recommend_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = recommendation_service.RecommendResponse() + post_with_metadata.return_value = ( + recommendation_service.RecommendResponse(), + metadata, + ) client.recommend( request, @@ -1816,6 +1873,7 @@ def test_recommend_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_sample_query_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_sample_query_service.py index ef1e369354e0..f6df20d70dfb 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_sample_query_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_sample_query_service.py @@ -77,6 +77,13 @@ from google.cloud.discoveryengine_v1alpha.types import sample_query from google.cloud.discoveryengine_v1alpha.types import sample_query_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -348,6 +355,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SampleQueryServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SampleQueryServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4994,10 +5044,14 @@ def test_get_sample_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_get_sample_query" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_get_sample_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_get_sample_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_service.GetSampleQueryRequest.pb( sample_query_service.GetSampleQueryRequest() ) @@ -5021,6 +5075,7 @@ def test_get_sample_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sample_query.SampleQuery() + post_with_metadata.return_value = sample_query.SampleQuery(), metadata client.get_sample_query( request, @@ -5032,6 +5087,7 @@ def test_get_sample_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_sample_queries_rest_bad_request( @@ -5120,10 +5176,14 @@ def test_list_sample_queries_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_list_sample_queries" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_list_sample_queries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_list_sample_queries" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_service.ListSampleQueriesRequest.pb( sample_query_service.ListSampleQueriesRequest() ) @@ -5149,6 +5209,10 @@ def test_list_sample_queries_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sample_query_service.ListSampleQueriesResponse() + post_with_metadata.return_value = ( + sample_query_service.ListSampleQueriesResponse(), + metadata, + ) client.list_sample_queries( request, @@ -5160,6 +5224,7 @@ def test_list_sample_queries_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_sample_query_rest_bad_request( @@ -5327,10 +5392,14 @@ def test_create_sample_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_create_sample_query" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_create_sample_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_create_sample_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_service.CreateSampleQueryRequest.pb( sample_query_service.CreateSampleQueryRequest() ) @@ -5356,6 +5425,7 @@ def test_create_sample_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sample_query.SampleQuery() + post_with_metadata.return_value = gcd_sample_query.SampleQuery(), metadata client.create_sample_query( request, @@ -5367,6 +5437,7 @@ def test_create_sample_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_sample_query_rest_bad_request( @@ -5538,10 +5609,14 @@ def test_update_sample_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_update_sample_query" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_update_sample_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_update_sample_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_service.UpdateSampleQueryRequest.pb( sample_query_service.UpdateSampleQueryRequest() ) @@ -5567,6 +5642,7 @@ def test_update_sample_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sample_query.SampleQuery() + post_with_metadata.return_value = gcd_sample_query.SampleQuery(), metadata client.update_sample_query( request, @@ -5578,6 +5654,7 @@ def test_update_sample_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_sample_query_rest_bad_request( @@ -5775,10 +5852,14 @@ def test_import_sample_queries_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_import_sample_queries" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_import_sample_queries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_import_sample_queries" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportSampleQueriesRequest.pb( import_config.ImportSampleQueriesRequest() ) @@ -5802,6 +5883,7 @@ def test_import_sample_queries_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_sample_queries( request, @@ -5813,6 +5895,7 @@ def test_import_sample_queries_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_sample_query_set_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_sample_query_set_service.py index 9d0ff245dbde..e6315a0db6d9 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_sample_query_set_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_sample_query_set_service.py @@ -68,6 +68,13 @@ from google.cloud.discoveryengine_v1alpha.types import sample_query_set from google.cloud.discoveryengine_v1alpha.types import sample_query_set_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SampleQuerySetServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SampleQuerySetServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4598,10 +4648,14 @@ def test_get_sample_query_set_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "post_get_sample_query_set" ) as post, mock.patch.object( + transports.SampleQuerySetServiceRestInterceptor, + "post_get_sample_query_set_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "pre_get_sample_query_set" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_set_service.GetSampleQuerySetRequest.pb( sample_query_set_service.GetSampleQuerySetRequest() ) @@ -4627,6 +4681,7 @@ def test_get_sample_query_set_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sample_query_set.SampleQuerySet() + post_with_metadata.return_value = sample_query_set.SampleQuerySet(), metadata client.get_sample_query_set( request, @@ -4638,6 +4693,7 @@ def test_get_sample_query_set_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_sample_query_sets_rest_bad_request( @@ -4724,10 +4780,14 @@ def test_list_sample_query_sets_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "post_list_sample_query_sets" ) as post, mock.patch.object( + transports.SampleQuerySetServiceRestInterceptor, + "post_list_sample_query_sets_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "pre_list_sample_query_sets" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_set_service.ListSampleQuerySetsRequest.pb( sample_query_set_service.ListSampleQuerySetsRequest() ) @@ -4753,6 +4813,10 @@ def test_list_sample_query_sets_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sample_query_set_service.ListSampleQuerySetsResponse() + post_with_metadata.return_value = ( + sample_query_set_service.ListSampleQuerySetsResponse(), + metadata, + ) client.list_sample_query_sets( request, @@ -4764,6 +4828,7 @@ def test_list_sample_query_sets_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_sample_query_set_rest_bad_request( @@ -4927,10 +4992,14 @@ def test_create_sample_query_set_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "post_create_sample_query_set" ) as post, mock.patch.object( + transports.SampleQuerySetServiceRestInterceptor, + "post_create_sample_query_set_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "pre_create_sample_query_set" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_set_service.CreateSampleQuerySetRequest.pb( sample_query_set_service.CreateSampleQuerySetRequest() ) @@ -4956,6 +5025,10 @@ def test_create_sample_query_set_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sample_query_set.SampleQuerySet() + post_with_metadata.return_value = ( + gcd_sample_query_set.SampleQuerySet(), + metadata, + ) client.create_sample_query_set( request, @@ -4967,6 +5040,7 @@ def test_create_sample_query_set_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_sample_query_set_rest_bad_request( @@ -5138,10 +5212,14 @@ def test_update_sample_query_set_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "post_update_sample_query_set" ) as post, mock.patch.object( + transports.SampleQuerySetServiceRestInterceptor, + "post_update_sample_query_set_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "pre_update_sample_query_set" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_set_service.UpdateSampleQuerySetRequest.pb( sample_query_set_service.UpdateSampleQuerySetRequest() ) @@ -5167,6 +5245,10 @@ def test_update_sample_query_set_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sample_query_set.SampleQuerySet() + post_with_metadata.return_value = ( + gcd_sample_query_set.SampleQuerySet(), + metadata, + ) client.update_sample_query_set( request, @@ -5178,6 +5260,7 @@ def test_update_sample_query_set_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_sample_query_set_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_schema_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_schema_service.py index 150b5e7975e8..3980a030cf61 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_schema_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_schema_service.py @@ -75,6 +75,13 @@ from google.cloud.discoveryengine_v1alpha.types import schema as gcd_schema from google.cloud.discoveryengine_v1alpha.types import schema_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -329,6 +336,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SchemaServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SchemaServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4279,10 +4329,13 @@ def test_get_schema_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_get_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_get_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_get_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.GetSchemaRequest.pb( schema_service.GetSchemaRequest() ) @@ -4306,6 +4359,7 @@ def test_get_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema.Schema() + post_with_metadata.return_value = schema.Schema(), metadata client.get_schema( request, @@ -4317,6 +4371,7 @@ def test_get_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_schemas_rest_bad_request(request_type=schema_service.ListSchemasRequest): @@ -4399,10 +4454,13 @@ def test_list_schemas_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_list_schemas" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_list_schemas_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_list_schemas" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.ListSchemasRequest.pb( schema_service.ListSchemasRequest() ) @@ -4428,6 +4486,7 @@ def test_list_schemas_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema_service.ListSchemasResponse() + post_with_metadata.return_value = schema_service.ListSchemasResponse(), metadata client.list_schemas( request, @@ -4439,6 +4498,7 @@ def test_list_schemas_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_schema_rest_bad_request( @@ -4609,10 +4669,13 @@ def test_create_schema_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SchemaServiceRestInterceptor, "post_create_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_create_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_create_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.CreateSchemaRequest.pb( schema_service.CreateSchemaRequest() ) @@ -4636,6 +4699,7 @@ def test_create_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_schema( request, @@ -4647,6 +4711,7 @@ def test_create_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_schema_rest_bad_request( @@ -4825,10 +4890,13 @@ def test_update_schema_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SchemaServiceRestInterceptor, "post_update_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_update_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_update_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.UpdateSchemaRequest.pb( schema_service.UpdateSchemaRequest() ) @@ -4852,6 +4920,7 @@ def test_update_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_schema( request, @@ -4863,6 +4932,7 @@ def test_update_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_schema_rest_bad_request( @@ -4947,10 +5017,13 @@ def test_delete_schema_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SchemaServiceRestInterceptor, "post_delete_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_delete_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_delete_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.DeleteSchemaRequest.pb( schema_service.DeleteSchemaRequest() ) @@ -4974,6 +5047,7 @@ def test_delete_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_schema( request, @@ -4985,6 +5059,7 @@ def test_delete_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_search_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_search_service.py index d0bb2e9e4f5d..d2c16e7b4288 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_search_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_search_service.py @@ -63,6 +63,13 @@ ) from google.cloud.discoveryengine_v1alpha.types import common, search_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -317,6 +324,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1994,10 +2044,13 @@ def test_search_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SearchServiceRestInterceptor, "post_search" ) as post, mock.patch.object( + transports.SearchServiceRestInterceptor, "post_search_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SearchServiceRestInterceptor, "pre_search" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_service.SearchRequest.pb(search_service.SearchRequest()) transcode.return_value = { "method": "post", @@ -2021,6 +2074,7 @@ def test_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = search_service.SearchResponse() + post_with_metadata.return_value = search_service.SearchResponse(), metadata client.search( request, @@ -2032,6 +2086,7 @@ def test_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_search_tuning_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_search_tuning_service.py index b942fead1757..5fe8f8bf9b5a 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_search_tuning_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_search_tuning_service.py @@ -74,6 +74,13 @@ search_tuning_service, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -347,6 +354,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SearchTuningServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SearchTuningServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2209,10 +2259,14 @@ def test_train_custom_model_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SearchTuningServiceRestInterceptor, "post_train_custom_model" ) as post, mock.patch.object( + transports.SearchTuningServiceRestInterceptor, + "post_train_custom_model_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SearchTuningServiceRestInterceptor, "pre_train_custom_model" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_tuning_service.TrainCustomModelRequest.pb( search_tuning_service.TrainCustomModelRequest() ) @@ -2236,6 +2290,7 @@ def test_train_custom_model_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.train_custom_model( request, @@ -2247,6 +2302,7 @@ def test_train_custom_model_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_custom_models_rest_bad_request( @@ -2332,10 +2388,14 @@ def test_list_custom_models_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SearchTuningServiceRestInterceptor, "post_list_custom_models" ) as post, mock.patch.object( + transports.SearchTuningServiceRestInterceptor, + "post_list_custom_models_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SearchTuningServiceRestInterceptor, "pre_list_custom_models" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_tuning_service.ListCustomModelsRequest.pb( search_tuning_service.ListCustomModelsRequest() ) @@ -2361,6 +2421,10 @@ def test_list_custom_models_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = search_tuning_service.ListCustomModelsResponse() + post_with_metadata.return_value = ( + search_tuning_service.ListCustomModelsResponse(), + metadata, + ) client.list_custom_models( request, @@ -2372,6 +2436,7 @@ def test_list_custom_models_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_serving_config_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_serving_config_service.py index 0b24f0fab49f..d11889938903 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_serving_config_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_serving_config_service.py @@ -69,6 +69,13 @@ from google.cloud.discoveryengine_v1alpha.types import serving_config from google.cloud.discoveryengine_v1alpha.types import serving_config_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -342,6 +349,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ServingConfigServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ServingConfigServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3717,10 +3767,14 @@ def test_update_serving_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "post_update_serving_config" ) as post, mock.patch.object( + transports.ServingConfigServiceRestInterceptor, + "post_update_serving_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "pre_update_serving_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = serving_config_service.UpdateServingConfigRequest.pb( serving_config_service.UpdateServingConfigRequest() ) @@ -3746,6 +3800,7 @@ def test_update_serving_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_serving_config.ServingConfig() + post_with_metadata.return_value = gcd_serving_config.ServingConfig(), metadata client.update_serving_config( request, @@ -3757,6 +3812,7 @@ def test_update_serving_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_serving_config_rest_bad_request( @@ -3871,10 +3927,14 @@ def test_get_serving_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "post_get_serving_config" ) as post, mock.patch.object( + transports.ServingConfigServiceRestInterceptor, + "post_get_serving_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "pre_get_serving_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = serving_config_service.GetServingConfigRequest.pb( serving_config_service.GetServingConfigRequest() ) @@ -3900,6 +3960,7 @@ def test_get_serving_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = serving_config.ServingConfig() + post_with_metadata.return_value = serving_config.ServingConfig(), metadata client.get_serving_config( request, @@ -3911,6 +3972,7 @@ def test_get_serving_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_serving_configs_rest_bad_request( @@ -3997,10 +4059,14 @@ def test_list_serving_configs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "post_list_serving_configs" ) as post, mock.patch.object( + transports.ServingConfigServiceRestInterceptor, + "post_list_serving_configs_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "pre_list_serving_configs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = serving_config_service.ListServingConfigsRequest.pb( serving_config_service.ListServingConfigsRequest() ) @@ -4026,6 +4092,10 @@ def test_list_serving_configs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = serving_config_service.ListServingConfigsResponse() + post_with_metadata.return_value = ( + serving_config_service.ListServingConfigsResponse(), + metadata, + ) client.list_serving_configs( request, @@ -4037,6 +4107,7 @@ def test_list_serving_configs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_site_search_engine_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_site_search_engine_service.py index 9514fd863ff3..7b4a35740c34 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_site_search_engine_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_site_search_engine_service.py @@ -77,6 +77,13 @@ site_search_engine_service, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -352,6 +359,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SiteSearchEngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SiteSearchEngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -8950,10 +9000,14 @@ def test_get_site_search_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_get_site_search_engine" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_get_site_search_engine_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_get_site_search_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.GetSiteSearchEngineRequest.pb( site_search_engine_service.GetSiteSearchEngineRequest() ) @@ -8979,6 +9033,10 @@ def test_get_site_search_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine.SiteSearchEngine() + post_with_metadata.return_value = ( + site_search_engine.SiteSearchEngine(), + metadata, + ) client.get_site_search_engine( request, @@ -8990,6 +9048,7 @@ def test_get_site_search_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_target_site_rest_bad_request( @@ -9158,10 +9217,14 @@ def test_create_target_site_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_create_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_create_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_create_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.CreateTargetSiteRequest.pb( site_search_engine_service.CreateTargetSiteRequest() ) @@ -9185,6 +9248,7 @@ def test_create_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_target_site( request, @@ -9196,6 +9260,7 @@ def test_create_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_create_target_sites_rest_bad_request( @@ -9281,11 +9346,15 @@ def test_batch_create_target_sites_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_batch_create_target_sites", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_batch_create_target_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_batch_create_target_sites", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.BatchCreateTargetSitesRequest.pb( site_search_engine_service.BatchCreateTargetSitesRequest() ) @@ -9309,6 +9378,7 @@ def test_batch_create_target_sites_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_create_target_sites( request, @@ -9320,6 +9390,7 @@ def test_batch_create_target_sites_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_target_site_rest_bad_request( @@ -9422,10 +9493,14 @@ def test_get_target_site_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_get_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_get_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_get_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.GetTargetSiteRequest.pb( site_search_engine_service.GetTargetSiteRequest() ) @@ -9451,6 +9526,7 @@ def test_get_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine.TargetSite() + post_with_metadata.return_value = site_search_engine.TargetSite(), metadata client.get_target_site( request, @@ -9462,6 +9538,7 @@ def test_get_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_target_site_rest_bad_request( @@ -9634,10 +9711,14 @@ def test_update_target_site_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_update_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_update_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_update_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.UpdateTargetSiteRequest.pb( site_search_engine_service.UpdateTargetSiteRequest() ) @@ -9661,6 +9742,7 @@ def test_update_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_target_site( request, @@ -9672,6 +9754,7 @@ def test_update_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_target_site_rest_bad_request( @@ -9756,10 +9839,14 @@ def test_delete_target_site_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_delete_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_delete_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_delete_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.DeleteTargetSiteRequest.pb( site_search_engine_service.DeleteTargetSiteRequest() ) @@ -9783,6 +9870,7 @@ def test_delete_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_target_site( request, @@ -9794,6 +9882,7 @@ def test_delete_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_target_sites_rest_bad_request( @@ -9886,10 +9975,14 @@ def test_list_target_sites_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_list_target_sites" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_list_target_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_list_target_sites" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.ListTargetSitesRequest.pb( site_search_engine_service.ListTargetSitesRequest() ) @@ -9915,6 +10008,10 @@ def test_list_target_sites_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine_service.ListTargetSitesResponse() + post_with_metadata.return_value = ( + site_search_engine_service.ListTargetSitesResponse(), + metadata, + ) client.list_target_sites( request, @@ -9926,6 +10023,7 @@ def test_list_target_sites_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_enable_advanced_site_search_rest_bad_request( @@ -10011,11 +10109,15 @@ def test_enable_advanced_site_search_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_enable_advanced_site_search", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_enable_advanced_site_search_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_enable_advanced_site_search", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.EnableAdvancedSiteSearchRequest.pb( site_search_engine_service.EnableAdvancedSiteSearchRequest() ) @@ -10039,6 +10141,7 @@ def test_enable_advanced_site_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.enable_advanced_site_search( request, @@ -10050,6 +10153,7 @@ def test_enable_advanced_site_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_disable_advanced_site_search_rest_bad_request( @@ -10135,11 +10239,15 @@ def test_disable_advanced_site_search_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_disable_advanced_site_search", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_disable_advanced_site_search_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_disable_advanced_site_search", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.DisableAdvancedSiteSearchRequest.pb( site_search_engine_service.DisableAdvancedSiteSearchRequest() ) @@ -10163,6 +10271,7 @@ def test_disable_advanced_site_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.disable_advanced_site_search( request, @@ -10174,6 +10283,7 @@ def test_disable_advanced_site_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_recrawl_uris_rest_bad_request( @@ -10258,10 +10368,14 @@ def test_recrawl_uris_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_recrawl_uris" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_recrawl_uris_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_recrawl_uris" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.RecrawlUrisRequest.pb( site_search_engine_service.RecrawlUrisRequest() ) @@ -10285,6 +10399,7 @@ def test_recrawl_uris_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.recrawl_uris( request, @@ -10296,6 +10411,7 @@ def test_recrawl_uris_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_verify_target_sites_rest_bad_request( @@ -10381,11 +10497,15 @@ def test_batch_verify_target_sites_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_batch_verify_target_sites", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_batch_verify_target_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_batch_verify_target_sites", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.BatchVerifyTargetSitesRequest.pb( site_search_engine_service.BatchVerifyTargetSitesRequest() ) @@ -10409,6 +10529,7 @@ def test_batch_verify_target_sites_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_verify_target_sites( request, @@ -10420,6 +10541,7 @@ def test_batch_verify_target_sites_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_domain_verification_status_rest_bad_request( @@ -10515,11 +10637,15 @@ def test_fetch_domain_verification_status_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_fetch_domain_verification_status", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_fetch_domain_verification_status_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_fetch_domain_verification_status", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.FetchDomainVerificationStatusRequest.pb( site_search_engine_service.FetchDomainVerificationStatusRequest() ) @@ -10549,6 +10675,10 @@ def test_fetch_domain_verification_status_rest_interceptors(null_interceptor): post.return_value = ( site_search_engine_service.FetchDomainVerificationStatusResponse() ) + post_with_metadata.return_value = ( + site_search_engine_service.FetchDomainVerificationStatusResponse(), + metadata, + ) client.fetch_domain_verification_status( request, @@ -10560,6 +10690,7 @@ def test_fetch_domain_verification_status_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_set_uri_pattern_document_data_rest_bad_request( @@ -10645,11 +10776,15 @@ def test_set_uri_pattern_document_data_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_set_uri_pattern_document_data", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_set_uri_pattern_document_data_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_set_uri_pattern_document_data", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.SetUriPatternDocumentDataRequest.pb( site_search_engine_service.SetUriPatternDocumentDataRequest() ) @@ -10673,6 +10808,7 @@ def test_set_uri_pattern_document_data_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.set_uri_pattern_document_data( request, @@ -10684,6 +10820,7 @@ def test_set_uri_pattern_document_data_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_uri_pattern_document_data_rest_bad_request( @@ -10774,11 +10911,15 @@ def test_get_uri_pattern_document_data_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_get_uri_pattern_document_data", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_get_uri_pattern_document_data_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_get_uri_pattern_document_data", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.GetUriPatternDocumentDataRequest.pb( site_search_engine_service.GetUriPatternDocumentDataRequest() ) @@ -10808,6 +10949,10 @@ def test_get_uri_pattern_document_data_rest_interceptors(null_interceptor): post.return_value = ( site_search_engine_service.GetUriPatternDocumentDataResponse() ) + post_with_metadata.return_value = ( + site_search_engine_service.GetUriPatternDocumentDataResponse(), + metadata, + ) client.get_uri_pattern_document_data( request, @@ -10819,6 +10964,7 @@ def test_get_uri_pattern_document_data_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_user_event_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_user_event_service.py index 44f87f1e4b5a..9bd3257ab529 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_user_event_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1alpha/test_user_event_service.py @@ -81,6 +81,13 @@ user_event_service, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -340,6 +347,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = UserEventServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = UserEventServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3287,10 +3337,14 @@ def test_write_user_event_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.UserEventServiceRestInterceptor, "post_write_user_event" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_write_user_event_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_write_user_event" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = user_event_service.WriteUserEventRequest.pb( user_event_service.WriteUserEventRequest() ) @@ -3314,6 +3368,7 @@ def test_write_user_event_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = user_event.UserEvent() + post_with_metadata.return_value = user_event.UserEvent(), metadata client.write_user_event( request, @@ -3325,6 +3380,7 @@ def test_write_user_event_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_collect_user_event_rest_bad_request( @@ -3408,10 +3464,14 @@ def test_collect_user_event_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.UserEventServiceRestInterceptor, "post_collect_user_event" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_collect_user_event_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_collect_user_event" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = user_event_service.CollectUserEventRequest.pb( user_event_service.CollectUserEventRequest() ) @@ -3435,6 +3495,7 @@ def test_collect_user_event_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = httpbody_pb2.HttpBody() + post_with_metadata.return_value = httpbody_pb2.HttpBody(), metadata client.collect_user_event( request, @@ -3446,6 +3507,7 @@ def test_collect_user_event_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_user_events_rest_bad_request( @@ -3526,10 +3588,14 @@ def test_purge_user_events_rest_interceptors(null_interceptor): ), mock.patch.object( transports.UserEventServiceRestInterceptor, "post_purge_user_events" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_purge_user_events_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_purge_user_events" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeUserEventsRequest.pb( purge_config.PurgeUserEventsRequest() ) @@ -3553,6 +3619,7 @@ def test_purge_user_events_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_user_events( request, @@ -3564,6 +3631,7 @@ def test_purge_user_events_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_user_events_rest_bad_request( @@ -3644,10 +3712,14 @@ def test_import_user_events_rest_interceptors(null_interceptor): ), mock.patch.object( transports.UserEventServiceRestInterceptor, "post_import_user_events" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_import_user_events_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_import_user_events" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportUserEventsRequest.pb( import_config.ImportUserEventsRequest() ) @@ -3671,6 +3743,7 @@ def test_import_user_events_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_user_events( request, @@ -3682,6 +3755,7 @@ def test_import_user_events_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_completion_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_completion_service.py index 6c341d20fa37..fde7ef4caddf 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_completion_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_completion_service.py @@ -77,6 +77,13 @@ purge_config, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -344,6 +351,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = CompletionServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = CompletionServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3994,10 +4044,13 @@ def test_complete_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CompletionServiceRestInterceptor, "post_complete_query" ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, "post_complete_query_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_complete_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = completion_service.CompleteQueryRequest.pb( completion_service.CompleteQueryRequest() ) @@ -4023,6 +4076,10 @@ def test_complete_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = completion_service.CompleteQueryResponse() + post_with_metadata.return_value = ( + completion_service.CompleteQueryResponse(), + metadata, + ) client.complete_query( request, @@ -4034,6 +4091,7 @@ def test_complete_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_advanced_complete_query_rest_bad_request( @@ -4122,10 +4180,14 @@ def test_advanced_complete_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.CompletionServiceRestInterceptor, "post_advanced_complete_query" ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_advanced_complete_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_advanced_complete_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = completion_service.AdvancedCompleteQueryRequest.pb( completion_service.AdvancedCompleteQueryRequest() ) @@ -4151,6 +4213,10 @@ def test_advanced_complete_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = completion_service.AdvancedCompleteQueryResponse() + post_with_metadata.return_value = ( + completion_service.AdvancedCompleteQueryResponse(), + metadata, + ) client.advanced_complete_query( request, @@ -4162,6 +4228,7 @@ def test_advanced_complete_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_suggestion_deny_list_entries_rest_bad_request( @@ -4247,11 +4314,15 @@ def test_import_suggestion_deny_list_entries_rest_interceptors(null_interceptor) transports.CompletionServiceRestInterceptor, "post_import_suggestion_deny_list_entries", ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_import_suggestion_deny_list_entries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_import_suggestion_deny_list_entries", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportSuggestionDenyListEntriesRequest.pb( import_config.ImportSuggestionDenyListEntriesRequest() ) @@ -4275,6 +4346,7 @@ def test_import_suggestion_deny_list_entries_rest_interceptors(null_interceptor) ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_suggestion_deny_list_entries( request, @@ -4286,6 +4358,7 @@ def test_import_suggestion_deny_list_entries_rest_interceptors(null_interceptor) pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_suggestion_deny_list_entries_rest_bad_request( @@ -4371,11 +4444,15 @@ def test_purge_suggestion_deny_list_entries_rest_interceptors(null_interceptor): transports.CompletionServiceRestInterceptor, "post_purge_suggestion_deny_list_entries", ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_purge_suggestion_deny_list_entries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_purge_suggestion_deny_list_entries", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeSuggestionDenyListEntriesRequest.pb( purge_config.PurgeSuggestionDenyListEntriesRequest() ) @@ -4399,6 +4476,7 @@ def test_purge_suggestion_deny_list_entries_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_suggestion_deny_list_entries( request, @@ -4410,6 +4488,7 @@ def test_purge_suggestion_deny_list_entries_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_completion_suggestions_rest_bad_request( @@ -4495,10 +4574,14 @@ def test_import_completion_suggestions_rest_interceptors(null_interceptor): transports.CompletionServiceRestInterceptor, "post_import_completion_suggestions", ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_import_completion_suggestions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_import_completion_suggestions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportCompletionSuggestionsRequest.pb( import_config.ImportCompletionSuggestionsRequest() ) @@ -4522,6 +4605,7 @@ def test_import_completion_suggestions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_completion_suggestions( request, @@ -4533,6 +4617,7 @@ def test_import_completion_suggestions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_completion_suggestions_rest_bad_request( @@ -4617,10 +4702,14 @@ def test_purge_completion_suggestions_rest_interceptors(null_interceptor): ), mock.patch.object( transports.CompletionServiceRestInterceptor, "post_purge_completion_suggestions" ) as post, mock.patch.object( + transports.CompletionServiceRestInterceptor, + "post_purge_completion_suggestions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.CompletionServiceRestInterceptor, "pre_purge_completion_suggestions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeCompletionSuggestionsRequest.pb( purge_config.PurgeCompletionSuggestionsRequest() ) @@ -4644,6 +4733,7 @@ def test_purge_completion_suggestions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_completion_suggestions( request, @@ -4655,6 +4745,7 @@ def test_purge_completion_suggestions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_control_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_control_service.py index 903f83bd63b7..31a45a829931 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_control_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_control_service.py @@ -67,6 +67,13 @@ from google.cloud.discoveryengine_v1beta.types import control as gcd_control from google.cloud.discoveryengine_v1beta.types import control_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -325,6 +332,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ControlServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ControlServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4545,10 +4595,13 @@ def test_create_control_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_create_control" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_create_control_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_create_control" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.CreateControlRequest.pb( control_service.CreateControlRequest() ) @@ -4572,6 +4625,7 @@ def test_create_control_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_control.Control() + post_with_metadata.return_value = gcd_control.Control(), metadata client.create_control( request, @@ -4583,6 +4637,7 @@ def test_create_control_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_control_rest_bad_request( @@ -4892,10 +4947,13 @@ def test_update_control_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_update_control" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_update_control_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_update_control" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.UpdateControlRequest.pb( control_service.UpdateControlRequest() ) @@ -4919,6 +4977,7 @@ def test_update_control_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_control.Control() + post_with_metadata.return_value = gcd_control.Control(), metadata client.update_control( request, @@ -4930,6 +4989,7 @@ def test_update_control_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_control_rest_bad_request(request_type=control_service.GetControlRequest): @@ -5026,10 +5086,13 @@ def test_get_control_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_get_control" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_get_control_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_get_control" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.GetControlRequest.pb( control_service.GetControlRequest() ) @@ -5053,6 +5116,7 @@ def test_get_control_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = control.Control() + post_with_metadata.return_value = control.Control(), metadata client.get_control( request, @@ -5064,6 +5128,7 @@ def test_get_control_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_controls_rest_bad_request( @@ -5148,10 +5213,13 @@ def test_list_controls_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ControlServiceRestInterceptor, "post_list_controls" ) as post, mock.patch.object( + transports.ControlServiceRestInterceptor, "post_list_controls_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ControlServiceRestInterceptor, "pre_list_controls" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = control_service.ListControlsRequest.pb( control_service.ListControlsRequest() ) @@ -5177,6 +5245,10 @@ def test_list_controls_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = control_service.ListControlsResponse() + post_with_metadata.return_value = ( + control_service.ListControlsResponse(), + metadata, + ) client.list_controls( request, @@ -5188,6 +5260,7 @@ def test_list_controls_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_conversational_search_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_conversational_search_service.py index bb2dc1ee5523..9c54f5455ccd 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_conversational_search_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_conversational_search_service.py @@ -72,6 +72,13 @@ from google.cloud.discoveryengine_v1beta.types import session from google.cloud.discoveryengine_v1beta.types import session as gcd_session +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -355,6 +362,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ConversationalSearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ConversationalSearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -9264,11 +9314,15 @@ def test_converse_conversation_rest_interceptors(null_interceptor): transports.ConversationalSearchServiceRestInterceptor, "post_converse_conversation", ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_converse_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_converse_conversation", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.ConverseConversationRequest.pb( conversational_search_service.ConverseConversationRequest() ) @@ -9296,6 +9350,10 @@ def test_converse_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.ConverseConversationResponse() + post_with_metadata.return_value = ( + conversational_search_service.ConverseConversationResponse(), + metadata, + ) client.converse_conversation( request, @@ -9307,6 +9365,7 @@ def test_converse_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_conversation_rest_bad_request( @@ -9531,10 +9590,14 @@ def test_create_conversation_rest_interceptors(null_interceptor): transports.ConversationalSearchServiceRestInterceptor, "post_create_conversation", ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_create_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_create_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.CreateConversationRequest.pb( conversational_search_service.CreateConversationRequest() ) @@ -9560,6 +9623,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.Conversation() + post_with_metadata.return_value = gcd_conversation.Conversation(), metadata client.create_conversation( request, @@ -9571,6 +9635,7 @@ def test_create_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_conversation_rest_bad_request( @@ -9916,10 +9981,14 @@ def test_update_conversation_rest_interceptors(null_interceptor): transports.ConversationalSearchServiceRestInterceptor, "post_update_conversation", ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_update_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_update_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.UpdateConversationRequest.pb( conversational_search_service.UpdateConversationRequest() ) @@ -9945,6 +10014,7 @@ def test_update_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_conversation.Conversation() + post_with_metadata.return_value = gcd_conversation.Conversation(), metadata client.update_conversation( request, @@ -9956,6 +10026,7 @@ def test_update_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_conversation_rest_bad_request( @@ -10048,10 +10119,14 @@ def test_get_conversation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_get_conversation" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_get_conversation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_get_conversation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.GetConversationRequest.pb( conversational_search_service.GetConversationRequest() ) @@ -10075,6 +10150,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversation.Conversation() + post_with_metadata.return_value = conversation.Conversation(), metadata client.get_conversation( request, @@ -10086,6 +10162,7 @@ def test_get_conversation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_conversations_rest_bad_request( @@ -10172,10 +10249,14 @@ def test_list_conversations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_list_conversations" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_list_conversations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_list_conversations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.ListConversationsRequest.pb( conversational_search_service.ListConversationsRequest() ) @@ -10201,6 +10282,10 @@ def test_list_conversations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.ListConversationsResponse() + post_with_metadata.return_value = ( + conversational_search_service.ListConversationsResponse(), + metadata, + ) client.list_conversations( request, @@ -10212,6 +10297,7 @@ def test_list_conversations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_answer_query_rest_bad_request( @@ -10302,10 +10388,14 @@ def test_answer_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_answer_query" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_answer_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_answer_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.AnswerQueryRequest.pb( conversational_search_service.AnswerQueryRequest() ) @@ -10331,6 +10421,10 @@ def test_answer_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.AnswerQueryResponse() + post_with_metadata.return_value = ( + conversational_search_service.AnswerQueryResponse(), + metadata, + ) client.answer_query( request, @@ -10342,6 +10436,7 @@ def test_answer_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_answer_rest_bad_request( @@ -10442,10 +10537,14 @@ def test_get_answer_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_get_answer" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_get_answer_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_get_answer" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.GetAnswerRequest.pb( conversational_search_service.GetAnswerRequest() ) @@ -10469,6 +10568,7 @@ def test_get_answer_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = answer.Answer() + post_with_metadata.return_value = answer.Answer(), metadata client.get_answer( request, @@ -10480,6 +10580,7 @@ def test_get_answer_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_session_rest_bad_request( @@ -10650,10 +10751,14 @@ def test_create_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_create_session" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_create_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_create_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.CreateSessionRequest.pb( conversational_search_service.CreateSessionRequest() ) @@ -10677,6 +10782,7 @@ def test_create_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session.Session() + post_with_metadata.return_value = gcd_session.Session(), metadata client.create_session( request, @@ -10688,6 +10794,7 @@ def test_create_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_session_rest_bad_request( @@ -10979,10 +11086,14 @@ def test_update_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_update_session" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_update_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_update_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.UpdateSessionRequest.pb( conversational_search_service.UpdateSessionRequest() ) @@ -11006,6 +11117,7 @@ def test_update_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_session.Session() + post_with_metadata.return_value = gcd_session.Session(), metadata client.update_session( request, @@ -11017,6 +11129,7 @@ def test_update_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_session_rest_bad_request( @@ -11109,10 +11222,14 @@ def test_get_session_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_get_session" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_get_session_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_get_session" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.GetSessionRequest.pb( conversational_search_service.GetSessionRequest() ) @@ -11136,6 +11253,7 @@ def test_get_session_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = session.Session() + post_with_metadata.return_value = session.Session(), metadata client.get_session( request, @@ -11147,6 +11265,7 @@ def test_get_session_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_sessions_rest_bad_request( @@ -11233,10 +11352,14 @@ def test_list_sessions_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "post_list_sessions" ) as post, mock.patch.object( + transports.ConversationalSearchServiceRestInterceptor, + "post_list_sessions_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ConversationalSearchServiceRestInterceptor, "pre_list_sessions" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = conversational_search_service.ListSessionsRequest.pb( conversational_search_service.ListSessionsRequest() ) @@ -11262,6 +11385,10 @@ def test_list_sessions_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = conversational_search_service.ListSessionsResponse() + post_with_metadata.return_value = ( + conversational_search_service.ListSessionsResponse(), + metadata, + ) client.list_sessions( request, @@ -11273,6 +11400,7 @@ def test_list_sessions_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_data_store_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_data_store_service.py index 4e5f3a2d51ec..a0cc6e0179d1 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_data_store_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_data_store_service.py @@ -82,6 +82,13 @@ from google.cloud.discoveryengine_v1beta.types import common from google.cloud.discoveryengine_v1beta.types import data_store +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -341,6 +348,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataStoreServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataStoreServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4667,10 +4717,14 @@ def test_create_data_store_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_create_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_create_data_store_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_create_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.CreateDataStoreRequest.pb( data_store_service.CreateDataStoreRequest() ) @@ -4694,6 +4748,7 @@ def test_create_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_data_store( request, @@ -4705,6 +4760,7 @@ def test_create_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_data_store_rest_bad_request( @@ -4799,10 +4855,13 @@ def test_get_data_store_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_get_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, "post_get_data_store_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_get_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.GetDataStoreRequest.pb( data_store_service.GetDataStoreRequest() ) @@ -4826,6 +4885,7 @@ def test_get_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = data_store.DataStore() + post_with_metadata.return_value = data_store.DataStore(), metadata client.get_data_store( request, @@ -4837,6 +4897,7 @@ def test_get_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_data_stores_rest_bad_request( @@ -4921,10 +4982,14 @@ def test_list_data_stores_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_list_data_stores" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_list_data_stores_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_list_data_stores" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.ListDataStoresRequest.pb( data_store_service.ListDataStoresRequest() ) @@ -4950,6 +5015,10 @@ def test_list_data_stores_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = data_store_service.ListDataStoresResponse() + post_with_metadata.return_value = ( + data_store_service.ListDataStoresResponse(), + metadata, + ) client.list_data_stores( request, @@ -4961,6 +5030,7 @@ def test_list_data_stores_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_data_store_rest_bad_request( @@ -5041,10 +5111,14 @@ def test_delete_data_store_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_delete_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_delete_data_store_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_delete_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.DeleteDataStoreRequest.pb( data_store_service.DeleteDataStoreRequest() ) @@ -5068,6 +5142,7 @@ def test_delete_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_data_store( request, @@ -5079,6 +5154,7 @@ def test_delete_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_data_store_rest_bad_request( @@ -5301,10 +5377,14 @@ def test_update_data_store_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DataStoreServiceRestInterceptor, "post_update_data_store" ) as post, mock.patch.object( + transports.DataStoreServiceRestInterceptor, + "post_update_data_store_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DataStoreServiceRestInterceptor, "pre_update_data_store" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = data_store_service.UpdateDataStoreRequest.pb( data_store_service.UpdateDataStoreRequest() ) @@ -5328,6 +5408,7 @@ def test_update_data_store_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_data_store.DataStore() + post_with_metadata.return_value = gcd_data_store.DataStore(), metadata client.update_data_store( request, @@ -5339,6 +5420,7 @@ def test_update_data_store_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_document_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_document_service.py index 625f966dd7d3..520fb56eaf0b 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_document_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_document_service.py @@ -83,6 +83,13 @@ from google.cloud.discoveryengine_v1beta.types import document from google.cloud.discoveryengine_v1beta.types import document as gcd_document +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -341,6 +348,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DocumentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DocumentServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6013,10 +6063,13 @@ def test_get_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_get_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_get_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_get_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.GetDocumentRequest.pb( document_service.GetDocumentRequest() ) @@ -6040,6 +6093,7 @@ def test_get_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document.Document() + post_with_metadata.return_value = document.Document(), metadata client.get_document( request, @@ -6051,6 +6105,7 @@ def test_get_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_documents_rest_bad_request( @@ -6139,10 +6194,13 @@ def test_list_documents_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_list_documents" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_list_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_list_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.ListDocumentsRequest.pb( document_service.ListDocumentsRequest() ) @@ -6168,6 +6226,10 @@ def test_list_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document_service.ListDocumentsResponse() + post_with_metadata.return_value = ( + document_service.ListDocumentsResponse(), + metadata, + ) client.list_documents( request, @@ -6179,6 +6241,7 @@ def test_list_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_document_rest_bad_request( @@ -6371,10 +6434,13 @@ def test_create_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_create_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_create_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_create_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.CreateDocumentRequest.pb( document_service.CreateDocumentRequest() ) @@ -6398,6 +6464,7 @@ def test_create_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_document.Document() + post_with_metadata.return_value = gcd_document.Document(), metadata client.create_document( request, @@ -6409,6 +6476,7 @@ def test_create_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_document_rest_bad_request( @@ -6605,10 +6673,13 @@ def test_update_document_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_update_document" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_update_document_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_update_document" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.UpdateDocumentRequest.pb( document_service.UpdateDocumentRequest() ) @@ -6632,6 +6703,7 @@ def test_update_document_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_document.Document() + post_with_metadata.return_value = gcd_document.Document(), metadata client.update_document( request, @@ -6643,6 +6715,7 @@ def test_update_document_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_document_rest_bad_request( @@ -6840,10 +6913,13 @@ def test_import_documents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentServiceRestInterceptor, "post_import_documents" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_import_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_import_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportDocumentsRequest.pb( import_config.ImportDocumentsRequest() ) @@ -6867,6 +6943,7 @@ def test_import_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_documents( request, @@ -6878,6 +6955,7 @@ def test_import_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_documents_rest_bad_request( @@ -6962,10 +7040,13 @@ def test_purge_documents_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DocumentServiceRestInterceptor, "post_purge_documents" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, "post_purge_documents_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_purge_documents" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeDocumentsRequest.pb( purge_config.PurgeDocumentsRequest() ) @@ -6989,6 +7070,7 @@ def test_purge_documents_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_documents( request, @@ -7000,6 +7082,7 @@ def test_purge_documents_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_get_documents_metadata_rest_bad_request( @@ -7087,10 +7170,14 @@ def test_batch_get_documents_metadata_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DocumentServiceRestInterceptor, "post_batch_get_documents_metadata" ) as post, mock.patch.object( + transports.DocumentServiceRestInterceptor, + "post_batch_get_documents_metadata_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DocumentServiceRestInterceptor, "pre_batch_get_documents_metadata" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = document_service.BatchGetDocumentsMetadataRequest.pb( document_service.BatchGetDocumentsMetadataRequest() ) @@ -7116,6 +7203,10 @@ def test_batch_get_documents_metadata_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = document_service.BatchGetDocumentsMetadataResponse() + post_with_metadata.return_value = ( + document_service.BatchGetDocumentsMetadataResponse(), + metadata, + ) client.batch_get_documents_metadata( request, @@ -7127,6 +7218,7 @@ def test_batch_get_documents_metadata_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_engine_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_engine_service.py index 057afab34583..f53860eda10c 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_engine_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_engine_service.py @@ -77,6 +77,13 @@ from google.cloud.discoveryengine_v1beta.types import engine as gcd_engine from google.cloud.discoveryengine_v1beta.types import engine_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -331,6 +338,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -6296,10 +6346,13 @@ def test_create_engine_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EngineServiceRestInterceptor, "post_create_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_create_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_create_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.CreateEngineRequest.pb( engine_service.CreateEngineRequest() ) @@ -6323,6 +6376,7 @@ def test_create_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_engine( request, @@ -6334,6 +6388,7 @@ def test_create_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_engine_rest_bad_request( @@ -6418,10 +6473,13 @@ def test_delete_engine_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EngineServiceRestInterceptor, "post_delete_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_delete_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_delete_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.DeleteEngineRequest.pb( engine_service.DeleteEngineRequest() ) @@ -6445,6 +6503,7 @@ def test_delete_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_engine( request, @@ -6456,6 +6515,7 @@ def test_delete_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_engine_rest_bad_request( @@ -6647,10 +6707,13 @@ def test_update_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_update_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_update_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_update_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.UpdateEngineRequest.pb( engine_service.UpdateEngineRequest() ) @@ -6674,6 +6737,7 @@ def test_update_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_engine.Engine() + post_with_metadata.return_value = gcd_engine.Engine(), metadata client.update_engine( request, @@ -6685,6 +6749,7 @@ def test_update_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_engine_rest_bad_request(request_type=engine_service.GetEngineRequest): @@ -6781,10 +6846,13 @@ def test_get_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_get_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_get_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_get_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.GetEngineRequest.pb( engine_service.GetEngineRequest() ) @@ -6808,6 +6876,7 @@ def test_get_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine.Engine() + post_with_metadata.return_value = engine.Engine(), metadata client.get_engine( request, @@ -6819,6 +6888,7 @@ def test_get_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_engines_rest_bad_request(request_type=engine_service.ListEnginesRequest): @@ -6901,10 +6971,13 @@ def test_list_engines_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_list_engines" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_list_engines_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_list_engines" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.ListEnginesRequest.pb( engine_service.ListEnginesRequest() ) @@ -6930,6 +7003,7 @@ def test_list_engines_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine_service.ListEnginesResponse() + post_with_metadata.return_value = engine_service.ListEnginesResponse(), metadata client.list_engines( request, @@ -6941,6 +7015,7 @@ def test_list_engines_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_pause_engine_rest_bad_request(request_type=engine_service.PauseEngineRequest): @@ -7037,10 +7112,13 @@ def test_pause_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_pause_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_pause_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_pause_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.PauseEngineRequest.pb( engine_service.PauseEngineRequest() ) @@ -7064,6 +7142,7 @@ def test_pause_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine.Engine() + post_with_metadata.return_value = engine.Engine(), metadata client.pause_engine( request, @@ -7075,6 +7154,7 @@ def test_pause_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_resume_engine_rest_bad_request( @@ -7173,10 +7253,13 @@ def test_resume_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EngineServiceRestInterceptor, "post_resume_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_resume_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_resume_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.ResumeEngineRequest.pb( engine_service.ResumeEngineRequest() ) @@ -7200,6 +7283,7 @@ def test_resume_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = engine.Engine() + post_with_metadata.return_value = engine.Engine(), metadata client.resume_engine( request, @@ -7211,6 +7295,7 @@ def test_resume_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_tune_engine_rest_bad_request(request_type=engine_service.TuneEngineRequest): @@ -7293,10 +7378,13 @@ def test_tune_engine_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EngineServiceRestInterceptor, "post_tune_engine" ) as post, mock.patch.object( + transports.EngineServiceRestInterceptor, "post_tune_engine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EngineServiceRestInterceptor, "pre_tune_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = engine_service.TuneEngineRequest.pb( engine_service.TuneEngineRequest() ) @@ -7320,6 +7408,7 @@ def test_tune_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.tune_engine( request, @@ -7331,6 +7420,7 @@ def test_tune_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_evaluation_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_evaluation_service.py index 1d2a7ae21374..e93b9fb8fa00 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_evaluation_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_evaluation_service.py @@ -78,6 +78,13 @@ from google.cloud.discoveryengine_v1beta.types import common from google.cloud.discoveryengine_v1beta.types import evaluation +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -345,6 +352,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EvaluationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EvaluationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4188,10 +4238,13 @@ def test_get_evaluation_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, "post_get_evaluation" ) as post, mock.patch.object( + transports.EvaluationServiceRestInterceptor, "post_get_evaluation_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, "pre_get_evaluation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = evaluation_service.GetEvaluationRequest.pb( evaluation_service.GetEvaluationRequest() ) @@ -4215,6 +4268,7 @@ def test_get_evaluation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = evaluation.Evaluation() + post_with_metadata.return_value = evaluation.Evaluation(), metadata client.get_evaluation( request, @@ -4226,6 +4280,7 @@ def test_get_evaluation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_evaluations_rest_bad_request( @@ -4310,10 +4365,14 @@ def test_list_evaluations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, "post_list_evaluations" ) as post, mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_list_evaluations_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, "pre_list_evaluations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = evaluation_service.ListEvaluationsRequest.pb( evaluation_service.ListEvaluationsRequest() ) @@ -4339,6 +4398,10 @@ def test_list_evaluations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = evaluation_service.ListEvaluationsResponse() + post_with_metadata.return_value = ( + evaluation_service.ListEvaluationsResponse(), + metadata, + ) client.list_evaluations( request, @@ -4350,6 +4413,7 @@ def test_list_evaluations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_evaluation_rest_bad_request( @@ -4660,10 +4724,14 @@ def test_create_evaluation_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EvaluationServiceRestInterceptor, "post_create_evaluation" ) as post, mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_create_evaluation_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, "pre_create_evaluation" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = evaluation_service.CreateEvaluationRequest.pb( evaluation_service.CreateEvaluationRequest() ) @@ -4687,6 +4755,7 @@ def test_create_evaluation_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_evaluation( request, @@ -4698,6 +4767,7 @@ def test_create_evaluation_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_evaluation_results_rest_bad_request( @@ -4786,10 +4856,14 @@ def test_list_evaluation_results_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EvaluationServiceRestInterceptor, "post_list_evaluation_results" ) as post, mock.patch.object( + transports.EvaluationServiceRestInterceptor, + "post_list_evaluation_results_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EvaluationServiceRestInterceptor, "pre_list_evaluation_results" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = evaluation_service.ListEvaluationResultsRequest.pb( evaluation_service.ListEvaluationResultsRequest() ) @@ -4815,6 +4889,10 @@ def test_list_evaluation_results_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = evaluation_service.ListEvaluationResultsResponse() + post_with_metadata.return_value = ( + evaluation_service.ListEvaluationResultsResponse(), + metadata, + ) client.list_evaluation_results( request, @@ -4826,6 +4904,7 @@ def test_list_evaluation_results_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_grounded_generation_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_grounded_generation_service.py index c2dd3c928427..c77ee91fdd33 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_grounded_generation_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_grounded_generation_service.py @@ -64,6 +64,13 @@ grounding, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = GroundedGenerationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = GroundedGenerationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2396,11 +2446,15 @@ def test_generate_grounded_content_rest_interceptors(null_interceptor): transports.GroundedGenerationServiceRestInterceptor, "post_generate_grounded_content", ) as post, mock.patch.object( + transports.GroundedGenerationServiceRestInterceptor, + "post_generate_grounded_content_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.GroundedGenerationServiceRestInterceptor, "pre_generate_grounded_content", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = grounded_generation_service.GenerateGroundedContentRequest.pb( grounded_generation_service.GenerateGroundedContentRequest() ) @@ -2430,6 +2484,10 @@ def test_generate_grounded_content_rest_interceptors(null_interceptor): post.return_value = ( grounded_generation_service.GenerateGroundedContentResponse() ) + post_with_metadata.return_value = ( + grounded_generation_service.GenerateGroundedContentResponse(), + metadata, + ) client.generate_grounded_content( request, @@ -2441,6 +2499,7 @@ def test_generate_grounded_content_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_check_grounding_rest_bad_request( @@ -2531,10 +2590,14 @@ def test_check_grounding_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.GroundedGenerationServiceRestInterceptor, "post_check_grounding" ) as post, mock.patch.object( + transports.GroundedGenerationServiceRestInterceptor, + "post_check_grounding_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.GroundedGenerationServiceRestInterceptor, "pre_check_grounding" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = grounded_generation_service.CheckGroundingRequest.pb( grounded_generation_service.CheckGroundingRequest() ) @@ -2560,6 +2623,10 @@ def test_check_grounding_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = grounded_generation_service.CheckGroundingResponse() + post_with_metadata.return_value = ( + grounded_generation_service.CheckGroundingResponse(), + metadata, + ) client.check_grounding( request, @@ -2571,6 +2638,7 @@ def test_check_grounding_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_project_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_project_service.py index 279035c4b685..d0960ca28352 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_project_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_project_service.py @@ -70,6 +70,13 @@ ) from google.cloud.discoveryengine_v1beta.types import project, project_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -328,6 +335,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ProjectServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ProjectServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1866,10 +1916,13 @@ def test_provision_project_rest_interceptors(null_interceptor): ), mock.patch.object( transports.ProjectServiceRestInterceptor, "post_provision_project" ) as post, mock.patch.object( + transports.ProjectServiceRestInterceptor, "post_provision_project_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.ProjectServiceRestInterceptor, "pre_provision_project" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = project_service.ProvisionProjectRequest.pb( project_service.ProvisionProjectRequest() ) @@ -1893,6 +1946,7 @@ def test_provision_project_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.provision_project( request, @@ -1904,6 +1958,7 @@ def test_provision_project_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_rank_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_rank_service.py index 8f587ba6b6a0..36752e2d20b4 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_rank_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_rank_service.py @@ -61,6 +61,13 @@ ) from google.cloud.discoveryengine_v1beta.types import rank_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -300,6 +307,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = RankServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = RankServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1641,10 +1691,13 @@ def test_rank_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.RankServiceRestInterceptor, "post_rank" ) as post, mock.patch.object( + transports.RankServiceRestInterceptor, "post_rank_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.RankServiceRestInterceptor, "pre_rank" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = rank_service.RankRequest.pb(rank_service.RankRequest()) transcode.return_value = { "method": "post", @@ -1666,6 +1719,7 @@ def test_rank_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = rank_service.RankResponse() + post_with_metadata.return_value = rank_service.RankResponse(), metadata client.rank( request, @@ -1677,6 +1731,7 @@ def test_rank_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_recommendation_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_recommendation_service.py index 8b96cb441be8..31346677c6a4 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_recommendation_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_recommendation_service.py @@ -68,6 +68,13 @@ user_event, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = RecommendationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = RecommendationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -1776,10 +1826,13 @@ def test_recommend_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.RecommendationServiceRestInterceptor, "post_recommend" ) as post, mock.patch.object( + transports.RecommendationServiceRestInterceptor, "post_recommend_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.RecommendationServiceRestInterceptor, "pre_recommend" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = recommendation_service.RecommendRequest.pb( recommendation_service.RecommendRequest() ) @@ -1805,6 +1858,10 @@ def test_recommend_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = recommendation_service.RecommendResponse() + post_with_metadata.return_value = ( + recommendation_service.RecommendResponse(), + metadata, + ) client.recommend( request, @@ -1816,6 +1873,7 @@ def test_recommend_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_sample_query_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_sample_query_service.py index 65dc921f35c6..0f54db70fafd 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_sample_query_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_sample_query_service.py @@ -77,6 +77,13 @@ from google.cloud.discoveryengine_v1beta.types import sample_query from google.cloud.discoveryengine_v1beta.types import sample_query_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -348,6 +355,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SampleQueryServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SampleQueryServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4994,10 +5044,14 @@ def test_get_sample_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_get_sample_query" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_get_sample_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_get_sample_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_service.GetSampleQueryRequest.pb( sample_query_service.GetSampleQueryRequest() ) @@ -5021,6 +5075,7 @@ def test_get_sample_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sample_query.SampleQuery() + post_with_metadata.return_value = sample_query.SampleQuery(), metadata client.get_sample_query( request, @@ -5032,6 +5087,7 @@ def test_get_sample_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_sample_queries_rest_bad_request( @@ -5120,10 +5176,14 @@ def test_list_sample_queries_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_list_sample_queries" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_list_sample_queries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_list_sample_queries" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_service.ListSampleQueriesRequest.pb( sample_query_service.ListSampleQueriesRequest() ) @@ -5149,6 +5209,10 @@ def test_list_sample_queries_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sample_query_service.ListSampleQueriesResponse() + post_with_metadata.return_value = ( + sample_query_service.ListSampleQueriesResponse(), + metadata, + ) client.list_sample_queries( request, @@ -5160,6 +5224,7 @@ def test_list_sample_queries_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_sample_query_rest_bad_request( @@ -5327,10 +5392,14 @@ def test_create_sample_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_create_sample_query" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_create_sample_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_create_sample_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_service.CreateSampleQueryRequest.pb( sample_query_service.CreateSampleQueryRequest() ) @@ -5356,6 +5425,7 @@ def test_create_sample_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sample_query.SampleQuery() + post_with_metadata.return_value = gcd_sample_query.SampleQuery(), metadata client.create_sample_query( request, @@ -5367,6 +5437,7 @@ def test_create_sample_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_sample_query_rest_bad_request( @@ -5538,10 +5609,14 @@ def test_update_sample_query_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_update_sample_query" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_update_sample_query_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_update_sample_query" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_service.UpdateSampleQueryRequest.pb( sample_query_service.UpdateSampleQueryRequest() ) @@ -5567,6 +5642,7 @@ def test_update_sample_query_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sample_query.SampleQuery() + post_with_metadata.return_value = gcd_sample_query.SampleQuery(), metadata client.update_sample_query( request, @@ -5578,6 +5654,7 @@ def test_update_sample_query_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_sample_query_rest_bad_request( @@ -5775,10 +5852,14 @@ def test_import_sample_queries_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SampleQueryServiceRestInterceptor, "post_import_sample_queries" ) as post, mock.patch.object( + transports.SampleQueryServiceRestInterceptor, + "post_import_sample_queries_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQueryServiceRestInterceptor, "pre_import_sample_queries" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportSampleQueriesRequest.pb( import_config.ImportSampleQueriesRequest() ) @@ -5802,6 +5883,7 @@ def test_import_sample_queries_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_sample_queries( request, @@ -5813,6 +5895,7 @@ def test_import_sample_queries_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_sample_query_set_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_sample_query_set_service.py index 0fbcaa71b50b..aab62fe7fb47 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_sample_query_set_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_sample_query_set_service.py @@ -68,6 +68,13 @@ from google.cloud.discoveryengine_v1beta.types import sample_query_set from google.cloud.discoveryengine_v1beta.types import sample_query_set_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -343,6 +350,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SampleQuerySetServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SampleQuerySetServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4598,10 +4648,14 @@ def test_get_sample_query_set_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "post_get_sample_query_set" ) as post, mock.patch.object( + transports.SampleQuerySetServiceRestInterceptor, + "post_get_sample_query_set_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "pre_get_sample_query_set" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_set_service.GetSampleQuerySetRequest.pb( sample_query_set_service.GetSampleQuerySetRequest() ) @@ -4627,6 +4681,7 @@ def test_get_sample_query_set_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sample_query_set.SampleQuerySet() + post_with_metadata.return_value = sample_query_set.SampleQuerySet(), metadata client.get_sample_query_set( request, @@ -4638,6 +4693,7 @@ def test_get_sample_query_set_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_sample_query_sets_rest_bad_request( @@ -4724,10 +4780,14 @@ def test_list_sample_query_sets_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "post_list_sample_query_sets" ) as post, mock.patch.object( + transports.SampleQuerySetServiceRestInterceptor, + "post_list_sample_query_sets_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "pre_list_sample_query_sets" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_set_service.ListSampleQuerySetsRequest.pb( sample_query_set_service.ListSampleQuerySetsRequest() ) @@ -4753,6 +4813,10 @@ def test_list_sample_query_sets_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = sample_query_set_service.ListSampleQuerySetsResponse() + post_with_metadata.return_value = ( + sample_query_set_service.ListSampleQuerySetsResponse(), + metadata, + ) client.list_sample_query_sets( request, @@ -4764,6 +4828,7 @@ def test_list_sample_query_sets_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_sample_query_set_rest_bad_request( @@ -4927,10 +4992,14 @@ def test_create_sample_query_set_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "post_create_sample_query_set" ) as post, mock.patch.object( + transports.SampleQuerySetServiceRestInterceptor, + "post_create_sample_query_set_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "pre_create_sample_query_set" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_set_service.CreateSampleQuerySetRequest.pb( sample_query_set_service.CreateSampleQuerySetRequest() ) @@ -4956,6 +5025,10 @@ def test_create_sample_query_set_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sample_query_set.SampleQuerySet() + post_with_metadata.return_value = ( + gcd_sample_query_set.SampleQuerySet(), + metadata, + ) client.create_sample_query_set( request, @@ -4967,6 +5040,7 @@ def test_create_sample_query_set_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_sample_query_set_rest_bad_request( @@ -5138,10 +5212,14 @@ def test_update_sample_query_set_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "post_update_sample_query_set" ) as post, mock.patch.object( + transports.SampleQuerySetServiceRestInterceptor, + "post_update_sample_query_set_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SampleQuerySetServiceRestInterceptor, "pre_update_sample_query_set" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = sample_query_set_service.UpdateSampleQuerySetRequest.pb( sample_query_set_service.UpdateSampleQuerySetRequest() ) @@ -5167,6 +5245,10 @@ def test_update_sample_query_set_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_sample_query_set.SampleQuerySet() + post_with_metadata.return_value = ( + gcd_sample_query_set.SampleQuerySet(), + metadata, + ) client.update_sample_query_set( request, @@ -5178,6 +5260,7 @@ def test_update_sample_query_set_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_sample_query_set_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_schema_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_schema_service.py index 23af64632394..15ed039ae838 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_schema_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_schema_service.py @@ -75,6 +75,13 @@ from google.cloud.discoveryengine_v1beta.types import schema as gcd_schema from google.cloud.discoveryengine_v1beta.types import schema_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -329,6 +336,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SchemaServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SchemaServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -4279,10 +4329,13 @@ def test_get_schema_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_get_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_get_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_get_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.GetSchemaRequest.pb( schema_service.GetSchemaRequest() ) @@ -4306,6 +4359,7 @@ def test_get_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema.Schema() + post_with_metadata.return_value = schema.Schema(), metadata client.get_schema( request, @@ -4317,6 +4371,7 @@ def test_get_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_schemas_rest_bad_request(request_type=schema_service.ListSchemasRequest): @@ -4399,10 +4454,13 @@ def test_list_schemas_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SchemaServiceRestInterceptor, "post_list_schemas" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_list_schemas_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_list_schemas" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.ListSchemasRequest.pb( schema_service.ListSchemasRequest() ) @@ -4428,6 +4486,7 @@ def test_list_schemas_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = schema_service.ListSchemasResponse() + post_with_metadata.return_value = schema_service.ListSchemasResponse(), metadata client.list_schemas( request, @@ -4439,6 +4498,7 @@ def test_list_schemas_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_schema_rest_bad_request( @@ -4591,10 +4651,13 @@ def test_create_schema_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SchemaServiceRestInterceptor, "post_create_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_create_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_create_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.CreateSchemaRequest.pb( schema_service.CreateSchemaRequest() ) @@ -4618,6 +4681,7 @@ def test_create_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_schema( request, @@ -4629,6 +4693,7 @@ def test_create_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_schema_rest_bad_request( @@ -4789,10 +4854,13 @@ def test_update_schema_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SchemaServiceRestInterceptor, "post_update_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_update_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_update_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.UpdateSchemaRequest.pb( schema_service.UpdateSchemaRequest() ) @@ -4816,6 +4884,7 @@ def test_update_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_schema( request, @@ -4827,6 +4896,7 @@ def test_update_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_schema_rest_bad_request( @@ -4911,10 +4981,13 @@ def test_delete_schema_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SchemaServiceRestInterceptor, "post_delete_schema" ) as post, mock.patch.object( + transports.SchemaServiceRestInterceptor, "post_delete_schema_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SchemaServiceRestInterceptor, "pre_delete_schema" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = schema_service.DeleteSchemaRequest.pb( schema_service.DeleteSchemaRequest() ) @@ -4938,6 +5011,7 @@ def test_delete_schema_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_schema( request, @@ -4949,6 +5023,7 @@ def test_delete_schema_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_search_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_search_service.py index 20856a1cd905..91e48c5c6b3e 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_search_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_search_service.py @@ -63,6 +63,13 @@ ) from google.cloud.discoveryengine_v1beta.types import common, search_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -317,6 +324,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SearchServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2712,10 +2762,13 @@ def test_search_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SearchServiceRestInterceptor, "post_search" ) as post, mock.patch.object( + transports.SearchServiceRestInterceptor, "post_search_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SearchServiceRestInterceptor, "pre_search" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_service.SearchRequest.pb(search_service.SearchRequest()) transcode.return_value = { "method": "post", @@ -2739,6 +2792,7 @@ def test_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = search_service.SearchResponse() + post_with_metadata.return_value = search_service.SearchResponse(), metadata client.search( request, @@ -2750,6 +2804,7 @@ def test_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_search_lite_rest_bad_request(request_type=search_service.SearchRequest): @@ -2846,10 +2901,13 @@ def test_search_lite_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SearchServiceRestInterceptor, "post_search_lite" ) as post, mock.patch.object( + transports.SearchServiceRestInterceptor, "post_search_lite_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.SearchServiceRestInterceptor, "pre_search_lite" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_service.SearchRequest.pb(search_service.SearchRequest()) transcode.return_value = { "method": "post", @@ -2873,6 +2931,7 @@ def test_search_lite_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = search_service.SearchResponse() + post_with_metadata.return_value = search_service.SearchResponse(), metadata client.search_lite( request, @@ -2884,6 +2943,7 @@ def test_search_lite_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_search_tuning_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_search_tuning_service.py index 801bfbda6422..7d8522748933 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_search_tuning_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_search_tuning_service.py @@ -74,6 +74,13 @@ search_tuning_service, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -347,6 +354,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SearchTuningServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SearchTuningServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -2209,10 +2259,14 @@ def test_train_custom_model_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SearchTuningServiceRestInterceptor, "post_train_custom_model" ) as post, mock.patch.object( + transports.SearchTuningServiceRestInterceptor, + "post_train_custom_model_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SearchTuningServiceRestInterceptor, "pre_train_custom_model" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_tuning_service.TrainCustomModelRequest.pb( search_tuning_service.TrainCustomModelRequest() ) @@ -2236,6 +2290,7 @@ def test_train_custom_model_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.train_custom_model( request, @@ -2247,6 +2302,7 @@ def test_train_custom_model_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_custom_models_rest_bad_request( @@ -2332,10 +2388,14 @@ def test_list_custom_models_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SearchTuningServiceRestInterceptor, "post_list_custom_models" ) as post, mock.patch.object( + transports.SearchTuningServiceRestInterceptor, + "post_list_custom_models_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SearchTuningServiceRestInterceptor, "pre_list_custom_models" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = search_tuning_service.ListCustomModelsRequest.pb( search_tuning_service.ListCustomModelsRequest() ) @@ -2361,6 +2421,10 @@ def test_list_custom_models_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = search_tuning_service.ListCustomModelsResponse() + post_with_metadata.return_value = ( + search_tuning_service.ListCustomModelsResponse(), + metadata, + ) client.list_custom_models( request, @@ -2372,6 +2436,7 @@ def test_list_custom_models_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_serving_config_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_serving_config_service.py index 8d7e0b3863ff..ca255027b712 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_serving_config_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_serving_config_service.py @@ -69,6 +69,13 @@ from google.cloud.discoveryengine_v1beta.types import serving_config from google.cloud.discoveryengine_v1beta.types import serving_config_service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -342,6 +349,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = ServingConfigServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = ServingConfigServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3714,10 +3764,14 @@ def test_update_serving_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "post_update_serving_config" ) as post, mock.patch.object( + transports.ServingConfigServiceRestInterceptor, + "post_update_serving_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "pre_update_serving_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = serving_config_service.UpdateServingConfigRequest.pb( serving_config_service.UpdateServingConfigRequest() ) @@ -3743,6 +3797,7 @@ def test_update_serving_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = gcd_serving_config.ServingConfig() + post_with_metadata.return_value = gcd_serving_config.ServingConfig(), metadata client.update_serving_config( request, @@ -3754,6 +3809,7 @@ def test_update_serving_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_serving_config_rest_bad_request( @@ -3868,10 +3924,14 @@ def test_get_serving_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "post_get_serving_config" ) as post, mock.patch.object( + transports.ServingConfigServiceRestInterceptor, + "post_get_serving_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "pre_get_serving_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = serving_config_service.GetServingConfigRequest.pb( serving_config_service.GetServingConfigRequest() ) @@ -3897,6 +3957,7 @@ def test_get_serving_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = serving_config.ServingConfig() + post_with_metadata.return_value = serving_config.ServingConfig(), metadata client.get_serving_config( request, @@ -3908,6 +3969,7 @@ def test_get_serving_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_serving_configs_rest_bad_request( @@ -3994,10 +4056,14 @@ def test_list_serving_configs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "post_list_serving_configs" ) as post, mock.patch.object( + transports.ServingConfigServiceRestInterceptor, + "post_list_serving_configs_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.ServingConfigServiceRestInterceptor, "pre_list_serving_configs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = serving_config_service.ListServingConfigsRequest.pb( serving_config_service.ListServingConfigsRequest() ) @@ -4023,6 +4089,10 @@ def test_list_serving_configs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = serving_config_service.ListServingConfigsResponse() + post_with_metadata.return_value = ( + serving_config_service.ListServingConfigsResponse(), + metadata, + ) client.list_serving_configs( request, @@ -4034,6 +4104,7 @@ def test_list_serving_configs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_site_search_engine_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_site_search_engine_service.py index 3ccf42fdac52..15d74781cda2 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_site_search_engine_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_site_search_engine_service.py @@ -76,6 +76,13 @@ site_search_engine_service, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -351,6 +358,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = SiteSearchEngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = SiteSearchEngineServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -9744,10 +9794,14 @@ def test_get_site_search_engine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_get_site_search_engine" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_get_site_search_engine_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_get_site_search_engine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.GetSiteSearchEngineRequest.pb( site_search_engine_service.GetSiteSearchEngineRequest() ) @@ -9773,6 +9827,10 @@ def test_get_site_search_engine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine.SiteSearchEngine() + post_with_metadata.return_value = ( + site_search_engine.SiteSearchEngine(), + metadata, + ) client.get_site_search_engine( request, @@ -9784,6 +9842,7 @@ def test_get_site_search_engine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_target_site_rest_bad_request( @@ -9952,10 +10011,14 @@ def test_create_target_site_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_create_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_create_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_create_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.CreateTargetSiteRequest.pb( site_search_engine_service.CreateTargetSiteRequest() ) @@ -9979,6 +10042,7 @@ def test_create_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_target_site( request, @@ -9990,6 +10054,7 @@ def test_create_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_create_target_sites_rest_bad_request( @@ -10075,11 +10140,15 @@ def test_batch_create_target_sites_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_batch_create_target_sites", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_batch_create_target_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_batch_create_target_sites", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.BatchCreateTargetSitesRequest.pb( site_search_engine_service.BatchCreateTargetSitesRequest() ) @@ -10103,6 +10172,7 @@ def test_batch_create_target_sites_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_create_target_sites( request, @@ -10114,6 +10184,7 @@ def test_batch_create_target_sites_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_target_site_rest_bad_request( @@ -10216,10 +10287,14 @@ def test_get_target_site_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_get_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_get_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_get_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.GetTargetSiteRequest.pb( site_search_engine_service.GetTargetSiteRequest() ) @@ -10245,6 +10320,7 @@ def test_get_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine.TargetSite() + post_with_metadata.return_value = site_search_engine.TargetSite(), metadata client.get_target_site( request, @@ -10256,6 +10332,7 @@ def test_get_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_target_site_rest_bad_request( @@ -10428,10 +10505,14 @@ def test_update_target_site_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_update_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_update_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_update_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.UpdateTargetSiteRequest.pb( site_search_engine_service.UpdateTargetSiteRequest() ) @@ -10455,6 +10536,7 @@ def test_update_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_target_site( request, @@ -10466,6 +10548,7 @@ def test_update_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_target_site_rest_bad_request( @@ -10550,10 +10633,14 @@ def test_delete_target_site_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_delete_target_site" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_delete_target_site_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_delete_target_site" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.DeleteTargetSiteRequest.pb( site_search_engine_service.DeleteTargetSiteRequest() ) @@ -10577,6 +10664,7 @@ def test_delete_target_site_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_target_site( request, @@ -10588,6 +10676,7 @@ def test_delete_target_site_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_target_sites_rest_bad_request( @@ -10680,10 +10769,14 @@ def test_list_target_sites_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_list_target_sites" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_list_target_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_list_target_sites" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.ListTargetSitesRequest.pb( site_search_engine_service.ListTargetSitesRequest() ) @@ -10709,6 +10802,10 @@ def test_list_target_sites_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine_service.ListTargetSitesResponse() + post_with_metadata.return_value = ( + site_search_engine_service.ListTargetSitesResponse(), + metadata, + ) client.list_target_sites( request, @@ -10720,6 +10817,7 @@ def test_list_target_sites_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_sitemap_rest_bad_request( @@ -10876,10 +10974,14 @@ def test_create_sitemap_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_create_sitemap" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_create_sitemap_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_create_sitemap" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.CreateSitemapRequest.pb( site_search_engine_service.CreateSitemapRequest() ) @@ -10903,6 +11005,7 @@ def test_create_sitemap_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_sitemap( request, @@ -10914,6 +11017,7 @@ def test_create_sitemap_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_sitemap_rest_bad_request( @@ -10998,10 +11102,14 @@ def test_delete_sitemap_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_delete_sitemap" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_delete_sitemap_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_delete_sitemap" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.DeleteSitemapRequest.pb( site_search_engine_service.DeleteSitemapRequest() ) @@ -11025,6 +11133,7 @@ def test_delete_sitemap_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_sitemap( request, @@ -11036,6 +11145,7 @@ def test_delete_sitemap_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_sitemaps_rest_bad_request( @@ -11121,10 +11231,14 @@ def test_fetch_sitemaps_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_fetch_sitemaps" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_fetch_sitemaps_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_fetch_sitemaps" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.FetchSitemapsRequest.pb( site_search_engine_service.FetchSitemapsRequest() ) @@ -11150,6 +11264,10 @@ def test_fetch_sitemaps_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = site_search_engine_service.FetchSitemapsResponse() + post_with_metadata.return_value = ( + site_search_engine_service.FetchSitemapsResponse(), + metadata, + ) client.fetch_sitemaps( request, @@ -11161,6 +11279,7 @@ def test_fetch_sitemaps_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_enable_advanced_site_search_rest_bad_request( @@ -11246,11 +11365,15 @@ def test_enable_advanced_site_search_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_enable_advanced_site_search", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_enable_advanced_site_search_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_enable_advanced_site_search", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.EnableAdvancedSiteSearchRequest.pb( site_search_engine_service.EnableAdvancedSiteSearchRequest() ) @@ -11274,6 +11397,7 @@ def test_enable_advanced_site_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.enable_advanced_site_search( request, @@ -11285,6 +11409,7 @@ def test_enable_advanced_site_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_disable_advanced_site_search_rest_bad_request( @@ -11370,11 +11495,15 @@ def test_disable_advanced_site_search_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_disable_advanced_site_search", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_disable_advanced_site_search_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_disable_advanced_site_search", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.DisableAdvancedSiteSearchRequest.pb( site_search_engine_service.DisableAdvancedSiteSearchRequest() ) @@ -11398,6 +11527,7 @@ def test_disable_advanced_site_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.disable_advanced_site_search( request, @@ -11409,6 +11539,7 @@ def test_disable_advanced_site_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_recrawl_uris_rest_bad_request( @@ -11493,10 +11624,14 @@ def test_recrawl_uris_rest_interceptors(null_interceptor): ), mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "post_recrawl_uris" ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_recrawl_uris_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_recrawl_uris" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.RecrawlUrisRequest.pb( site_search_engine_service.RecrawlUrisRequest() ) @@ -11520,6 +11655,7 @@ def test_recrawl_uris_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.recrawl_uris( request, @@ -11531,6 +11667,7 @@ def test_recrawl_uris_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_batch_verify_target_sites_rest_bad_request( @@ -11616,11 +11753,15 @@ def test_batch_verify_target_sites_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_batch_verify_target_sites", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_batch_verify_target_sites_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_batch_verify_target_sites", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.BatchVerifyTargetSitesRequest.pb( site_search_engine_service.BatchVerifyTargetSitesRequest() ) @@ -11644,6 +11785,7 @@ def test_batch_verify_target_sites_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.batch_verify_target_sites( request, @@ -11655,6 +11797,7 @@ def test_batch_verify_target_sites_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_fetch_domain_verification_status_rest_bad_request( @@ -11750,11 +11893,15 @@ def test_fetch_domain_verification_status_rest_interceptors(null_interceptor): transports.SiteSearchEngineServiceRestInterceptor, "post_fetch_domain_verification_status", ) as post, mock.patch.object( + transports.SiteSearchEngineServiceRestInterceptor, + "post_fetch_domain_verification_status_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.SiteSearchEngineServiceRestInterceptor, "pre_fetch_domain_verification_status", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = site_search_engine_service.FetchDomainVerificationStatusRequest.pb( site_search_engine_service.FetchDomainVerificationStatusRequest() ) @@ -11784,6 +11931,10 @@ def test_fetch_domain_verification_status_rest_interceptors(null_interceptor): post.return_value = ( site_search_engine_service.FetchDomainVerificationStatusResponse() ) + post_with_metadata.return_value = ( + site_search_engine_service.FetchDomainVerificationStatusResponse(), + metadata, + ) client.fetch_domain_verification_status( request, @@ -11795,6 +11946,7 @@ def test_fetch_domain_verification_status_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_user_event_service.py b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_user_event_service.py index 0031c6081dd4..e4f911dfff5b 100644 --- a/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_user_event_service.py +++ b/packages/google-cloud-discoveryengine/tests/unit/gapic/discoveryengine_v1beta/test_user_event_service.py @@ -81,6 +81,13 @@ user_event_service, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -340,6 +347,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = UserEventServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = UserEventServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -3289,10 +3339,14 @@ def test_write_user_event_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.UserEventServiceRestInterceptor, "post_write_user_event" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_write_user_event_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_write_user_event" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = user_event_service.WriteUserEventRequest.pb( user_event_service.WriteUserEventRequest() ) @@ -3316,6 +3370,7 @@ def test_write_user_event_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = user_event.UserEvent() + post_with_metadata.return_value = user_event.UserEvent(), metadata client.write_user_event( request, @@ -3327,6 +3382,7 @@ def test_write_user_event_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_collect_user_event_rest_bad_request( @@ -3410,10 +3466,14 @@ def test_collect_user_event_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.UserEventServiceRestInterceptor, "post_collect_user_event" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_collect_user_event_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_collect_user_event" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = user_event_service.CollectUserEventRequest.pb( user_event_service.CollectUserEventRequest() ) @@ -3437,6 +3497,7 @@ def test_collect_user_event_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = httpbody_pb2.HttpBody() + post_with_metadata.return_value = httpbody_pb2.HttpBody(), metadata client.collect_user_event( request, @@ -3448,6 +3509,7 @@ def test_collect_user_event_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_purge_user_events_rest_bad_request( @@ -3528,10 +3590,14 @@ def test_purge_user_events_rest_interceptors(null_interceptor): ), mock.patch.object( transports.UserEventServiceRestInterceptor, "post_purge_user_events" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_purge_user_events_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_purge_user_events" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = purge_config.PurgeUserEventsRequest.pb( purge_config.PurgeUserEventsRequest() ) @@ -3555,6 +3621,7 @@ def test_purge_user_events_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.purge_user_events( request, @@ -3566,6 +3633,7 @@ def test_purge_user_events_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_import_user_events_rest_bad_request( @@ -3646,10 +3714,14 @@ def test_import_user_events_rest_interceptors(null_interceptor): ), mock.patch.object( transports.UserEventServiceRestInterceptor, "post_import_user_events" ) as post, mock.patch.object( + transports.UserEventServiceRestInterceptor, + "post_import_user_events_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.UserEventServiceRestInterceptor, "pre_import_user_events" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = import_config.ImportUserEventsRequest.pb( import_config.ImportUserEventsRequest() ) @@ -3673,6 +3745,7 @@ def test_import_user_events_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.import_user_events( request, @@ -3684,6 +3757,7 @@ def test_import_user_events_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_operation_rest_bad_request( diff --git a/packages/google-cloud-dlp/google/cloud/dlp/gapic_version.py b/packages/google-cloud-dlp/google/cloud/dlp/gapic_version.py index 1fe6836b543e..558c8aab67c5 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp/gapic_version.py +++ b/packages/google-cloud-dlp/google/cloud/dlp/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.26.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dlp/google/cloud/dlp_v2/gapic_version.py b/packages/google-cloud-dlp/google/cloud/dlp_v2/gapic_version.py index 1fe6836b543e..558c8aab67c5 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp_v2/gapic_version.py +++ b/packages/google-cloud-dlp/google/cloud/dlp_v2/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "3.26.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dlp/google/cloud/dlp_v2/services/dlp_service/client.py b/packages/google-cloud-dlp/google/cloud/dlp_v2/services/dlp_service/client.py index cc1f3fa4f386..f647d8cd0d60 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp_v2/services/dlp_service/client.py +++ b/packages/google-cloud-dlp/google/cloud/dlp_v2/services/dlp_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -739,6 +741,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-dlp/google/cloud/dlp_v2/services/dlp_service/transports/rest.py b/packages/google-cloud-dlp/google/cloud/dlp_v2/services/dlp_service/transports/rest.py index ccb233cc7ffb..4029cdc5eb90 100644 --- a/packages/google-cloud-dlp/google/cloud/dlp_v2/services/dlp_service/transports/rest.py +++ b/packages/google-cloud-dlp/google/cloud/dlp_v2/services/dlp_service/transports/rest.py @@ -487,12 +487,33 @@ def pre_activate_job_trigger( def post_activate_job_trigger(self, response: dlp.DlpJob) -> dlp.DlpJob: """Post-rpc interceptor for activate_job_trigger - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_activate_job_trigger_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_activate_job_trigger` interceptor runs + before the `post_activate_job_trigger_with_metadata` interceptor. """ return response + def post_activate_job_trigger_with_metadata( + self, response: dlp.DlpJob, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[dlp.DlpJob, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for activate_job_trigger + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_activate_job_trigger_with_metadata` + interceptor in new development instead of the `post_activate_job_trigger` interceptor. + When both interceptors are used, this `post_activate_job_trigger_with_metadata` interceptor runs after the + `post_activate_job_trigger` interceptor. The (possibly modified) response returned by + `post_activate_job_trigger` will be passed to + `post_activate_job_trigger_with_metadata`. + """ + return response, metadata + def pre_cancel_dlp_job( self, request: dlp.CancelDlpJobRequest, @@ -520,12 +541,35 @@ def pre_create_connection( def post_create_connection(self, response: dlp.Connection) -> dlp.Connection: """Post-rpc interceptor for create_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_create_connection` interceptor runs + before the `post_create_connection_with_metadata` interceptor. """ return response + def post_create_connection_with_metadata( + self, + response: dlp.Connection, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.Connection, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_create_connection_with_metadata` + interceptor in new development instead of the `post_create_connection` interceptor. + When both interceptors are used, this `post_create_connection_with_metadata` interceptor runs after the + `post_create_connection` interceptor. The (possibly modified) response returned by + `post_create_connection` will be passed to + `post_create_connection_with_metadata`. + """ + return response, metadata + def pre_create_deidentify_template( self, request: dlp.CreateDeidentifyTemplateRequest, @@ -545,12 +589,35 @@ def post_create_deidentify_template( ) -> dlp.DeidentifyTemplate: """Post-rpc interceptor for create_deidentify_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_deidentify_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_create_deidentify_template` interceptor runs + before the `post_create_deidentify_template_with_metadata` interceptor. """ return response + def post_create_deidentify_template_with_metadata( + self, + response: dlp.DeidentifyTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.DeidentifyTemplate, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_deidentify_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_create_deidentify_template_with_metadata` + interceptor in new development instead of the `post_create_deidentify_template` interceptor. + When both interceptors are used, this `post_create_deidentify_template_with_metadata` interceptor runs after the + `post_create_deidentify_template` interceptor. The (possibly modified) response returned by + `post_create_deidentify_template` will be passed to + `post_create_deidentify_template_with_metadata`. + """ + return response, metadata + def pre_create_discovery_config( self, request: dlp.CreateDiscoveryConfigRequest, @@ -570,12 +637,35 @@ def post_create_discovery_config( ) -> dlp.DiscoveryConfig: """Post-rpc interceptor for create_discovery_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_discovery_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_create_discovery_config` interceptor runs + before the `post_create_discovery_config_with_metadata` interceptor. """ return response + def post_create_discovery_config_with_metadata( + self, + response: dlp.DiscoveryConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.DiscoveryConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_discovery_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_create_discovery_config_with_metadata` + interceptor in new development instead of the `post_create_discovery_config` interceptor. + When both interceptors are used, this `post_create_discovery_config_with_metadata` interceptor runs after the + `post_create_discovery_config` interceptor. The (possibly modified) response returned by + `post_create_discovery_config` will be passed to + `post_create_discovery_config_with_metadata`. + """ + return response, metadata + def pre_create_dlp_job( self, request: dlp.CreateDlpJobRequest, @@ -591,12 +681,33 @@ def pre_create_dlp_job( def post_create_dlp_job(self, response: dlp.DlpJob) -> dlp.DlpJob: """Post-rpc interceptor for create_dlp_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_dlp_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_create_dlp_job` interceptor runs + before the `post_create_dlp_job_with_metadata` interceptor. """ return response + def post_create_dlp_job_with_metadata( + self, response: dlp.DlpJob, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[dlp.DlpJob, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_dlp_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_create_dlp_job_with_metadata` + interceptor in new development instead of the `post_create_dlp_job` interceptor. + When both interceptors are used, this `post_create_dlp_job_with_metadata` interceptor runs after the + `post_create_dlp_job` interceptor. The (possibly modified) response returned by + `post_create_dlp_job` will be passed to + `post_create_dlp_job_with_metadata`. + """ + return response, metadata + def pre_create_inspect_template( self, request: dlp.CreateInspectTemplateRequest, @@ -616,12 +727,35 @@ def post_create_inspect_template( ) -> dlp.InspectTemplate: """Post-rpc interceptor for create_inspect_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_inspect_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_create_inspect_template` interceptor runs + before the `post_create_inspect_template_with_metadata` interceptor. """ return response + def post_create_inspect_template_with_metadata( + self, + response: dlp.InspectTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.InspectTemplate, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_inspect_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_create_inspect_template_with_metadata` + interceptor in new development instead of the `post_create_inspect_template` interceptor. + When both interceptors are used, this `post_create_inspect_template_with_metadata` interceptor runs after the + `post_create_inspect_template` interceptor. The (possibly modified) response returned by + `post_create_inspect_template` will be passed to + `post_create_inspect_template_with_metadata`. + """ + return response, metadata + def pre_create_job_trigger( self, request: dlp.CreateJobTriggerRequest, @@ -637,12 +771,35 @@ def pre_create_job_trigger( def post_create_job_trigger(self, response: dlp.JobTrigger) -> dlp.JobTrigger: """Post-rpc interceptor for create_job_trigger - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_job_trigger_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_create_job_trigger` interceptor runs + before the `post_create_job_trigger_with_metadata` interceptor. """ return response + def post_create_job_trigger_with_metadata( + self, + response: dlp.JobTrigger, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.JobTrigger, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_job_trigger + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_create_job_trigger_with_metadata` + interceptor in new development instead of the `post_create_job_trigger` interceptor. + When both interceptors are used, this `post_create_job_trigger_with_metadata` interceptor runs after the + `post_create_job_trigger` interceptor. The (possibly modified) response returned by + `post_create_job_trigger` will be passed to + `post_create_job_trigger_with_metadata`. + """ + return response, metadata + def pre_create_stored_info_type( self, request: dlp.CreateStoredInfoTypeRequest, @@ -662,12 +819,35 @@ def post_create_stored_info_type( ) -> dlp.StoredInfoType: """Post-rpc interceptor for create_stored_info_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_stored_info_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_create_stored_info_type` interceptor runs + before the `post_create_stored_info_type_with_metadata` interceptor. """ return response + def post_create_stored_info_type_with_metadata( + self, + response: dlp.StoredInfoType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.StoredInfoType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_stored_info_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_create_stored_info_type_with_metadata` + interceptor in new development instead of the `post_create_stored_info_type` interceptor. + When both interceptors are used, this `post_create_stored_info_type_with_metadata` interceptor runs after the + `post_create_stored_info_type` interceptor. The (possibly modified) response returned by + `post_create_stored_info_type` will be passed to + `post_create_stored_info_type_with_metadata`. + """ + return response, metadata + def pre_deidentify_content( self, request: dlp.DeidentifyContentRequest, @@ -685,12 +865,35 @@ def post_deidentify_content( ) -> dlp.DeidentifyContentResponse: """Post-rpc interceptor for deidentify_content - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_deidentify_content_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_deidentify_content` interceptor runs + before the `post_deidentify_content_with_metadata` interceptor. """ return response + def post_deidentify_content_with_metadata( + self, + response: dlp.DeidentifyContentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.DeidentifyContentResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for deidentify_content + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_deidentify_content_with_metadata` + interceptor in new development instead of the `post_deidentify_content` interceptor. + When both interceptors are used, this `post_deidentify_content_with_metadata` interceptor runs after the + `post_deidentify_content` interceptor. The (possibly modified) response returned by + `post_deidentify_content` will be passed to + `post_deidentify_content_with_metadata`. + """ + return response, metadata + def pre_delete_connection( self, request: dlp.DeleteConnectionRequest, @@ -842,12 +1045,35 @@ def post_get_column_data_profile( ) -> dlp.ColumnDataProfile: """Post-rpc interceptor for get_column_data_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_column_data_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_column_data_profile` interceptor runs + before the `post_get_column_data_profile_with_metadata` interceptor. """ return response + def post_get_column_data_profile_with_metadata( + self, + response: dlp.ColumnDataProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.ColumnDataProfile, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_column_data_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_column_data_profile_with_metadata` + interceptor in new development instead of the `post_get_column_data_profile` interceptor. + When both interceptors are used, this `post_get_column_data_profile_with_metadata` interceptor runs after the + `post_get_column_data_profile` interceptor. The (possibly modified) response returned by + `post_get_column_data_profile` will be passed to + `post_get_column_data_profile_with_metadata`. + """ + return response, metadata + def pre_get_connection( self, request: dlp.GetConnectionRequest, @@ -863,12 +1089,35 @@ def pre_get_connection( def post_get_connection(self, response: dlp.Connection) -> dlp.Connection: """Post-rpc interceptor for get_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_connection` interceptor runs + before the `post_get_connection_with_metadata` interceptor. """ return response + def post_get_connection_with_metadata( + self, + response: dlp.Connection, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.Connection, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_connection_with_metadata` + interceptor in new development instead of the `post_get_connection` interceptor. + When both interceptors are used, this `post_get_connection_with_metadata` interceptor runs after the + `post_get_connection` interceptor. The (possibly modified) response returned by + `post_get_connection` will be passed to + `post_get_connection_with_metadata`. + """ + return response, metadata + def pre_get_deidentify_template( self, request: dlp.GetDeidentifyTemplateRequest, @@ -888,12 +1137,35 @@ def post_get_deidentify_template( ) -> dlp.DeidentifyTemplate: """Post-rpc interceptor for get_deidentify_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_deidentify_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_deidentify_template` interceptor runs + before the `post_get_deidentify_template_with_metadata` interceptor. """ return response + def post_get_deidentify_template_with_metadata( + self, + response: dlp.DeidentifyTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.DeidentifyTemplate, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_deidentify_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_deidentify_template_with_metadata` + interceptor in new development instead of the `post_get_deidentify_template` interceptor. + When both interceptors are used, this `post_get_deidentify_template_with_metadata` interceptor runs after the + `post_get_deidentify_template` interceptor. The (possibly modified) response returned by + `post_get_deidentify_template` will be passed to + `post_get_deidentify_template_with_metadata`. + """ + return response, metadata + def pre_get_discovery_config( self, request: dlp.GetDiscoveryConfigRequest, @@ -911,12 +1183,35 @@ def post_get_discovery_config( ) -> dlp.DiscoveryConfig: """Post-rpc interceptor for get_discovery_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_discovery_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_discovery_config` interceptor runs + before the `post_get_discovery_config_with_metadata` interceptor. """ return response + def post_get_discovery_config_with_metadata( + self, + response: dlp.DiscoveryConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.DiscoveryConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_discovery_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_discovery_config_with_metadata` + interceptor in new development instead of the `post_get_discovery_config` interceptor. + When both interceptors are used, this `post_get_discovery_config_with_metadata` interceptor runs after the + `post_get_discovery_config` interceptor. The (possibly modified) response returned by + `post_get_discovery_config` will be passed to + `post_get_discovery_config_with_metadata`. + """ + return response, metadata + def pre_get_dlp_job( self, request: dlp.GetDlpJobRequest, @@ -932,12 +1227,33 @@ def pre_get_dlp_job( def post_get_dlp_job(self, response: dlp.DlpJob) -> dlp.DlpJob: """Post-rpc interceptor for get_dlp_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_dlp_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_dlp_job` interceptor runs + before the `post_get_dlp_job_with_metadata` interceptor. """ return response + def post_get_dlp_job_with_metadata( + self, response: dlp.DlpJob, metadata: Sequence[Tuple[str, Union[str, bytes]]] + ) -> Tuple[dlp.DlpJob, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_dlp_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_dlp_job_with_metadata` + interceptor in new development instead of the `post_get_dlp_job` interceptor. + When both interceptors are used, this `post_get_dlp_job_with_metadata` interceptor runs after the + `post_get_dlp_job` interceptor. The (possibly modified) response returned by + `post_get_dlp_job` will be passed to + `post_get_dlp_job_with_metadata`. + """ + return response, metadata + def pre_get_file_store_data_profile( self, request: dlp.GetFileStoreDataProfileRequest, @@ -957,12 +1273,35 @@ def post_get_file_store_data_profile( ) -> dlp.FileStoreDataProfile: """Post-rpc interceptor for get_file_store_data_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_file_store_data_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_file_store_data_profile` interceptor runs + before the `post_get_file_store_data_profile_with_metadata` interceptor. """ return response + def post_get_file_store_data_profile_with_metadata( + self, + response: dlp.FileStoreDataProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.FileStoreDataProfile, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_file_store_data_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_file_store_data_profile_with_metadata` + interceptor in new development instead of the `post_get_file_store_data_profile` interceptor. + When both interceptors are used, this `post_get_file_store_data_profile_with_metadata` interceptor runs after the + `post_get_file_store_data_profile` interceptor. The (possibly modified) response returned by + `post_get_file_store_data_profile` will be passed to + `post_get_file_store_data_profile_with_metadata`. + """ + return response, metadata + def pre_get_inspect_template( self, request: dlp.GetInspectTemplateRequest, @@ -980,12 +1319,35 @@ def post_get_inspect_template( ) -> dlp.InspectTemplate: """Post-rpc interceptor for get_inspect_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_inspect_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_inspect_template` interceptor runs + before the `post_get_inspect_template_with_metadata` interceptor. """ return response + def post_get_inspect_template_with_metadata( + self, + response: dlp.InspectTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.InspectTemplate, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_inspect_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_inspect_template_with_metadata` + interceptor in new development instead of the `post_get_inspect_template` interceptor. + When both interceptors are used, this `post_get_inspect_template_with_metadata` interceptor runs after the + `post_get_inspect_template` interceptor. The (possibly modified) response returned by + `post_get_inspect_template` will be passed to + `post_get_inspect_template_with_metadata`. + """ + return response, metadata + def pre_get_job_trigger( self, request: dlp.GetJobTriggerRequest, @@ -1001,12 +1363,35 @@ def pre_get_job_trigger( def post_get_job_trigger(self, response: dlp.JobTrigger) -> dlp.JobTrigger: """Post-rpc interceptor for get_job_trigger - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_job_trigger_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_job_trigger` interceptor runs + before the `post_get_job_trigger_with_metadata` interceptor. """ return response + def post_get_job_trigger_with_metadata( + self, + response: dlp.JobTrigger, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.JobTrigger, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_job_trigger + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_job_trigger_with_metadata` + interceptor in new development instead of the `post_get_job_trigger` interceptor. + When both interceptors are used, this `post_get_job_trigger_with_metadata` interceptor runs after the + `post_get_job_trigger` interceptor. The (possibly modified) response returned by + `post_get_job_trigger` will be passed to + `post_get_job_trigger_with_metadata`. + """ + return response, metadata + def pre_get_project_data_profile( self, request: dlp.GetProjectDataProfileRequest, @@ -1026,12 +1411,35 @@ def post_get_project_data_profile( ) -> dlp.ProjectDataProfile: """Post-rpc interceptor for get_project_data_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_project_data_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_project_data_profile` interceptor runs + before the `post_get_project_data_profile_with_metadata` interceptor. """ return response + def post_get_project_data_profile_with_metadata( + self, + response: dlp.ProjectDataProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.ProjectDataProfile, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_project_data_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_project_data_profile_with_metadata` + interceptor in new development instead of the `post_get_project_data_profile` interceptor. + When both interceptors are used, this `post_get_project_data_profile_with_metadata` interceptor runs after the + `post_get_project_data_profile` interceptor. The (possibly modified) response returned by + `post_get_project_data_profile` will be passed to + `post_get_project_data_profile_with_metadata`. + """ + return response, metadata + def pre_get_stored_info_type( self, request: dlp.GetStoredInfoTypeRequest, @@ -1049,12 +1457,35 @@ def post_get_stored_info_type( ) -> dlp.StoredInfoType: """Post-rpc interceptor for get_stored_info_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_stored_info_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_stored_info_type` interceptor runs + before the `post_get_stored_info_type_with_metadata` interceptor. """ return response + def post_get_stored_info_type_with_metadata( + self, + response: dlp.StoredInfoType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.StoredInfoType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_stored_info_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_stored_info_type_with_metadata` + interceptor in new development instead of the `post_get_stored_info_type` interceptor. + When both interceptors are used, this `post_get_stored_info_type_with_metadata` interceptor runs after the + `post_get_stored_info_type` interceptor. The (possibly modified) response returned by + `post_get_stored_info_type` will be passed to + `post_get_stored_info_type_with_metadata`. + """ + return response, metadata + def pre_get_table_data_profile( self, request: dlp.GetTableDataProfileRequest, @@ -1072,12 +1503,35 @@ def post_get_table_data_profile( ) -> dlp.TableDataProfile: """Post-rpc interceptor for get_table_data_profile - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_table_data_profile_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_get_table_data_profile` interceptor runs + before the `post_get_table_data_profile_with_metadata` interceptor. """ return response + def post_get_table_data_profile_with_metadata( + self, + response: dlp.TableDataProfile, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.TableDataProfile, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_table_data_profile + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_get_table_data_profile_with_metadata` + interceptor in new development instead of the `post_get_table_data_profile` interceptor. + When both interceptors are used, this `post_get_table_data_profile_with_metadata` interceptor runs after the + `post_get_table_data_profile` interceptor. The (possibly modified) response returned by + `post_get_table_data_profile` will be passed to + `post_get_table_data_profile_with_metadata`. + """ + return response, metadata + def pre_hybrid_inspect_dlp_job( self, request: dlp.HybridInspectDlpJobRequest, @@ -1095,12 +1549,35 @@ def post_hybrid_inspect_dlp_job( ) -> dlp.HybridInspectResponse: """Post-rpc interceptor for hybrid_inspect_dlp_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_hybrid_inspect_dlp_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_hybrid_inspect_dlp_job` interceptor runs + before the `post_hybrid_inspect_dlp_job_with_metadata` interceptor. """ return response + def post_hybrid_inspect_dlp_job_with_metadata( + self, + response: dlp.HybridInspectResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.HybridInspectResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for hybrid_inspect_dlp_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_hybrid_inspect_dlp_job_with_metadata` + interceptor in new development instead of the `post_hybrid_inspect_dlp_job` interceptor. + When both interceptors are used, this `post_hybrid_inspect_dlp_job_with_metadata` interceptor runs after the + `post_hybrid_inspect_dlp_job` interceptor. The (possibly modified) response returned by + `post_hybrid_inspect_dlp_job` will be passed to + `post_hybrid_inspect_dlp_job_with_metadata`. + """ + return response, metadata + def pre_hybrid_inspect_job_trigger( self, request: dlp.HybridInspectJobTriggerRequest, @@ -1120,12 +1597,35 @@ def post_hybrid_inspect_job_trigger( ) -> dlp.HybridInspectResponse: """Post-rpc interceptor for hybrid_inspect_job_trigger - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_hybrid_inspect_job_trigger_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_hybrid_inspect_job_trigger` interceptor runs + before the `post_hybrid_inspect_job_trigger_with_metadata` interceptor. """ return response + def post_hybrid_inspect_job_trigger_with_metadata( + self, + response: dlp.HybridInspectResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.HybridInspectResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for hybrid_inspect_job_trigger + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_hybrid_inspect_job_trigger_with_metadata` + interceptor in new development instead of the `post_hybrid_inspect_job_trigger` interceptor. + When both interceptors are used, this `post_hybrid_inspect_job_trigger_with_metadata` interceptor runs after the + `post_hybrid_inspect_job_trigger` interceptor. The (possibly modified) response returned by + `post_hybrid_inspect_job_trigger` will be passed to + `post_hybrid_inspect_job_trigger_with_metadata`. + """ + return response, metadata + def pre_inspect_content( self, request: dlp.InspectContentRequest, @@ -1143,12 +1643,35 @@ def post_inspect_content( ) -> dlp.InspectContentResponse: """Post-rpc interceptor for inspect_content - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_inspect_content_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_inspect_content` interceptor runs + before the `post_inspect_content_with_metadata` interceptor. """ return response + def post_inspect_content_with_metadata( + self, + response: dlp.InspectContentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.InspectContentResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for inspect_content + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_inspect_content_with_metadata` + interceptor in new development instead of the `post_inspect_content` interceptor. + When both interceptors are used, this `post_inspect_content_with_metadata` interceptor runs after the + `post_inspect_content` interceptor. The (possibly modified) response returned by + `post_inspect_content` will be passed to + `post_inspect_content_with_metadata`. + """ + return response, metadata + def pre_list_column_data_profiles( self, request: dlp.ListColumnDataProfilesRequest, @@ -1168,12 +1691,37 @@ def post_list_column_data_profiles( ) -> dlp.ListColumnDataProfilesResponse: """Post-rpc interceptor for list_column_data_profiles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_column_data_profiles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_column_data_profiles` interceptor runs + before the `post_list_column_data_profiles_with_metadata` interceptor. """ return response + def post_list_column_data_profiles_with_metadata( + self, + response: dlp.ListColumnDataProfilesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dlp.ListColumnDataProfilesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_column_data_profiles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_column_data_profiles_with_metadata` + interceptor in new development instead of the `post_list_column_data_profiles` interceptor. + When both interceptors are used, this `post_list_column_data_profiles_with_metadata` interceptor runs after the + `post_list_column_data_profiles` interceptor. The (possibly modified) response returned by + `post_list_column_data_profiles` will be passed to + `post_list_column_data_profiles_with_metadata`. + """ + return response, metadata + def pre_list_connections( self, request: dlp.ListConnectionsRequest, @@ -1191,12 +1739,35 @@ def post_list_connections( ) -> dlp.ListConnectionsResponse: """Post-rpc interceptor for list_connections - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_connections_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_connections` interceptor runs + before the `post_list_connections_with_metadata` interceptor. """ return response + def post_list_connections_with_metadata( + self, + response: dlp.ListConnectionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.ListConnectionsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_connections + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_connections_with_metadata` + interceptor in new development instead of the `post_list_connections` interceptor. + When both interceptors are used, this `post_list_connections_with_metadata` interceptor runs after the + `post_list_connections` interceptor. The (possibly modified) response returned by + `post_list_connections` will be passed to + `post_list_connections_with_metadata`. + """ + return response, metadata + def pre_list_deidentify_templates( self, request: dlp.ListDeidentifyTemplatesRequest, @@ -1216,12 +1787,37 @@ def post_list_deidentify_templates( ) -> dlp.ListDeidentifyTemplatesResponse: """Post-rpc interceptor for list_deidentify_templates - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_deidentify_templates_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_deidentify_templates` interceptor runs + before the `post_list_deidentify_templates_with_metadata` interceptor. """ return response + def post_list_deidentify_templates_with_metadata( + self, + response: dlp.ListDeidentifyTemplatesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dlp.ListDeidentifyTemplatesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_deidentify_templates + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_deidentify_templates_with_metadata` + interceptor in new development instead of the `post_list_deidentify_templates` interceptor. + When both interceptors are used, this `post_list_deidentify_templates_with_metadata` interceptor runs after the + `post_list_deidentify_templates` interceptor. The (possibly modified) response returned by + `post_list_deidentify_templates` will be passed to + `post_list_deidentify_templates_with_metadata`. + """ + return response, metadata + def pre_list_discovery_configs( self, request: dlp.ListDiscoveryConfigsRequest, @@ -1241,12 +1837,37 @@ def post_list_discovery_configs( ) -> dlp.ListDiscoveryConfigsResponse: """Post-rpc interceptor for list_discovery_configs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_discovery_configs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_discovery_configs` interceptor runs + before the `post_list_discovery_configs_with_metadata` interceptor. """ return response + def post_list_discovery_configs_with_metadata( + self, + response: dlp.ListDiscoveryConfigsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dlp.ListDiscoveryConfigsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_discovery_configs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_discovery_configs_with_metadata` + interceptor in new development instead of the `post_list_discovery_configs` interceptor. + When both interceptors are used, this `post_list_discovery_configs_with_metadata` interceptor runs after the + `post_list_discovery_configs` interceptor. The (possibly modified) response returned by + `post_list_discovery_configs` will be passed to + `post_list_discovery_configs_with_metadata`. + """ + return response, metadata + def pre_list_dlp_jobs( self, request: dlp.ListDlpJobsRequest, @@ -1264,12 +1885,35 @@ def post_list_dlp_jobs( ) -> dlp.ListDlpJobsResponse: """Post-rpc interceptor for list_dlp_jobs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_dlp_jobs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_dlp_jobs` interceptor runs + before the `post_list_dlp_jobs_with_metadata` interceptor. """ return response + def post_list_dlp_jobs_with_metadata( + self, + response: dlp.ListDlpJobsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.ListDlpJobsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_dlp_jobs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_dlp_jobs_with_metadata` + interceptor in new development instead of the `post_list_dlp_jobs` interceptor. + When both interceptors are used, this `post_list_dlp_jobs_with_metadata` interceptor runs after the + `post_list_dlp_jobs` interceptor. The (possibly modified) response returned by + `post_list_dlp_jobs` will be passed to + `post_list_dlp_jobs_with_metadata`. + """ + return response, metadata + def pre_list_file_store_data_profiles( self, request: dlp.ListFileStoreDataProfilesRequest, @@ -1289,12 +1933,37 @@ def post_list_file_store_data_profiles( ) -> dlp.ListFileStoreDataProfilesResponse: """Post-rpc interceptor for list_file_store_data_profiles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_file_store_data_profiles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_file_store_data_profiles` interceptor runs + before the `post_list_file_store_data_profiles_with_metadata` interceptor. """ return response + def post_list_file_store_data_profiles_with_metadata( + self, + response: dlp.ListFileStoreDataProfilesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dlp.ListFileStoreDataProfilesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_file_store_data_profiles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_file_store_data_profiles_with_metadata` + interceptor in new development instead of the `post_list_file_store_data_profiles` interceptor. + When both interceptors are used, this `post_list_file_store_data_profiles_with_metadata` interceptor runs after the + `post_list_file_store_data_profiles` interceptor. The (possibly modified) response returned by + `post_list_file_store_data_profiles` will be passed to + `post_list_file_store_data_profiles_with_metadata`. + """ + return response, metadata + def pre_list_info_types( self, request: dlp.ListInfoTypesRequest, @@ -1312,12 +1981,35 @@ def post_list_info_types( ) -> dlp.ListInfoTypesResponse: """Post-rpc interceptor for list_info_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_info_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_info_types` interceptor runs + before the `post_list_info_types_with_metadata` interceptor. """ return response + def post_list_info_types_with_metadata( + self, + response: dlp.ListInfoTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.ListInfoTypesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_info_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_info_types_with_metadata` + interceptor in new development instead of the `post_list_info_types` interceptor. + When both interceptors are used, this `post_list_info_types_with_metadata` interceptor runs after the + `post_list_info_types` interceptor. The (possibly modified) response returned by + `post_list_info_types` will be passed to + `post_list_info_types_with_metadata`. + """ + return response, metadata + def pre_list_inspect_templates( self, request: dlp.ListInspectTemplatesRequest, @@ -1337,12 +2029,37 @@ def post_list_inspect_templates( ) -> dlp.ListInspectTemplatesResponse: """Post-rpc interceptor for list_inspect_templates - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_inspect_templates_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_inspect_templates` interceptor runs + before the `post_list_inspect_templates_with_metadata` interceptor. """ return response + def post_list_inspect_templates_with_metadata( + self, + response: dlp.ListInspectTemplatesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dlp.ListInspectTemplatesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_inspect_templates + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_inspect_templates_with_metadata` + interceptor in new development instead of the `post_list_inspect_templates` interceptor. + When both interceptors are used, this `post_list_inspect_templates_with_metadata` interceptor runs after the + `post_list_inspect_templates` interceptor. The (possibly modified) response returned by + `post_list_inspect_templates` will be passed to + `post_list_inspect_templates_with_metadata`. + """ + return response, metadata + def pre_list_job_triggers( self, request: dlp.ListJobTriggersRequest, @@ -1360,12 +2077,35 @@ def post_list_job_triggers( ) -> dlp.ListJobTriggersResponse: """Post-rpc interceptor for list_job_triggers - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_job_triggers_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_job_triggers` interceptor runs + before the `post_list_job_triggers_with_metadata` interceptor. """ return response + def post_list_job_triggers_with_metadata( + self, + response: dlp.ListJobTriggersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.ListJobTriggersResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_job_triggers + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_job_triggers_with_metadata` + interceptor in new development instead of the `post_list_job_triggers` interceptor. + When both interceptors are used, this `post_list_job_triggers_with_metadata` interceptor runs after the + `post_list_job_triggers` interceptor. The (possibly modified) response returned by + `post_list_job_triggers` will be passed to + `post_list_job_triggers_with_metadata`. + """ + return response, metadata + def pre_list_project_data_profiles( self, request: dlp.ListProjectDataProfilesRequest, @@ -1385,12 +2125,37 @@ def post_list_project_data_profiles( ) -> dlp.ListProjectDataProfilesResponse: """Post-rpc interceptor for list_project_data_profiles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_project_data_profiles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_project_data_profiles` interceptor runs + before the `post_list_project_data_profiles_with_metadata` interceptor. """ return response + def post_list_project_data_profiles_with_metadata( + self, + response: dlp.ListProjectDataProfilesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dlp.ListProjectDataProfilesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_project_data_profiles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_project_data_profiles_with_metadata` + interceptor in new development instead of the `post_list_project_data_profiles` interceptor. + When both interceptors are used, this `post_list_project_data_profiles_with_metadata` interceptor runs after the + `post_list_project_data_profiles` interceptor. The (possibly modified) response returned by + `post_list_project_data_profiles` will be passed to + `post_list_project_data_profiles_with_metadata`. + """ + return response, metadata + def pre_list_stored_info_types( self, request: dlp.ListStoredInfoTypesRequest, @@ -1408,12 +2173,37 @@ def post_list_stored_info_types( ) -> dlp.ListStoredInfoTypesResponse: """Post-rpc interceptor for list_stored_info_types - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_stored_info_types_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_stored_info_types` interceptor runs + before the `post_list_stored_info_types_with_metadata` interceptor. """ return response + def post_list_stored_info_types_with_metadata( + self, + response: dlp.ListStoredInfoTypesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dlp.ListStoredInfoTypesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_stored_info_types + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_stored_info_types_with_metadata` + interceptor in new development instead of the `post_list_stored_info_types` interceptor. + When both interceptors are used, this `post_list_stored_info_types_with_metadata` interceptor runs after the + `post_list_stored_info_types` interceptor. The (possibly modified) response returned by + `post_list_stored_info_types` will be passed to + `post_list_stored_info_types_with_metadata`. + """ + return response, metadata + def pre_list_table_data_profiles( self, request: dlp.ListTableDataProfilesRequest, @@ -1433,12 +2223,37 @@ def post_list_table_data_profiles( ) -> dlp.ListTableDataProfilesResponse: """Post-rpc interceptor for list_table_data_profiles - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_table_data_profiles_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_list_table_data_profiles` interceptor runs + before the `post_list_table_data_profiles_with_metadata` interceptor. """ return response + def post_list_table_data_profiles_with_metadata( + self, + response: dlp.ListTableDataProfilesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + dlp.ListTableDataProfilesResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_table_data_profiles + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_list_table_data_profiles_with_metadata` + interceptor in new development instead of the `post_list_table_data_profiles` interceptor. + When both interceptors are used, this `post_list_table_data_profiles_with_metadata` interceptor runs after the + `post_list_table_data_profiles` interceptor. The (possibly modified) response returned by + `post_list_table_data_profiles` will be passed to + `post_list_table_data_profiles_with_metadata`. + """ + return response, metadata + def pre_redact_image( self, request: dlp.RedactImageRequest, @@ -1456,12 +2271,35 @@ def post_redact_image( ) -> dlp.RedactImageResponse: """Post-rpc interceptor for redact_image - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_redact_image_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_redact_image` interceptor runs + before the `post_redact_image_with_metadata` interceptor. """ return response + def post_redact_image_with_metadata( + self, + response: dlp.RedactImageResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.RedactImageResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for redact_image + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_redact_image_with_metadata` + interceptor in new development instead of the `post_redact_image` interceptor. + When both interceptors are used, this `post_redact_image_with_metadata` interceptor runs after the + `post_redact_image` interceptor. The (possibly modified) response returned by + `post_redact_image` will be passed to + `post_redact_image_with_metadata`. + """ + return response, metadata + def pre_reidentify_content( self, request: dlp.ReidentifyContentRequest, @@ -1479,12 +2317,35 @@ def post_reidentify_content( ) -> dlp.ReidentifyContentResponse: """Post-rpc interceptor for reidentify_content - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_reidentify_content_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_reidentify_content` interceptor runs + before the `post_reidentify_content_with_metadata` interceptor. """ return response + def post_reidentify_content_with_metadata( + self, + response: dlp.ReidentifyContentResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.ReidentifyContentResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for reidentify_content + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_reidentify_content_with_metadata` + interceptor in new development instead of the `post_reidentify_content` interceptor. + When both interceptors are used, this `post_reidentify_content_with_metadata` interceptor runs after the + `post_reidentify_content` interceptor. The (possibly modified) response returned by + `post_reidentify_content` will be passed to + `post_reidentify_content_with_metadata`. + """ + return response, metadata + def pre_search_connections( self, request: dlp.SearchConnectionsRequest, @@ -1502,12 +2363,35 @@ def post_search_connections( ) -> dlp.SearchConnectionsResponse: """Post-rpc interceptor for search_connections - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_connections_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_search_connections` interceptor runs + before the `post_search_connections_with_metadata` interceptor. """ return response + def post_search_connections_with_metadata( + self, + response: dlp.SearchConnectionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.SearchConnectionsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search_connections + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_search_connections_with_metadata` + interceptor in new development instead of the `post_search_connections` interceptor. + When both interceptors are used, this `post_search_connections_with_metadata` interceptor runs after the + `post_search_connections` interceptor. The (possibly modified) response returned by + `post_search_connections` will be passed to + `post_search_connections_with_metadata`. + """ + return response, metadata + def pre_update_connection( self, request: dlp.UpdateConnectionRequest, @@ -1523,12 +2407,35 @@ def pre_update_connection( def post_update_connection(self, response: dlp.Connection) -> dlp.Connection: """Post-rpc interceptor for update_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_update_connection` interceptor runs + before the `post_update_connection_with_metadata` interceptor. """ return response + def post_update_connection_with_metadata( + self, + response: dlp.Connection, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.Connection, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_update_connection_with_metadata` + interceptor in new development instead of the `post_update_connection` interceptor. + When both interceptors are used, this `post_update_connection_with_metadata` interceptor runs after the + `post_update_connection` interceptor. The (possibly modified) response returned by + `post_update_connection` will be passed to + `post_update_connection_with_metadata`. + """ + return response, metadata + def pre_update_deidentify_template( self, request: dlp.UpdateDeidentifyTemplateRequest, @@ -1548,12 +2455,35 @@ def post_update_deidentify_template( ) -> dlp.DeidentifyTemplate: """Post-rpc interceptor for update_deidentify_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_deidentify_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_update_deidentify_template` interceptor runs + before the `post_update_deidentify_template_with_metadata` interceptor. """ return response + def post_update_deidentify_template_with_metadata( + self, + response: dlp.DeidentifyTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.DeidentifyTemplate, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_deidentify_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_update_deidentify_template_with_metadata` + interceptor in new development instead of the `post_update_deidentify_template` interceptor. + When both interceptors are used, this `post_update_deidentify_template_with_metadata` interceptor runs after the + `post_update_deidentify_template` interceptor. The (possibly modified) response returned by + `post_update_deidentify_template` will be passed to + `post_update_deidentify_template_with_metadata`. + """ + return response, metadata + def pre_update_discovery_config( self, request: dlp.UpdateDiscoveryConfigRequest, @@ -1573,12 +2503,35 @@ def post_update_discovery_config( ) -> dlp.DiscoveryConfig: """Post-rpc interceptor for update_discovery_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_discovery_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_update_discovery_config` interceptor runs + before the `post_update_discovery_config_with_metadata` interceptor. """ return response + def post_update_discovery_config_with_metadata( + self, + response: dlp.DiscoveryConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.DiscoveryConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_discovery_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_update_discovery_config_with_metadata` + interceptor in new development instead of the `post_update_discovery_config` interceptor. + When both interceptors are used, this `post_update_discovery_config_with_metadata` interceptor runs after the + `post_update_discovery_config` interceptor. The (possibly modified) response returned by + `post_update_discovery_config` will be passed to + `post_update_discovery_config_with_metadata`. + """ + return response, metadata + def pre_update_inspect_template( self, request: dlp.UpdateInspectTemplateRequest, @@ -1598,12 +2551,35 @@ def post_update_inspect_template( ) -> dlp.InspectTemplate: """Post-rpc interceptor for update_inspect_template - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_inspect_template_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_update_inspect_template` interceptor runs + before the `post_update_inspect_template_with_metadata` interceptor. """ return response + def post_update_inspect_template_with_metadata( + self, + response: dlp.InspectTemplate, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.InspectTemplate, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_inspect_template + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_update_inspect_template_with_metadata` + interceptor in new development instead of the `post_update_inspect_template` interceptor. + When both interceptors are used, this `post_update_inspect_template_with_metadata` interceptor runs after the + `post_update_inspect_template` interceptor. The (possibly modified) response returned by + `post_update_inspect_template` will be passed to + `post_update_inspect_template_with_metadata`. + """ + return response, metadata + def pre_update_job_trigger( self, request: dlp.UpdateJobTriggerRequest, @@ -1619,12 +2595,35 @@ def pre_update_job_trigger( def post_update_job_trigger(self, response: dlp.JobTrigger) -> dlp.JobTrigger: """Post-rpc interceptor for update_job_trigger - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_job_trigger_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_update_job_trigger` interceptor runs + before the `post_update_job_trigger_with_metadata` interceptor. """ return response + def post_update_job_trigger_with_metadata( + self, + response: dlp.JobTrigger, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.JobTrigger, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_job_trigger + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_update_job_trigger_with_metadata` + interceptor in new development instead of the `post_update_job_trigger` interceptor. + When both interceptors are used, this `post_update_job_trigger_with_metadata` interceptor runs after the + `post_update_job_trigger` interceptor. The (possibly modified) response returned by + `post_update_job_trigger` will be passed to + `post_update_job_trigger_with_metadata`. + """ + return response, metadata + def pre_update_stored_info_type( self, request: dlp.UpdateStoredInfoTypeRequest, @@ -1644,12 +2643,35 @@ def post_update_stored_info_type( ) -> dlp.StoredInfoType: """Post-rpc interceptor for update_stored_info_type - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_stored_info_type_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the DlpService server but before - it is returned to user code. + it is returned to user code. This `post_update_stored_info_type` interceptor runs + before the `post_update_stored_info_type_with_metadata` interceptor. """ return response + def post_update_stored_info_type_with_metadata( + self, + response: dlp.StoredInfoType, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[dlp.StoredInfoType, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_stored_info_type + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the DlpService server but before it is returned to user code. + + We recommend only using this `post_update_stored_info_type_with_metadata` + interceptor in new development instead of the `post_update_stored_info_type` interceptor. + When both interceptors are used, this `post_update_stored_info_type_with_metadata` interceptor runs after the + `post_update_stored_info_type` interceptor. The (possibly modified) response returned by + `post_update_stored_info_type` will be passed to + `post_update_stored_info_type_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class DlpServiceRestStub: @@ -1870,6 +2892,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_activate_job_trigger(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_activate_job_trigger_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2140,6 +3166,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2295,6 +3325,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_deidentify_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_deidentify_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2451,6 +3485,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_discovery_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_discovery_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2609,6 +3647,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_dlp_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_dlp_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2765,6 +3807,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_inspect_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_inspect_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2917,6 +3963,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_job_trigger(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_job_trigger_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3069,6 +4119,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_stored_info_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_stored_info_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3219,6 +4273,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_deidentify_content(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_deidentify_content_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4467,6 +5525,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_column_data_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_column_data_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4614,6 +5676,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4762,6 +5828,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_deidentify_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_deidentify_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4912,6 +5982,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_discovery_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_discovery_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5056,6 +6130,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_dlp_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_dlp_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5204,6 +6282,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_file_store_data_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_file_store_data_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5354,6 +6436,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_inspect_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_inspect_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5502,6 +6588,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_job_trigger(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_job_trigger_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5648,6 +6738,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_project_data_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_project_data_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5794,6 +6888,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_stored_info_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_stored_info_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -5936,6 +7034,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_table_data_profile(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_table_data_profile_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6087,6 +7189,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_hybrid_inspect_dlp_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_hybrid_inspect_dlp_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6239,6 +7345,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_hybrid_inspect_job_trigger(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_hybrid_inspect_job_trigger_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6390,6 +7500,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_inspect_content(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_inspect_content_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6536,6 +7650,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_column_data_profiles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_column_data_profiles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6680,6 +7798,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_connections(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_connections_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6825,6 +7947,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_deidentify_templates(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_deidentify_templates_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -6972,6 +8098,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_discovery_configs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_discovery_configs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7121,6 +8251,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_dlp_jobs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_dlp_jobs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7269,6 +8403,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_file_store_data_profiles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_list_file_store_data_profiles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7417,6 +8558,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_info_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_info_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7562,6 +8707,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_inspect_templates(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_inspect_templates_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7706,6 +8855,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_job_triggers(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_job_triggers_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -7853,6 +9006,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_project_data_profiles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_project_data_profiles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8000,6 +9157,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_stored_info_types(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_stored_info_types_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8146,6 +9307,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_table_data_profiles(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_table_data_profiles_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8300,6 +9465,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_redact_image(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_redact_image_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8448,6 +9617,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_reidentify_content(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_reidentify_content_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8593,6 +9766,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_connections(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_connections_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8744,6 +9921,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -8899,6 +10080,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_deidentify_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_deidentify_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -9055,6 +10240,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_discovery_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_discovery_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -9211,6 +10400,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_inspect_template(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_inspect_template_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -9363,6 +10556,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_job_trigger(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_job_trigger_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -9515,6 +10712,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_stored_info_type(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_stored_info_type_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-dlp/samples/generated_samples/snippet_metadata_google.privacy.dlp.v2.json b/packages/google-cloud-dlp/samples/generated_samples/snippet_metadata_google.privacy.dlp.v2.json index 0d79612ba0ab..8e523fad2045 100644 --- a/packages/google-cloud-dlp/samples/generated_samples/snippet_metadata_google.privacy.dlp.v2.json +++ b/packages/google-cloud-dlp/samples/generated_samples/snippet_metadata_google.privacy.dlp.v2.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dlp", - "version": "3.26.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dlp/tests/unit/gapic/dlp_v2/test_dlp_service.py b/packages/google-cloud-dlp/tests/unit/gapic/dlp_v2/test_dlp_service.py index c472606b7c0f..dfa52befa7bc 100644 --- a/packages/google-cloud-dlp/tests/unit/gapic/dlp_v2/test_dlp_service.py +++ b/packages/google-cloud-dlp/tests/unit/gapic/dlp_v2/test_dlp_service.py @@ -70,6 +70,13 @@ ) from google.cloud.dlp_v2.types import dlp, storage +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -305,6 +312,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DlpServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DlpServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -35158,10 +35208,13 @@ def test_inspect_content_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_inspect_content" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_inspect_content_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_inspect_content" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.InspectContentRequest.pb(dlp.InspectContentRequest()) transcode.return_value = { "method": "post", @@ -35183,6 +35236,7 @@ def test_inspect_content_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.InspectContentResponse() + post_with_metadata.return_value = dlp.InspectContentResponse(), metadata client.inspect_content( request, @@ -35194,6 +35248,7 @@ def test_inspect_content_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_redact_image_rest_bad_request(request_type=dlp.RedactImageRequest): @@ -35278,10 +35333,13 @@ def test_redact_image_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_redact_image" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_redact_image_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_redact_image" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.RedactImageRequest.pb(dlp.RedactImageRequest()) transcode.return_value = { "method": "post", @@ -35303,6 +35361,7 @@ def test_redact_image_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.RedactImageResponse() + post_with_metadata.return_value = dlp.RedactImageResponse(), metadata client.redact_image( request, @@ -35314,6 +35373,7 @@ def test_redact_image_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_deidentify_content_rest_bad_request(request_type=dlp.DeidentifyContentRequest): @@ -35393,10 +35453,13 @@ def test_deidentify_content_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_deidentify_content" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_deidentify_content_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_deidentify_content" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.DeidentifyContentRequest.pb(dlp.DeidentifyContentRequest()) transcode.return_value = { "method": "post", @@ -35420,6 +35483,7 @@ def test_deidentify_content_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DeidentifyContentResponse() + post_with_metadata.return_value = dlp.DeidentifyContentResponse(), metadata client.deidentify_content( request, @@ -35431,6 +35495,7 @@ def test_deidentify_content_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_reidentify_content_rest_bad_request(request_type=dlp.ReidentifyContentRequest): @@ -35510,10 +35575,13 @@ def test_reidentify_content_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_reidentify_content" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_reidentify_content_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_reidentify_content" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ReidentifyContentRequest.pb(dlp.ReidentifyContentRequest()) transcode.return_value = { "method": "post", @@ -35537,6 +35605,7 @@ def test_reidentify_content_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ReidentifyContentResponse() + post_with_metadata.return_value = dlp.ReidentifyContentResponse(), metadata client.reidentify_content( request, @@ -35548,6 +35617,7 @@ def test_reidentify_content_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_info_types_rest_bad_request(request_type=dlp.ListInfoTypesRequest): @@ -35627,10 +35697,13 @@ def test_list_info_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_info_types" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_list_info_types_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_info_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListInfoTypesRequest.pb(dlp.ListInfoTypesRequest()) transcode.return_value = { "method": "post", @@ -35652,6 +35725,7 @@ def test_list_info_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListInfoTypesResponse() + post_with_metadata.return_value = dlp.ListInfoTypesResponse(), metadata client.list_info_types( request, @@ -35663,6 +35737,7 @@ def test_list_info_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_inspect_template_rest_bad_request( @@ -35751,10 +35826,14 @@ def test_create_inspect_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_create_inspect_template" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_create_inspect_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_create_inspect_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.CreateInspectTemplateRequest.pb( dlp.CreateInspectTemplateRequest() ) @@ -35778,6 +35857,7 @@ def test_create_inspect_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.InspectTemplate() + post_with_metadata.return_value = dlp.InspectTemplate(), metadata client.create_inspect_template( request, @@ -35789,6 +35869,7 @@ def test_create_inspect_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_inspect_template_rest_bad_request( @@ -35881,10 +35962,14 @@ def test_update_inspect_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_update_inspect_template" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_update_inspect_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_update_inspect_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.UpdateInspectTemplateRequest.pb( dlp.UpdateInspectTemplateRequest() ) @@ -35908,6 +35993,7 @@ def test_update_inspect_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.InspectTemplate() + post_with_metadata.return_value = dlp.InspectTemplate(), metadata client.update_inspect_template( request, @@ -35919,6 +36005,7 @@ def test_update_inspect_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_inspect_template_rest_bad_request( @@ -36011,10 +36098,13 @@ def test_get_inspect_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_inspect_template" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_get_inspect_template_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_inspect_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetInspectTemplateRequest.pb(dlp.GetInspectTemplateRequest()) transcode.return_value = { "method": "post", @@ -36036,6 +36126,7 @@ def test_get_inspect_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.InspectTemplate() + post_with_metadata.return_value = dlp.InspectTemplate(), metadata client.get_inspect_template( request, @@ -36047,6 +36138,7 @@ def test_get_inspect_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_inspect_templates_rest_bad_request( @@ -36131,10 +36223,14 @@ def test_list_inspect_templates_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_inspect_templates" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_list_inspect_templates_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_inspect_templates" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListInspectTemplatesRequest.pb( dlp.ListInspectTemplatesRequest() ) @@ -36160,6 +36256,7 @@ def test_list_inspect_templates_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListInspectTemplatesResponse() + post_with_metadata.return_value = dlp.ListInspectTemplatesResponse(), metadata client.list_inspect_templates( request, @@ -36171,6 +36268,7 @@ def test_list_inspect_templates_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_inspect_template_rest_bad_request( @@ -36372,10 +36470,14 @@ def test_create_deidentify_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_create_deidentify_template" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_create_deidentify_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_create_deidentify_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.CreateDeidentifyTemplateRequest.pb( dlp.CreateDeidentifyTemplateRequest() ) @@ -36399,6 +36501,7 @@ def test_create_deidentify_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DeidentifyTemplate() + post_with_metadata.return_value = dlp.DeidentifyTemplate(), metadata client.create_deidentify_template( request, @@ -36410,6 +36513,7 @@ def test_create_deidentify_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_deidentify_template_rest_bad_request( @@ -36498,10 +36602,14 @@ def test_update_deidentify_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_update_deidentify_template" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_update_deidentify_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_update_deidentify_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.UpdateDeidentifyTemplateRequest.pb( dlp.UpdateDeidentifyTemplateRequest() ) @@ -36525,6 +36633,7 @@ def test_update_deidentify_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DeidentifyTemplate() + post_with_metadata.return_value = dlp.DeidentifyTemplate(), metadata client.update_deidentify_template( request, @@ -36536,6 +36645,7 @@ def test_update_deidentify_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_deidentify_template_rest_bad_request( @@ -36624,10 +36734,14 @@ def test_get_deidentify_template_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_deidentify_template" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_get_deidentify_template_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_deidentify_template" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetDeidentifyTemplateRequest.pb( dlp.GetDeidentifyTemplateRequest() ) @@ -36651,6 +36765,7 @@ def test_get_deidentify_template_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DeidentifyTemplate() + post_with_metadata.return_value = dlp.DeidentifyTemplate(), metadata client.get_deidentify_template( request, @@ -36662,6 +36777,7 @@ def test_get_deidentify_template_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_deidentify_templates_rest_bad_request( @@ -36746,10 +36862,14 @@ def test_list_deidentify_templates_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_deidentify_templates" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_list_deidentify_templates_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_deidentify_templates" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListDeidentifyTemplatesRequest.pb( dlp.ListDeidentifyTemplatesRequest() ) @@ -36775,6 +36895,10 @@ def test_list_deidentify_templates_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListDeidentifyTemplatesResponse() + post_with_metadata.return_value = ( + dlp.ListDeidentifyTemplatesResponse(), + metadata, + ) client.list_deidentify_templates( request, @@ -36786,6 +36910,7 @@ def test_list_deidentify_templates_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_deidentify_template_rest_bad_request( @@ -36983,10 +37108,13 @@ def test_create_job_trigger_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_create_job_trigger" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_create_job_trigger_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_create_job_trigger" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.CreateJobTriggerRequest.pb(dlp.CreateJobTriggerRequest()) transcode.return_value = { "method": "post", @@ -37008,6 +37136,7 @@ def test_create_job_trigger_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.JobTrigger() + post_with_metadata.return_value = dlp.JobTrigger(), metadata client.create_job_trigger( request, @@ -37019,6 +37148,7 @@ def test_create_job_trigger_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_job_trigger_rest_bad_request(request_type=dlp.UpdateJobTriggerRequest): @@ -37107,10 +37237,13 @@ def test_update_job_trigger_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_update_job_trigger" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_update_job_trigger_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_update_job_trigger" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.UpdateJobTriggerRequest.pb(dlp.UpdateJobTriggerRequest()) transcode.return_value = { "method": "post", @@ -37132,6 +37265,7 @@ def test_update_job_trigger_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.JobTrigger() + post_with_metadata.return_value = dlp.JobTrigger(), metadata client.update_job_trigger( request, @@ -37143,6 +37277,7 @@ def test_update_job_trigger_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_hybrid_inspect_job_trigger_rest_bad_request( @@ -37224,10 +37359,14 @@ def test_hybrid_inspect_job_trigger_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_hybrid_inspect_job_trigger" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_hybrid_inspect_job_trigger_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_hybrid_inspect_job_trigger" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.HybridInspectJobTriggerRequest.pb( dlp.HybridInspectJobTriggerRequest() ) @@ -37251,6 +37390,7 @@ def test_hybrid_inspect_job_trigger_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.HybridInspectResponse() + post_with_metadata.return_value = dlp.HybridInspectResponse(), metadata client.hybrid_inspect_job_trigger( request, @@ -37262,6 +37402,7 @@ def test_hybrid_inspect_job_trigger_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_job_trigger_rest_bad_request(request_type=dlp.GetJobTriggerRequest): @@ -37350,10 +37491,13 @@ def test_get_job_trigger_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_job_trigger" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_get_job_trigger_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_job_trigger" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetJobTriggerRequest.pb(dlp.GetJobTriggerRequest()) transcode.return_value = { "method": "post", @@ -37375,6 +37519,7 @@ def test_get_job_trigger_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.JobTrigger() + post_with_metadata.return_value = dlp.JobTrigger(), metadata client.get_job_trigger( request, @@ -37386,6 +37531,7 @@ def test_get_job_trigger_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_job_triggers_rest_bad_request(request_type=dlp.ListJobTriggersRequest): @@ -37468,10 +37614,13 @@ def test_list_job_triggers_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_job_triggers" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_list_job_triggers_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_job_triggers" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListJobTriggersRequest.pb(dlp.ListJobTriggersRequest()) transcode.return_value = { "method": "post", @@ -37495,6 +37644,7 @@ def test_list_job_triggers_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListJobTriggersResponse() + post_with_metadata.return_value = dlp.ListJobTriggersResponse(), metadata client.list_job_triggers( request, @@ -37506,6 +37656,7 @@ def test_list_job_triggers_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_job_trigger_rest_bad_request(request_type=dlp.DeleteJobTriggerRequest): @@ -37701,10 +37852,13 @@ def test_activate_job_trigger_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_activate_job_trigger" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_activate_job_trigger_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_activate_job_trigger" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ActivateJobTriggerRequest.pb(dlp.ActivateJobTriggerRequest()) transcode.return_value = { "method": "post", @@ -37726,6 +37880,7 @@ def test_activate_job_trigger_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DlpJob() + post_with_metadata.return_value = dlp.DlpJob(), metadata client.activate_job_trigger( request, @@ -37737,6 +37892,7 @@ def test_activate_job_trigger_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_discovery_config_rest_bad_request( @@ -37827,10 +37983,14 @@ def test_create_discovery_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_create_discovery_config" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_create_discovery_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_create_discovery_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.CreateDiscoveryConfigRequest.pb( dlp.CreateDiscoveryConfigRequest() ) @@ -37854,6 +38014,7 @@ def test_create_discovery_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DiscoveryConfig() + post_with_metadata.return_value = dlp.DiscoveryConfig(), metadata client.create_discovery_config( request, @@ -37865,6 +38026,7 @@ def test_create_discovery_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_discovery_config_rest_bad_request( @@ -37959,10 +38121,14 @@ def test_update_discovery_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_update_discovery_config" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_update_discovery_config_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_update_discovery_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.UpdateDiscoveryConfigRequest.pb( dlp.UpdateDiscoveryConfigRequest() ) @@ -37986,6 +38152,7 @@ def test_update_discovery_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DiscoveryConfig() + post_with_metadata.return_value = dlp.DiscoveryConfig(), metadata client.update_discovery_config( request, @@ -37997,6 +38164,7 @@ def test_update_discovery_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_discovery_config_rest_bad_request( @@ -38091,10 +38259,13 @@ def test_get_discovery_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_discovery_config" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_get_discovery_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_discovery_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetDiscoveryConfigRequest.pb(dlp.GetDiscoveryConfigRequest()) transcode.return_value = { "method": "post", @@ -38116,6 +38287,7 @@ def test_get_discovery_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DiscoveryConfig() + post_with_metadata.return_value = dlp.DiscoveryConfig(), metadata client.get_discovery_config( request, @@ -38127,6 +38299,7 @@ def test_get_discovery_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_discovery_configs_rest_bad_request( @@ -38211,10 +38384,14 @@ def test_list_discovery_configs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_discovery_configs" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_list_discovery_configs_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_discovery_configs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListDiscoveryConfigsRequest.pb( dlp.ListDiscoveryConfigsRequest() ) @@ -38240,6 +38417,7 @@ def test_list_discovery_configs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListDiscoveryConfigsResponse() + post_with_metadata.return_value = dlp.ListDiscoveryConfigsResponse(), metadata client.list_discovery_configs( request, @@ -38251,6 +38429,7 @@ def test_list_discovery_configs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_discovery_config_rest_bad_request( @@ -38452,10 +38631,13 @@ def test_create_dlp_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_create_dlp_job" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_create_dlp_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_create_dlp_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.CreateDlpJobRequest.pb(dlp.CreateDlpJobRequest()) transcode.return_value = { "method": "post", @@ -38477,6 +38659,7 @@ def test_create_dlp_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DlpJob() + post_with_metadata.return_value = dlp.DlpJob(), metadata client.create_dlp_job( request, @@ -38488,6 +38671,7 @@ def test_create_dlp_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_dlp_jobs_rest_bad_request(request_type=dlp.ListDlpJobsRequest): @@ -38570,10 +38754,13 @@ def test_list_dlp_jobs_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_dlp_jobs" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_list_dlp_jobs_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_dlp_jobs" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListDlpJobsRequest.pb(dlp.ListDlpJobsRequest()) transcode.return_value = { "method": "post", @@ -38595,6 +38782,7 @@ def test_list_dlp_jobs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListDlpJobsResponse() + post_with_metadata.return_value = dlp.ListDlpJobsResponse(), metadata client.list_dlp_jobs( request, @@ -38606,6 +38794,7 @@ def test_list_dlp_jobs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_dlp_job_rest_bad_request(request_type=dlp.GetDlpJobRequest): @@ -38694,10 +38883,13 @@ def test_get_dlp_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_dlp_job" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_get_dlp_job_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_dlp_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetDlpJobRequest.pb(dlp.GetDlpJobRequest()) transcode.return_value = { "method": "post", @@ -38719,6 +38911,7 @@ def test_get_dlp_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.DlpJob() + post_with_metadata.return_value = dlp.DlpJob(), metadata client.get_dlp_job( request, @@ -38730,6 +38923,7 @@ def test_get_dlp_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_dlp_job_rest_bad_request(request_type=dlp.DeleteDlpJobRequest): @@ -39024,10 +39218,14 @@ def test_create_stored_info_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_create_stored_info_type" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_create_stored_info_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_create_stored_info_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.CreateStoredInfoTypeRequest.pb( dlp.CreateStoredInfoTypeRequest() ) @@ -39051,6 +39249,7 @@ def test_create_stored_info_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.StoredInfoType() + post_with_metadata.return_value = dlp.StoredInfoType(), metadata client.create_stored_info_type( request, @@ -39062,6 +39261,7 @@ def test_create_stored_info_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_stored_info_type_rest_bad_request( @@ -39146,10 +39346,14 @@ def test_update_stored_info_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_update_stored_info_type" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_update_stored_info_type_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_update_stored_info_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.UpdateStoredInfoTypeRequest.pb( dlp.UpdateStoredInfoTypeRequest() ) @@ -39173,6 +39377,7 @@ def test_update_stored_info_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.StoredInfoType() + post_with_metadata.return_value = dlp.StoredInfoType(), metadata client.update_stored_info_type( request, @@ -39184,6 +39389,7 @@ def test_update_stored_info_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_stored_info_type_rest_bad_request( @@ -39268,10 +39474,13 @@ def test_get_stored_info_type_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_stored_info_type" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_get_stored_info_type_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_stored_info_type" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetStoredInfoTypeRequest.pb(dlp.GetStoredInfoTypeRequest()) transcode.return_value = { "method": "post", @@ -39293,6 +39502,7 @@ def test_get_stored_info_type_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.StoredInfoType() + post_with_metadata.return_value = dlp.StoredInfoType(), metadata client.get_stored_info_type( request, @@ -39304,6 +39514,7 @@ def test_get_stored_info_type_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_stored_info_types_rest_bad_request( @@ -39388,10 +39599,14 @@ def test_list_stored_info_types_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_stored_info_types" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_list_stored_info_types_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_stored_info_types" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListStoredInfoTypesRequest.pb(dlp.ListStoredInfoTypesRequest()) transcode.return_value = { "method": "post", @@ -39415,6 +39630,7 @@ def test_list_stored_info_types_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListStoredInfoTypesResponse() + post_with_metadata.return_value = dlp.ListStoredInfoTypesResponse(), metadata client.list_stored_info_types( request, @@ -39426,6 +39642,7 @@ def test_list_stored_info_types_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_stored_info_type_rest_bad_request( @@ -39619,10 +39836,14 @@ def test_list_project_data_profiles_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_project_data_profiles" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_list_project_data_profiles_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_project_data_profiles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListProjectDataProfilesRequest.pb( dlp.ListProjectDataProfilesRequest() ) @@ -39648,6 +39869,10 @@ def test_list_project_data_profiles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListProjectDataProfilesResponse() + post_with_metadata.return_value = ( + dlp.ListProjectDataProfilesResponse(), + metadata, + ) client.list_project_data_profiles( request, @@ -39659,6 +39884,7 @@ def test_list_project_data_profiles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_table_data_profiles_rest_bad_request( @@ -39743,10 +39969,14 @@ def test_list_table_data_profiles_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_table_data_profiles" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_list_table_data_profiles_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_table_data_profiles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListTableDataProfilesRequest.pb( dlp.ListTableDataProfilesRequest() ) @@ -39772,6 +40002,7 @@ def test_list_table_data_profiles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListTableDataProfilesResponse() + post_with_metadata.return_value = dlp.ListTableDataProfilesResponse(), metadata client.list_table_data_profiles( request, @@ -39783,6 +40014,7 @@ def test_list_table_data_profiles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_column_data_profiles_rest_bad_request( @@ -39867,10 +40099,14 @@ def test_list_column_data_profiles_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_column_data_profiles" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_list_column_data_profiles_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_column_data_profiles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListColumnDataProfilesRequest.pb( dlp.ListColumnDataProfilesRequest() ) @@ -39896,6 +40132,7 @@ def test_list_column_data_profiles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListColumnDataProfilesResponse() + post_with_metadata.return_value = dlp.ListColumnDataProfilesResponse(), metadata client.list_column_data_profiles( request, @@ -39907,6 +40144,7 @@ def test_list_column_data_profiles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_project_data_profile_rest_bad_request( @@ -40001,10 +40239,14 @@ def test_get_project_data_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_project_data_profile" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_get_project_data_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_project_data_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetProjectDataProfileRequest.pb( dlp.GetProjectDataProfileRequest() ) @@ -40028,6 +40270,7 @@ def test_get_project_data_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ProjectDataProfile() + post_with_metadata.return_value = dlp.ProjectDataProfile(), metadata client.get_project_data_profile( request, @@ -40039,6 +40282,7 @@ def test_get_project_data_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_file_store_data_profiles_rest_bad_request( @@ -40123,10 +40367,14 @@ def test_list_file_store_data_profiles_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_file_store_data_profiles" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_list_file_store_data_profiles_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_file_store_data_profiles" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListFileStoreDataProfilesRequest.pb( dlp.ListFileStoreDataProfilesRequest() ) @@ -40152,6 +40400,10 @@ def test_list_file_store_data_profiles_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListFileStoreDataProfilesResponse() + post_with_metadata.return_value = ( + dlp.ListFileStoreDataProfilesResponse(), + metadata, + ) client.list_file_store_data_profiles( request, @@ -40163,6 +40415,7 @@ def test_list_file_store_data_profiles_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_file_store_data_profile_rest_bad_request( @@ -40274,10 +40527,14 @@ def test_get_file_store_data_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_file_store_data_profile" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_get_file_store_data_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_file_store_data_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetFileStoreDataProfileRequest.pb( dlp.GetFileStoreDataProfileRequest() ) @@ -40301,6 +40558,7 @@ def test_get_file_store_data_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.FileStoreDataProfile() + post_with_metadata.return_value = dlp.FileStoreDataProfile(), metadata client.get_file_store_data_profile( request, @@ -40312,6 +40570,7 @@ def test_get_file_store_data_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_file_store_data_profile_rest_bad_request( @@ -40542,10 +40801,14 @@ def test_get_table_data_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_table_data_profile" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_get_table_data_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_table_data_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetTableDataProfileRequest.pb(dlp.GetTableDataProfileRequest()) transcode.return_value = { "method": "post", @@ -40567,6 +40830,7 @@ def test_get_table_data_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.TableDataProfile() + post_with_metadata.return_value = dlp.TableDataProfile(), metadata client.get_table_data_profile( request, @@ -40578,6 +40842,7 @@ def test_get_table_data_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_column_data_profile_rest_bad_request( @@ -40701,10 +40966,14 @@ def test_get_column_data_profile_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_column_data_profile" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_get_column_data_profile_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_column_data_profile" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetColumnDataProfileRequest.pb( dlp.GetColumnDataProfileRequest() ) @@ -40728,6 +40997,7 @@ def test_get_column_data_profile_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ColumnDataProfile() + post_with_metadata.return_value = dlp.ColumnDataProfile(), metadata client.get_column_data_profile( request, @@ -40739,6 +41009,7 @@ def test_get_column_data_profile_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_table_data_profile_rest_bad_request( @@ -40933,10 +41204,14 @@ def test_hybrid_inspect_dlp_job_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_hybrid_inspect_dlp_job" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, + "post_hybrid_inspect_dlp_job_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_hybrid_inspect_dlp_job" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.HybridInspectDlpJobRequest.pb(dlp.HybridInspectDlpJobRequest()) transcode.return_value = { "method": "post", @@ -40958,6 +41233,7 @@ def test_hybrid_inspect_dlp_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.HybridInspectResponse() + post_with_metadata.return_value = dlp.HybridInspectResponse(), metadata client.hybrid_inspect_dlp_job( request, @@ -40969,6 +41245,7 @@ def test_hybrid_inspect_dlp_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_finish_dlp_job_rest_bad_request(request_type=dlp.FinishDlpJobRequest): @@ -41158,10 +41435,13 @@ def test_create_connection_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_create_connection" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_create_connection_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_create_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.CreateConnectionRequest.pb(dlp.CreateConnectionRequest()) transcode.return_value = { "method": "post", @@ -41183,6 +41463,7 @@ def test_create_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.Connection() + post_with_metadata.return_value = dlp.Connection(), metadata client.create_connection( request, @@ -41194,6 +41475,7 @@ def test_create_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_connection_rest_bad_request(request_type=dlp.GetConnectionRequest): @@ -41278,10 +41560,13 @@ def test_get_connection_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_get_connection" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_get_connection_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_get_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.GetConnectionRequest.pb(dlp.GetConnectionRequest()) transcode.return_value = { "method": "post", @@ -41303,6 +41588,7 @@ def test_get_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.Connection() + post_with_metadata.return_value = dlp.Connection(), metadata client.get_connection( request, @@ -41314,6 +41600,7 @@ def test_get_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_connections_rest_bad_request(request_type=dlp.ListConnectionsRequest): @@ -41396,10 +41683,13 @@ def test_list_connections_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_list_connections" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_list_connections_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_list_connections" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.ListConnectionsRequest.pb(dlp.ListConnectionsRequest()) transcode.return_value = { "method": "post", @@ -41423,6 +41713,7 @@ def test_list_connections_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.ListConnectionsResponse() + post_with_metadata.return_value = dlp.ListConnectionsResponse(), metadata client.list_connections( request, @@ -41434,6 +41725,7 @@ def test_list_connections_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_search_connections_rest_bad_request(request_type=dlp.SearchConnectionsRequest): @@ -41516,10 +41808,13 @@ def test_search_connections_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_search_connections" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_search_connections_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_search_connections" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.SearchConnectionsRequest.pb(dlp.SearchConnectionsRequest()) transcode.return_value = { "method": "post", @@ -41543,6 +41838,7 @@ def test_search_connections_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.SearchConnectionsResponse() + post_with_metadata.return_value = dlp.SearchConnectionsResponse(), metadata client.search_connections( request, @@ -41554,6 +41850,7 @@ def test_search_connections_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_connection_rest_bad_request(request_type=dlp.DeleteConnectionRequest): @@ -41743,10 +42040,13 @@ def test_update_connection_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DlpServiceRestInterceptor, "post_update_connection" ) as post, mock.patch.object( + transports.DlpServiceRestInterceptor, "post_update_connection_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DlpServiceRestInterceptor, "pre_update_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = dlp.UpdateConnectionRequest.pb(dlp.UpdateConnectionRequest()) transcode.return_value = { "method": "post", @@ -41768,6 +42068,7 @@ def test_update_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = dlp.Connection() + post_with_metadata.return_value = dlp.Connection(), metadata client.update_connection( request, @@ -41779,6 +42080,7 @@ def test_update_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-dms/google/cloud/clouddms/gapic_version.py b/packages/google-cloud-dms/google/cloud/clouddms/gapic_version.py index 50d842f376d0..558c8aab67c5 100644 --- a/packages/google-cloud-dms/google/cloud/clouddms/gapic_version.py +++ b/packages/google-cloud-dms/google/cloud/clouddms/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.11.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dms/google/cloud/clouddms_v1/gapic_version.py b/packages/google-cloud-dms/google/cloud/clouddms_v1/gapic_version.py index 50d842f376d0..558c8aab67c5 100644 --- a/packages/google-cloud-dms/google/cloud/clouddms_v1/gapic_version.py +++ b/packages/google-cloud-dms/google/cloud/clouddms_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.11.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-dms/google/cloud/clouddms_v1/services/data_migration_service/client.py b/packages/google-cloud-dms/google/cloud/clouddms_v1/services/data_migration_service/client.py index 22f99798d05c..186edb7eec08 100644 --- a/packages/google-cloud-dms/google/cloud/clouddms_v1/services/data_migration_service/client.py +++ b/packages/google-cloud-dms/google/cloud/clouddms_v1/services/data_migration_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -607,6 +609,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -5633,16 +5662,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -5688,16 +5721,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -5920,16 +5957,20 @@ def set_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_iam_policy( self, @@ -6042,16 +6083,20 @@ def get_iam_policy( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def test_iam_permissions( self, @@ -6102,16 +6147,20 @@ def test_iam_permissions( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_location( self, @@ -6157,16 +6206,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -6212,16 +6265,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-dms/samples/generated_samples/snippet_metadata_google.cloud.clouddms.v1.json b/packages/google-cloud-dms/samples/generated_samples/snippet_metadata_google.cloud.clouddms.v1.json index 66d78478488e..c26f7e5a0532 100644 --- a/packages/google-cloud-dms/samples/generated_samples/snippet_metadata_google.cloud.clouddms.v1.json +++ b/packages/google-cloud-dms/samples/generated_samples/snippet_metadata_google.cloud.clouddms.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-dms", - "version": "1.11.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-dms/tests/unit/gapic/clouddms_v1/test_data_migration_service.py b/packages/google-cloud-dms/tests/unit/gapic/clouddms_v1/test_data_migration_service.py index 2bfff7d057f1..2fbeeb5f117b 100644 --- a/packages/google-cloud-dms/tests/unit/gapic/clouddms_v1/test_data_migration_service.py +++ b/packages/google-cloud-dms/tests/unit/gapic/clouddms_v1/test_data_migration_service.py @@ -22,6 +22,7 @@ except ImportError: # pragma: NO COVER import mock +import json import math from google.api_core import api_core_version @@ -81,6 +82,13 @@ conversionworkspace_resources, ) +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -354,6 +362,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DataMigrationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DataMigrationServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ diff --git a/packages/google-cloud-domains/google/cloud/domains/gapic_version.py b/packages/google-cloud-domains/google/cloud/domains/gapic_version.py index 1c08bcbd1569..558c8aab67c5 100644 --- a/packages/google-cloud-domains/google/cloud/domains/gapic_version.py +++ b/packages/google-cloud-domains/google/cloud/domains/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.9.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-domains/google/cloud/domains_v1/gapic_version.py b/packages/google-cloud-domains/google/cloud/domains_v1/gapic_version.py index 1c08bcbd1569..558c8aab67c5 100644 --- a/packages/google-cloud-domains/google/cloud/domains_v1/gapic_version.py +++ b/packages/google-cloud-domains/google/cloud/domains_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.9.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-domains/google/cloud/domains_v1/services/domains/client.py b/packages/google-cloud-domains/google/cloud/domains_v1/services/domains/client.py index ca29e1c6619e..48bff31dfc26 100644 --- a/packages/google-cloud-domains/google/cloud/domains_v1/services/domains/client.py +++ b/packages/google-cloud-domains/google/cloud/domains_v1/services/domains/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -491,6 +493,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-domains/google/cloud/domains_v1/services/domains/transports/rest.py b/packages/google-cloud-domains/google/cloud/domains_v1/services/domains/transports/rest.py index 86aa9bccdcc9..e808770e2e7b 100644 --- a/packages/google-cloud-domains/google/cloud/domains_v1/services/domains/transports/rest.py +++ b/packages/google-cloud-domains/google/cloud/domains_v1/services/domains/transports/rest.py @@ -214,12 +214,35 @@ def post_configure_contact_settings( ) -> operations_pb2.Operation: """Post-rpc interceptor for configure_contact_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_configure_contact_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_configure_contact_settings` interceptor runs + before the `post_configure_contact_settings_with_metadata` interceptor. """ return response + def post_configure_contact_settings_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for configure_contact_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_configure_contact_settings_with_metadata` + interceptor in new development instead of the `post_configure_contact_settings` interceptor. + When both interceptors are used, this `post_configure_contact_settings_with_metadata` interceptor runs after the + `post_configure_contact_settings` interceptor. The (possibly modified) response returned by + `post_configure_contact_settings` will be passed to + `post_configure_contact_settings_with_metadata`. + """ + return response, metadata + def pre_configure_dns_settings( self, request: domains.ConfigureDnsSettingsRequest, @@ -239,12 +262,35 @@ def post_configure_dns_settings( ) -> operations_pb2.Operation: """Post-rpc interceptor for configure_dns_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_configure_dns_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_configure_dns_settings` interceptor runs + before the `post_configure_dns_settings_with_metadata` interceptor. """ return response + def post_configure_dns_settings_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for configure_dns_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_configure_dns_settings_with_metadata` + interceptor in new development instead of the `post_configure_dns_settings` interceptor. + When both interceptors are used, this `post_configure_dns_settings_with_metadata` interceptor runs after the + `post_configure_dns_settings` interceptor. The (possibly modified) response returned by + `post_configure_dns_settings` will be passed to + `post_configure_dns_settings_with_metadata`. + """ + return response, metadata + def pre_configure_management_settings( self, request: domains.ConfigureManagementSettingsRequest, @@ -265,12 +311,35 @@ def post_configure_management_settings( ) -> operations_pb2.Operation: """Post-rpc interceptor for configure_management_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_configure_management_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_configure_management_settings` interceptor runs + before the `post_configure_management_settings_with_metadata` interceptor. """ return response + def post_configure_management_settings_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for configure_management_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_configure_management_settings_with_metadata` + interceptor in new development instead of the `post_configure_management_settings` interceptor. + When both interceptors are used, this `post_configure_management_settings_with_metadata` interceptor runs after the + `post_configure_management_settings` interceptor. The (possibly modified) response returned by + `post_configure_management_settings` will be passed to + `post_configure_management_settings_with_metadata`. + """ + return response, metadata + def pre_delete_registration( self, request: domains.DeleteRegistrationRequest, @@ -290,12 +359,35 @@ def post_delete_registration( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_registration - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_registration_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_delete_registration` interceptor runs + before the `post_delete_registration_with_metadata` interceptor. """ return response + def post_delete_registration_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_registration + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_delete_registration_with_metadata` + interceptor in new development instead of the `post_delete_registration` interceptor. + When both interceptors are used, this `post_delete_registration_with_metadata` interceptor runs after the + `post_delete_registration` interceptor. The (possibly modified) response returned by + `post_delete_registration` will be passed to + `post_delete_registration_with_metadata`. + """ + return response, metadata + def pre_export_registration( self, request: domains.ExportRegistrationRequest, @@ -315,12 +407,35 @@ def post_export_registration( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_registration - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_registration_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_export_registration` interceptor runs + before the `post_export_registration_with_metadata` interceptor. """ return response + def post_export_registration_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_registration + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_export_registration_with_metadata` + interceptor in new development instead of the `post_export_registration` interceptor. + When both interceptors are used, this `post_export_registration_with_metadata` interceptor runs after the + `post_export_registration` interceptor. The (possibly modified) response returned by + `post_export_registration` will be passed to + `post_export_registration_with_metadata`. + """ + return response, metadata + def pre_get_registration( self, request: domains.GetRegistrationRequest, @@ -338,12 +453,35 @@ def post_get_registration( ) -> domains.Registration: """Post-rpc interceptor for get_registration - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_registration_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_get_registration` interceptor runs + before the `post_get_registration_with_metadata` interceptor. """ return response + def post_get_registration_with_metadata( + self, + response: domains.Registration, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[domains.Registration, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_registration + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_get_registration_with_metadata` + interceptor in new development instead of the `post_get_registration` interceptor. + When both interceptors are used, this `post_get_registration_with_metadata` interceptor runs after the + `post_get_registration` interceptor. The (possibly modified) response returned by + `post_get_registration` will be passed to + `post_get_registration_with_metadata`. + """ + return response, metadata + def pre_list_registrations( self, request: domains.ListRegistrationsRequest, @@ -363,12 +501,37 @@ def post_list_registrations( ) -> domains.ListRegistrationsResponse: """Post-rpc interceptor for list_registrations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_registrations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_list_registrations` interceptor runs + before the `post_list_registrations_with_metadata` interceptor. """ return response + def post_list_registrations_with_metadata( + self, + response: domains.ListRegistrationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + domains.ListRegistrationsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_registrations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_list_registrations_with_metadata` + interceptor in new development instead of the `post_list_registrations` interceptor. + When both interceptors are used, this `post_list_registrations_with_metadata` interceptor runs after the + `post_list_registrations` interceptor. The (possibly modified) response returned by + `post_list_registrations` will be passed to + `post_list_registrations_with_metadata`. + """ + return response, metadata + def pre_register_domain( self, request: domains.RegisterDomainRequest, @@ -386,12 +549,35 @@ def post_register_domain( ) -> operations_pb2.Operation: """Post-rpc interceptor for register_domain - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_register_domain_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_register_domain` interceptor runs + before the `post_register_domain_with_metadata` interceptor. """ return response + def post_register_domain_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for register_domain + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_register_domain_with_metadata` + interceptor in new development instead of the `post_register_domain` interceptor. + When both interceptors are used, this `post_register_domain_with_metadata` interceptor runs after the + `post_register_domain` interceptor. The (possibly modified) response returned by + `post_register_domain` will be passed to + `post_register_domain_with_metadata`. + """ + return response, metadata + def pre_reset_authorization_code( self, request: domains.ResetAuthorizationCodeRequest, @@ -411,12 +597,35 @@ def post_reset_authorization_code( ) -> domains.AuthorizationCode: """Post-rpc interceptor for reset_authorization_code - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_reset_authorization_code_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_reset_authorization_code` interceptor runs + before the `post_reset_authorization_code_with_metadata` interceptor. """ return response + def post_reset_authorization_code_with_metadata( + self, + response: domains.AuthorizationCode, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[domains.AuthorizationCode, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for reset_authorization_code + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_reset_authorization_code_with_metadata` + interceptor in new development instead of the `post_reset_authorization_code` interceptor. + When both interceptors are used, this `post_reset_authorization_code_with_metadata` interceptor runs after the + `post_reset_authorization_code` interceptor. The (possibly modified) response returned by + `post_reset_authorization_code` will be passed to + `post_reset_authorization_code_with_metadata`. + """ + return response, metadata + def pre_retrieve_authorization_code( self, request: domains.RetrieveAuthorizationCodeRequest, @@ -437,12 +646,35 @@ def post_retrieve_authorization_code( ) -> domains.AuthorizationCode: """Post-rpc interceptor for retrieve_authorization_code - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_retrieve_authorization_code_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_retrieve_authorization_code` interceptor runs + before the `post_retrieve_authorization_code_with_metadata` interceptor. """ return response + def post_retrieve_authorization_code_with_metadata( + self, + response: domains.AuthorizationCode, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[domains.AuthorizationCode, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for retrieve_authorization_code + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_retrieve_authorization_code_with_metadata` + interceptor in new development instead of the `post_retrieve_authorization_code` interceptor. + When both interceptors are used, this `post_retrieve_authorization_code_with_metadata` interceptor runs after the + `post_retrieve_authorization_code` interceptor. The (possibly modified) response returned by + `post_retrieve_authorization_code` will be passed to + `post_retrieve_authorization_code_with_metadata`. + """ + return response, metadata + def pre_retrieve_register_parameters( self, request: domains.RetrieveRegisterParametersRequest, @@ -463,12 +695,38 @@ def post_retrieve_register_parameters( ) -> domains.RetrieveRegisterParametersResponse: """Post-rpc interceptor for retrieve_register_parameters - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_retrieve_register_parameters_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_retrieve_register_parameters` interceptor runs + before the `post_retrieve_register_parameters_with_metadata` interceptor. """ return response + def post_retrieve_register_parameters_with_metadata( + self, + response: domains.RetrieveRegisterParametersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + domains.RetrieveRegisterParametersResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for retrieve_register_parameters + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_retrieve_register_parameters_with_metadata` + interceptor in new development instead of the `post_retrieve_register_parameters` interceptor. + When both interceptors are used, this `post_retrieve_register_parameters_with_metadata` interceptor runs after the + `post_retrieve_register_parameters` interceptor. The (possibly modified) response returned by + `post_retrieve_register_parameters` will be passed to + `post_retrieve_register_parameters_with_metadata`. + """ + return response, metadata + def pre_retrieve_transfer_parameters( self, request: domains.RetrieveTransferParametersRequest, @@ -489,12 +747,38 @@ def post_retrieve_transfer_parameters( ) -> domains.RetrieveTransferParametersResponse: """Post-rpc interceptor for retrieve_transfer_parameters - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_retrieve_transfer_parameters_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_retrieve_transfer_parameters` interceptor runs + before the `post_retrieve_transfer_parameters_with_metadata` interceptor. """ return response + def post_retrieve_transfer_parameters_with_metadata( + self, + response: domains.RetrieveTransferParametersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + domains.RetrieveTransferParametersResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for retrieve_transfer_parameters + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_retrieve_transfer_parameters_with_metadata` + interceptor in new development instead of the `post_retrieve_transfer_parameters` interceptor. + When both interceptors are used, this `post_retrieve_transfer_parameters_with_metadata` interceptor runs after the + `post_retrieve_transfer_parameters` interceptor. The (possibly modified) response returned by + `post_retrieve_transfer_parameters` will be passed to + `post_retrieve_transfer_parameters_with_metadata`. + """ + return response, metadata + def pre_search_domains( self, request: domains.SearchDomainsRequest, @@ -512,12 +796,35 @@ def post_search_domains( ) -> domains.SearchDomainsResponse: """Post-rpc interceptor for search_domains - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_domains_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_search_domains` interceptor runs + before the `post_search_domains_with_metadata` interceptor. """ return response + def post_search_domains_with_metadata( + self, + response: domains.SearchDomainsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[domains.SearchDomainsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search_domains + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_search_domains_with_metadata` + interceptor in new development instead of the `post_search_domains` interceptor. + When both interceptors are used, this `post_search_domains_with_metadata` interceptor runs after the + `post_search_domains` interceptor. The (possibly modified) response returned by + `post_search_domains` will be passed to + `post_search_domains_with_metadata`. + """ + return response, metadata + def pre_transfer_domain( self, request: domains.TransferDomainRequest, @@ -535,12 +842,35 @@ def post_transfer_domain( ) -> operations_pb2.Operation: """Post-rpc interceptor for transfer_domain - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_transfer_domain_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_transfer_domain` interceptor runs + before the `post_transfer_domain_with_metadata` interceptor. """ return response + def post_transfer_domain_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for transfer_domain + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_transfer_domain_with_metadata` + interceptor in new development instead of the `post_transfer_domain` interceptor. + When both interceptors are used, this `post_transfer_domain_with_metadata` interceptor runs after the + `post_transfer_domain` interceptor. The (possibly modified) response returned by + `post_transfer_domain` will be passed to + `post_transfer_domain_with_metadata`. + """ + return response, metadata + def pre_update_registration( self, request: domains.UpdateRegistrationRequest, @@ -560,12 +890,35 @@ def post_update_registration( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_registration - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_registration_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_update_registration` interceptor runs + before the `post_update_registration_with_metadata` interceptor. """ return response + def post_update_registration_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_registration + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_update_registration_with_metadata` + interceptor in new development instead of the `post_update_registration` interceptor. + When both interceptors are used, this `post_update_registration_with_metadata` interceptor runs after the + `post_update_registration` interceptor. The (possibly modified) response returned by + `post_update_registration` will be passed to + `post_update_registration_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class DomainsRestStub: @@ -822,6 +1175,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_configure_contact_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_configure_contact_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -971,6 +1328,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_configure_dns_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_configure_dns_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1121,6 +1482,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_configure_management_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_configure_management_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1264,6 +1632,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_registration(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_registration_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1413,6 +1785,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_registration(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_registration_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1581,6 +1957,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_registration(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_registration_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1725,6 +2105,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_registrations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_registrations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1878,6 +2262,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_register_domain(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_register_domain_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2026,6 +2414,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_reset_authorization_code(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_reset_authorization_code_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2169,6 +2561,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_retrieve_authorization_code(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_retrieve_authorization_code_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2312,6 +2708,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_retrieve_register_parameters(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_retrieve_register_parameters_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2457,6 +2857,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_retrieve_transfer_parameters(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_retrieve_transfer_parameters_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2601,6 +3005,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_domains(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_domains_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2752,6 +3160,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_transfer_domain(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_transfer_domain_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2901,6 +3313,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_registration(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_registration_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-domains/google/cloud/domains_v1beta1/gapic_version.py b/packages/google-cloud-domains/google/cloud/domains_v1beta1/gapic_version.py index 1c08bcbd1569..558c8aab67c5 100644 --- a/packages/google-cloud-domains/google/cloud/domains_v1beta1/gapic_version.py +++ b/packages/google-cloud-domains/google/cloud/domains_v1beta1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "1.9.0" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-domains/google/cloud/domains_v1beta1/services/domains/client.py b/packages/google-cloud-domains/google/cloud/domains_v1beta1/services/domains/client.py index 3d6f5f03acfe..bc8c11e981b4 100644 --- a/packages/google-cloud-domains/google/cloud/domains_v1beta1/services/domains/client.py +++ b/packages/google-cloud-domains/google/cloud/domains_v1beta1/services/domains/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -491,6 +493,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-domains/google/cloud/domains_v1beta1/services/domains/transports/rest.py b/packages/google-cloud-domains/google/cloud/domains_v1beta1/services/domains/transports/rest.py index 84bc362c351e..a57473444380 100644 --- a/packages/google-cloud-domains/google/cloud/domains_v1beta1/services/domains/transports/rest.py +++ b/packages/google-cloud-domains/google/cloud/domains_v1beta1/services/domains/transports/rest.py @@ -214,12 +214,35 @@ def post_configure_contact_settings( ) -> operations_pb2.Operation: """Post-rpc interceptor for configure_contact_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_configure_contact_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_configure_contact_settings` interceptor runs + before the `post_configure_contact_settings_with_metadata` interceptor. """ return response + def post_configure_contact_settings_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for configure_contact_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_configure_contact_settings_with_metadata` + interceptor in new development instead of the `post_configure_contact_settings` interceptor. + When both interceptors are used, this `post_configure_contact_settings_with_metadata` interceptor runs after the + `post_configure_contact_settings` interceptor. The (possibly modified) response returned by + `post_configure_contact_settings` will be passed to + `post_configure_contact_settings_with_metadata`. + """ + return response, metadata + def pre_configure_dns_settings( self, request: domains.ConfigureDnsSettingsRequest, @@ -239,12 +262,35 @@ def post_configure_dns_settings( ) -> operations_pb2.Operation: """Post-rpc interceptor for configure_dns_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_configure_dns_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_configure_dns_settings` interceptor runs + before the `post_configure_dns_settings_with_metadata` interceptor. """ return response + def post_configure_dns_settings_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for configure_dns_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_configure_dns_settings_with_metadata` + interceptor in new development instead of the `post_configure_dns_settings` interceptor. + When both interceptors are used, this `post_configure_dns_settings_with_metadata` interceptor runs after the + `post_configure_dns_settings` interceptor. The (possibly modified) response returned by + `post_configure_dns_settings` will be passed to + `post_configure_dns_settings_with_metadata`. + """ + return response, metadata + def pre_configure_management_settings( self, request: domains.ConfigureManagementSettingsRequest, @@ -265,12 +311,35 @@ def post_configure_management_settings( ) -> operations_pb2.Operation: """Post-rpc interceptor for configure_management_settings - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_configure_management_settings_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_configure_management_settings` interceptor runs + before the `post_configure_management_settings_with_metadata` interceptor. """ return response + def post_configure_management_settings_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for configure_management_settings + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_configure_management_settings_with_metadata` + interceptor in new development instead of the `post_configure_management_settings` interceptor. + When both interceptors are used, this `post_configure_management_settings_with_metadata` interceptor runs after the + `post_configure_management_settings` interceptor. The (possibly modified) response returned by + `post_configure_management_settings` will be passed to + `post_configure_management_settings_with_metadata`. + """ + return response, metadata + def pre_delete_registration( self, request: domains.DeleteRegistrationRequest, @@ -290,12 +359,35 @@ def post_delete_registration( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_registration - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_registration_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_delete_registration` interceptor runs + before the `post_delete_registration_with_metadata` interceptor. """ return response + def post_delete_registration_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_registration + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_delete_registration_with_metadata` + interceptor in new development instead of the `post_delete_registration` interceptor. + When both interceptors are used, this `post_delete_registration_with_metadata` interceptor runs after the + `post_delete_registration` interceptor. The (possibly modified) response returned by + `post_delete_registration` will be passed to + `post_delete_registration_with_metadata`. + """ + return response, metadata + def pre_export_registration( self, request: domains.ExportRegistrationRequest, @@ -315,12 +407,35 @@ def post_export_registration( ) -> operations_pb2.Operation: """Post-rpc interceptor for export_registration - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_export_registration_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_export_registration` interceptor runs + before the `post_export_registration_with_metadata` interceptor. """ return response + def post_export_registration_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for export_registration + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_export_registration_with_metadata` + interceptor in new development instead of the `post_export_registration` interceptor. + When both interceptors are used, this `post_export_registration_with_metadata` interceptor runs after the + `post_export_registration` interceptor. The (possibly modified) response returned by + `post_export_registration` will be passed to + `post_export_registration_with_metadata`. + """ + return response, metadata + def pre_get_registration( self, request: domains.GetRegistrationRequest, @@ -338,12 +453,35 @@ def post_get_registration( ) -> domains.Registration: """Post-rpc interceptor for get_registration - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_registration_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_get_registration` interceptor runs + before the `post_get_registration_with_metadata` interceptor. """ return response + def post_get_registration_with_metadata( + self, + response: domains.Registration, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[domains.Registration, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_registration + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_get_registration_with_metadata` + interceptor in new development instead of the `post_get_registration` interceptor. + When both interceptors are used, this `post_get_registration_with_metadata` interceptor runs after the + `post_get_registration` interceptor. The (possibly modified) response returned by + `post_get_registration` will be passed to + `post_get_registration_with_metadata`. + """ + return response, metadata + def pre_list_registrations( self, request: domains.ListRegistrationsRequest, @@ -363,12 +501,37 @@ def post_list_registrations( ) -> domains.ListRegistrationsResponse: """Post-rpc interceptor for list_registrations - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_registrations_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_list_registrations` interceptor runs + before the `post_list_registrations_with_metadata` interceptor. """ return response + def post_list_registrations_with_metadata( + self, + response: domains.ListRegistrationsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + domains.ListRegistrationsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_registrations + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_list_registrations_with_metadata` + interceptor in new development instead of the `post_list_registrations` interceptor. + When both interceptors are used, this `post_list_registrations_with_metadata` interceptor runs after the + `post_list_registrations` interceptor. The (possibly modified) response returned by + `post_list_registrations` will be passed to + `post_list_registrations_with_metadata`. + """ + return response, metadata + def pre_register_domain( self, request: domains.RegisterDomainRequest, @@ -386,12 +549,35 @@ def post_register_domain( ) -> operations_pb2.Operation: """Post-rpc interceptor for register_domain - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_register_domain_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_register_domain` interceptor runs + before the `post_register_domain_with_metadata` interceptor. """ return response + def post_register_domain_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for register_domain + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_register_domain_with_metadata` + interceptor in new development instead of the `post_register_domain` interceptor. + When both interceptors are used, this `post_register_domain_with_metadata` interceptor runs after the + `post_register_domain` interceptor. The (possibly modified) response returned by + `post_register_domain` will be passed to + `post_register_domain_with_metadata`. + """ + return response, metadata + def pre_reset_authorization_code( self, request: domains.ResetAuthorizationCodeRequest, @@ -411,12 +597,35 @@ def post_reset_authorization_code( ) -> domains.AuthorizationCode: """Post-rpc interceptor for reset_authorization_code - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_reset_authorization_code_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_reset_authorization_code` interceptor runs + before the `post_reset_authorization_code_with_metadata` interceptor. """ return response + def post_reset_authorization_code_with_metadata( + self, + response: domains.AuthorizationCode, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[domains.AuthorizationCode, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for reset_authorization_code + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_reset_authorization_code_with_metadata` + interceptor in new development instead of the `post_reset_authorization_code` interceptor. + When both interceptors are used, this `post_reset_authorization_code_with_metadata` interceptor runs after the + `post_reset_authorization_code` interceptor. The (possibly modified) response returned by + `post_reset_authorization_code` will be passed to + `post_reset_authorization_code_with_metadata`. + """ + return response, metadata + def pre_retrieve_authorization_code( self, request: domains.RetrieveAuthorizationCodeRequest, @@ -437,12 +646,35 @@ def post_retrieve_authorization_code( ) -> domains.AuthorizationCode: """Post-rpc interceptor for retrieve_authorization_code - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_retrieve_authorization_code_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_retrieve_authorization_code` interceptor runs + before the `post_retrieve_authorization_code_with_metadata` interceptor. """ return response + def post_retrieve_authorization_code_with_metadata( + self, + response: domains.AuthorizationCode, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[domains.AuthorizationCode, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for retrieve_authorization_code + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_retrieve_authorization_code_with_metadata` + interceptor in new development instead of the `post_retrieve_authorization_code` interceptor. + When both interceptors are used, this `post_retrieve_authorization_code_with_metadata` interceptor runs after the + `post_retrieve_authorization_code` interceptor. The (possibly modified) response returned by + `post_retrieve_authorization_code` will be passed to + `post_retrieve_authorization_code_with_metadata`. + """ + return response, metadata + def pre_retrieve_register_parameters( self, request: domains.RetrieveRegisterParametersRequest, @@ -463,12 +695,38 @@ def post_retrieve_register_parameters( ) -> domains.RetrieveRegisterParametersResponse: """Post-rpc interceptor for retrieve_register_parameters - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_retrieve_register_parameters_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_retrieve_register_parameters` interceptor runs + before the `post_retrieve_register_parameters_with_metadata` interceptor. """ return response + def post_retrieve_register_parameters_with_metadata( + self, + response: domains.RetrieveRegisterParametersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + domains.RetrieveRegisterParametersResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for retrieve_register_parameters + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_retrieve_register_parameters_with_metadata` + interceptor in new development instead of the `post_retrieve_register_parameters` interceptor. + When both interceptors are used, this `post_retrieve_register_parameters_with_metadata` interceptor runs after the + `post_retrieve_register_parameters` interceptor. The (possibly modified) response returned by + `post_retrieve_register_parameters` will be passed to + `post_retrieve_register_parameters_with_metadata`. + """ + return response, metadata + def pre_retrieve_transfer_parameters( self, request: domains.RetrieveTransferParametersRequest, @@ -489,12 +747,38 @@ def post_retrieve_transfer_parameters( ) -> domains.RetrieveTransferParametersResponse: """Post-rpc interceptor for retrieve_transfer_parameters - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_retrieve_transfer_parameters_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_retrieve_transfer_parameters` interceptor runs + before the `post_retrieve_transfer_parameters_with_metadata` interceptor. """ return response + def post_retrieve_transfer_parameters_with_metadata( + self, + response: domains.RetrieveTransferParametersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + domains.RetrieveTransferParametersResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for retrieve_transfer_parameters + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_retrieve_transfer_parameters_with_metadata` + interceptor in new development instead of the `post_retrieve_transfer_parameters` interceptor. + When both interceptors are used, this `post_retrieve_transfer_parameters_with_metadata` interceptor runs after the + `post_retrieve_transfer_parameters` interceptor. The (possibly modified) response returned by + `post_retrieve_transfer_parameters` will be passed to + `post_retrieve_transfer_parameters_with_metadata`. + """ + return response, metadata + def pre_search_domains( self, request: domains.SearchDomainsRequest, @@ -512,12 +796,35 @@ def post_search_domains( ) -> domains.SearchDomainsResponse: """Post-rpc interceptor for search_domains - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_domains_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_search_domains` interceptor runs + before the `post_search_domains_with_metadata` interceptor. """ return response + def post_search_domains_with_metadata( + self, + response: domains.SearchDomainsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[domains.SearchDomainsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search_domains + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_search_domains_with_metadata` + interceptor in new development instead of the `post_search_domains` interceptor. + When both interceptors are used, this `post_search_domains_with_metadata` interceptor runs after the + `post_search_domains` interceptor. The (possibly modified) response returned by + `post_search_domains` will be passed to + `post_search_domains_with_metadata`. + """ + return response, metadata + def pre_transfer_domain( self, request: domains.TransferDomainRequest, @@ -535,12 +842,35 @@ def post_transfer_domain( ) -> operations_pb2.Operation: """Post-rpc interceptor for transfer_domain - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_transfer_domain_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_transfer_domain` interceptor runs + before the `post_transfer_domain_with_metadata` interceptor. """ return response + def post_transfer_domain_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for transfer_domain + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_transfer_domain_with_metadata` + interceptor in new development instead of the `post_transfer_domain` interceptor. + When both interceptors are used, this `post_transfer_domain_with_metadata` interceptor runs after the + `post_transfer_domain` interceptor. The (possibly modified) response returned by + `post_transfer_domain` will be passed to + `post_transfer_domain_with_metadata`. + """ + return response, metadata + def pre_update_registration( self, request: domains.UpdateRegistrationRequest, @@ -560,12 +890,35 @@ def post_update_registration( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_registration - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_registration_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the Domains server but before - it is returned to user code. + it is returned to user code. This `post_update_registration` interceptor runs + before the `post_update_registration_with_metadata` interceptor. """ return response + def post_update_registration_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_registration + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the Domains server but before it is returned to user code. + + We recommend only using this `post_update_registration_with_metadata` + interceptor in new development instead of the `post_update_registration` interceptor. + When both interceptors are used, this `post_update_registration_with_metadata` interceptor runs after the + `post_update_registration` interceptor. The (possibly modified) response returned by + `post_update_registration` will be passed to + `post_update_registration_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class DomainsRestStub: @@ -822,6 +1175,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_configure_contact_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_configure_contact_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -971,6 +1328,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_configure_dns_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_configure_dns_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1121,6 +1482,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_configure_management_settings(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_configure_management_settings_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1264,6 +1632,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_registration(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_registration_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1413,6 +1785,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_export_registration(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_export_registration_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1581,6 +1957,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_registration(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_registration_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1725,6 +2105,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_registrations(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_registrations_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1878,6 +2262,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_register_domain(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_register_domain_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2026,6 +2414,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_reset_authorization_code(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_reset_authorization_code_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2169,6 +2561,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_retrieve_authorization_code(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_retrieve_authorization_code_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2312,6 +2708,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_retrieve_register_parameters(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_retrieve_register_parameters_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2457,6 +2857,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_retrieve_transfer_parameters(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_retrieve_transfer_parameters_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2601,6 +3005,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_domains(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_domains_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2752,6 +3160,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_transfer_domain(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_transfer_domain_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2901,6 +3313,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_registration(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_registration_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-domains/samples/generated_samples/snippet_metadata_google.cloud.domains.v1.json b/packages/google-cloud-domains/samples/generated_samples/snippet_metadata_google.cloud.domains.v1.json index db2d9e3e9be6..a78fdcc2efa6 100644 --- a/packages/google-cloud-domains/samples/generated_samples/snippet_metadata_google.cloud.domains.v1.json +++ b/packages/google-cloud-domains/samples/generated_samples/snippet_metadata_google.cloud.domains.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-domains", - "version": "1.9.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-domains/samples/generated_samples/snippet_metadata_google.cloud.domains.v1beta1.json b/packages/google-cloud-domains/samples/generated_samples/snippet_metadata_google.cloud.domains.v1beta1.json index b47d940bd529..cec560b94d2d 100644 --- a/packages/google-cloud-domains/samples/generated_samples/snippet_metadata_google.cloud.domains.v1beta1.json +++ b/packages/google-cloud-domains/samples/generated_samples/snippet_metadata_google.cloud.domains.v1beta1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-domains", - "version": "1.9.0" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-domains/tests/unit/gapic/domains_v1/test_domains.py b/packages/google-cloud-domains/tests/unit/gapic/domains_v1/test_domains.py index 18a6ea1a606c..44ad86c67345 100644 --- a/packages/google-cloud-domains/tests/unit/gapic/domains_v1/test_domains.py +++ b/packages/google-cloud-domains/tests/unit/gapic/domains_v1/test_domains.py @@ -75,6 +75,13 @@ ) from google.cloud.domains_v1.types import domains +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -298,6 +305,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DomainsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DomainsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -10424,10 +10474,13 @@ def test_search_domains_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_search_domains" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_search_domains_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_search_domains" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.SearchDomainsRequest.pb(domains.SearchDomainsRequest()) transcode.return_value = { "method": "post", @@ -10451,6 +10504,7 @@ def test_search_domains_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.SearchDomainsResponse() + post_with_metadata.return_value = domains.SearchDomainsResponse(), metadata client.search_domains( request, @@ -10462,6 +10516,7 @@ def test_search_domains_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_retrieve_register_parameters_rest_bad_request( @@ -10541,10 +10596,14 @@ def test_retrieve_register_parameters_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_retrieve_register_parameters" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_retrieve_register_parameters_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_retrieve_register_parameters" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.RetrieveRegisterParametersRequest.pb( domains.RetrieveRegisterParametersRequest() ) @@ -10570,6 +10629,10 @@ def test_retrieve_register_parameters_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.RetrieveRegisterParametersResponse() + post_with_metadata.return_value = ( + domains.RetrieveRegisterParametersResponse(), + metadata, + ) client.retrieve_register_parameters( request, @@ -10581,6 +10644,7 @@ def test_retrieve_register_parameters_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_register_domain_rest_bad_request(request_type=domains.RegisterDomainRequest): @@ -10657,10 +10721,13 @@ def test_register_domain_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_register_domain" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_register_domain_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_register_domain" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.RegisterDomainRequest.pb(domains.RegisterDomainRequest()) transcode.return_value = { "method": "post", @@ -10682,6 +10749,7 @@ def test_register_domain_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.register_domain( request, @@ -10693,6 +10761,7 @@ def test_register_domain_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_retrieve_transfer_parameters_rest_bad_request( @@ -10772,10 +10841,14 @@ def test_retrieve_transfer_parameters_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_retrieve_transfer_parameters" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_retrieve_transfer_parameters_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_retrieve_transfer_parameters" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.RetrieveTransferParametersRequest.pb( domains.RetrieveTransferParametersRequest() ) @@ -10801,6 +10874,10 @@ def test_retrieve_transfer_parameters_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.RetrieveTransferParametersResponse() + post_with_metadata.return_value = ( + domains.RetrieveTransferParametersResponse(), + metadata, + ) client.retrieve_transfer_parameters( request, @@ -10812,6 +10889,7 @@ def test_retrieve_transfer_parameters_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_transfer_domain_rest_bad_request(request_type=domains.TransferDomainRequest): @@ -10888,10 +10966,13 @@ def test_transfer_domain_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_transfer_domain" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_transfer_domain_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_transfer_domain" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.TransferDomainRequest.pb(domains.TransferDomainRequest()) transcode.return_value = { "method": "post", @@ -10913,6 +10994,7 @@ def test_transfer_domain_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.transfer_domain( request, @@ -10924,6 +11006,7 @@ def test_transfer_domain_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_registrations_rest_bad_request( @@ -11006,10 +11089,13 @@ def test_list_registrations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_list_registrations" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_list_registrations_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_list_registrations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ListRegistrationsRequest.pb( domains.ListRegistrationsRequest() ) @@ -11035,6 +11121,7 @@ def test_list_registrations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.ListRegistrationsResponse() + post_with_metadata.return_value = domains.ListRegistrationsResponse(), metadata client.list_registrations( request, @@ -11046,6 +11133,7 @@ def test_list_registrations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_registration_rest_bad_request(request_type=domains.GetRegistrationRequest): @@ -11134,10 +11222,13 @@ def test_get_registration_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_get_registration" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_get_registration_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_get_registration" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.GetRegistrationRequest.pb(domains.GetRegistrationRequest()) transcode.return_value = { "method": "post", @@ -11159,6 +11250,7 @@ def test_get_registration_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.Registration() + post_with_metadata.return_value = domains.Registration(), metadata client.get_registration( request, @@ -11170,6 +11262,7 @@ def test_get_registration_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_registration_rest_bad_request( @@ -11389,10 +11482,13 @@ def test_update_registration_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_update_registration" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_update_registration_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_update_registration" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.UpdateRegistrationRequest.pb( domains.UpdateRegistrationRequest() ) @@ -11416,6 +11512,7 @@ def test_update_registration_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_registration( request, @@ -11427,6 +11524,7 @@ def test_update_registration_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_configure_management_settings_rest_bad_request( @@ -11509,10 +11607,14 @@ def test_configure_management_settings_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_configure_management_settings" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_configure_management_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_configure_management_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ConfigureManagementSettingsRequest.pb( domains.ConfigureManagementSettingsRequest() ) @@ -11536,6 +11638,7 @@ def test_configure_management_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.configure_management_settings( request, @@ -11547,6 +11650,7 @@ def test_configure_management_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_configure_dns_settings_rest_bad_request( @@ -11629,10 +11733,13 @@ def test_configure_dns_settings_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_configure_dns_settings" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_configure_dns_settings_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_configure_dns_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ConfigureDnsSettingsRequest.pb( domains.ConfigureDnsSettingsRequest() ) @@ -11656,6 +11763,7 @@ def test_configure_dns_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.configure_dns_settings( request, @@ -11667,6 +11775,7 @@ def test_configure_dns_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_configure_contact_settings_rest_bad_request( @@ -11749,10 +11858,14 @@ def test_configure_contact_settings_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_configure_contact_settings" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_configure_contact_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_configure_contact_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ConfigureContactSettingsRequest.pb( domains.ConfigureContactSettingsRequest() ) @@ -11776,6 +11889,7 @@ def test_configure_contact_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.configure_contact_settings( request, @@ -11787,6 +11901,7 @@ def test_configure_contact_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_registration_rest_bad_request( @@ -11865,10 +11980,13 @@ def test_export_registration_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_export_registration" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_export_registration_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_export_registration" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ExportRegistrationRequest.pb( domains.ExportRegistrationRequest() ) @@ -11892,6 +12010,7 @@ def test_export_registration_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_registration( request, @@ -11903,6 +12022,7 @@ def test_export_registration_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_registration_rest_bad_request( @@ -11981,10 +12101,13 @@ def test_delete_registration_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_delete_registration" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_delete_registration_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_delete_registration" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.DeleteRegistrationRequest.pb( domains.DeleteRegistrationRequest() ) @@ -12008,6 +12131,7 @@ def test_delete_registration_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_registration( request, @@ -12019,6 +12143,7 @@ def test_delete_registration_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_retrieve_authorization_code_rest_bad_request( @@ -12105,10 +12230,14 @@ def test_retrieve_authorization_code_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_retrieve_authorization_code" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_retrieve_authorization_code_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_retrieve_authorization_code" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.RetrieveAuthorizationCodeRequest.pb( domains.RetrieveAuthorizationCodeRequest() ) @@ -12132,6 +12261,7 @@ def test_retrieve_authorization_code_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.AuthorizationCode() + post_with_metadata.return_value = domains.AuthorizationCode(), metadata client.retrieve_authorization_code( request, @@ -12143,6 +12273,7 @@ def test_retrieve_authorization_code_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_reset_authorization_code_rest_bad_request( @@ -12229,10 +12360,13 @@ def test_reset_authorization_code_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_reset_authorization_code" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_reset_authorization_code_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_reset_authorization_code" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ResetAuthorizationCodeRequest.pb( domains.ResetAuthorizationCodeRequest() ) @@ -12256,6 +12390,7 @@ def test_reset_authorization_code_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.AuthorizationCode() + post_with_metadata.return_value = domains.AuthorizationCode(), metadata client.reset_authorization_code( request, @@ -12267,6 +12402,7 @@ def test_reset_authorization_code_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-domains/tests/unit/gapic/domains_v1beta1/test_domains.py b/packages/google-cloud-domains/tests/unit/gapic/domains_v1beta1/test_domains.py index c5f9ab7872d1..610e5ffb0691 100644 --- a/packages/google-cloud-domains/tests/unit/gapic/domains_v1beta1/test_domains.py +++ b/packages/google-cloud-domains/tests/unit/gapic/domains_v1beta1/test_domains.py @@ -75,6 +75,13 @@ ) from google.cloud.domains_v1beta1.types import domains +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -298,6 +305,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = DomainsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = DomainsClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -10424,10 +10474,13 @@ def test_search_domains_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_search_domains" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_search_domains_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_search_domains" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.SearchDomainsRequest.pb(domains.SearchDomainsRequest()) transcode.return_value = { "method": "post", @@ -10451,6 +10504,7 @@ def test_search_domains_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.SearchDomainsResponse() + post_with_metadata.return_value = domains.SearchDomainsResponse(), metadata client.search_domains( request, @@ -10462,6 +10516,7 @@ def test_search_domains_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_retrieve_register_parameters_rest_bad_request( @@ -10541,10 +10596,14 @@ def test_retrieve_register_parameters_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_retrieve_register_parameters" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_retrieve_register_parameters_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_retrieve_register_parameters" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.RetrieveRegisterParametersRequest.pb( domains.RetrieveRegisterParametersRequest() ) @@ -10570,6 +10629,10 @@ def test_retrieve_register_parameters_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.RetrieveRegisterParametersResponse() + post_with_metadata.return_value = ( + domains.RetrieveRegisterParametersResponse(), + metadata, + ) client.retrieve_register_parameters( request, @@ -10581,6 +10644,7 @@ def test_retrieve_register_parameters_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_register_domain_rest_bad_request(request_type=domains.RegisterDomainRequest): @@ -10657,10 +10721,13 @@ def test_register_domain_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_register_domain" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_register_domain_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_register_domain" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.RegisterDomainRequest.pb(domains.RegisterDomainRequest()) transcode.return_value = { "method": "post", @@ -10682,6 +10749,7 @@ def test_register_domain_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.register_domain( request, @@ -10693,6 +10761,7 @@ def test_register_domain_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_retrieve_transfer_parameters_rest_bad_request( @@ -10772,10 +10841,14 @@ def test_retrieve_transfer_parameters_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_retrieve_transfer_parameters" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_retrieve_transfer_parameters_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_retrieve_transfer_parameters" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.RetrieveTransferParametersRequest.pb( domains.RetrieveTransferParametersRequest() ) @@ -10801,6 +10874,10 @@ def test_retrieve_transfer_parameters_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.RetrieveTransferParametersResponse() + post_with_metadata.return_value = ( + domains.RetrieveTransferParametersResponse(), + metadata, + ) client.retrieve_transfer_parameters( request, @@ -10812,6 +10889,7 @@ def test_retrieve_transfer_parameters_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_transfer_domain_rest_bad_request(request_type=domains.TransferDomainRequest): @@ -10888,10 +10966,13 @@ def test_transfer_domain_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_transfer_domain" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_transfer_domain_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_transfer_domain" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.TransferDomainRequest.pb(domains.TransferDomainRequest()) transcode.return_value = { "method": "post", @@ -10913,6 +10994,7 @@ def test_transfer_domain_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.transfer_domain( request, @@ -10924,6 +11006,7 @@ def test_transfer_domain_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_registrations_rest_bad_request( @@ -11006,10 +11089,13 @@ def test_list_registrations_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_list_registrations" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_list_registrations_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_list_registrations" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ListRegistrationsRequest.pb( domains.ListRegistrationsRequest() ) @@ -11035,6 +11121,7 @@ def test_list_registrations_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.ListRegistrationsResponse() + post_with_metadata.return_value = domains.ListRegistrationsResponse(), metadata client.list_registrations( request, @@ -11046,6 +11133,7 @@ def test_list_registrations_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_registration_rest_bad_request(request_type=domains.GetRegistrationRequest): @@ -11134,10 +11222,13 @@ def test_get_registration_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_get_registration" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_get_registration_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_get_registration" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.GetRegistrationRequest.pb(domains.GetRegistrationRequest()) transcode.return_value = { "method": "post", @@ -11159,6 +11250,7 @@ def test_get_registration_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.Registration() + post_with_metadata.return_value = domains.Registration(), metadata client.get_registration( request, @@ -11170,6 +11262,7 @@ def test_get_registration_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_registration_rest_bad_request( @@ -11389,10 +11482,13 @@ def test_update_registration_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_update_registration" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_update_registration_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_update_registration" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.UpdateRegistrationRequest.pb( domains.UpdateRegistrationRequest() ) @@ -11416,6 +11512,7 @@ def test_update_registration_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_registration( request, @@ -11427,6 +11524,7 @@ def test_update_registration_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_configure_management_settings_rest_bad_request( @@ -11509,10 +11607,14 @@ def test_configure_management_settings_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_configure_management_settings" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_configure_management_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_configure_management_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ConfigureManagementSettingsRequest.pb( domains.ConfigureManagementSettingsRequest() ) @@ -11536,6 +11638,7 @@ def test_configure_management_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.configure_management_settings( request, @@ -11547,6 +11650,7 @@ def test_configure_management_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_configure_dns_settings_rest_bad_request( @@ -11629,10 +11733,13 @@ def test_configure_dns_settings_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_configure_dns_settings" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_configure_dns_settings_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_configure_dns_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ConfigureDnsSettingsRequest.pb( domains.ConfigureDnsSettingsRequest() ) @@ -11656,6 +11763,7 @@ def test_configure_dns_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.configure_dns_settings( request, @@ -11667,6 +11775,7 @@ def test_configure_dns_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_configure_contact_settings_rest_bad_request( @@ -11749,10 +11858,14 @@ def test_configure_contact_settings_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_configure_contact_settings" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_configure_contact_settings_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_configure_contact_settings" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ConfigureContactSettingsRequest.pb( domains.ConfigureContactSettingsRequest() ) @@ -11776,6 +11889,7 @@ def test_configure_contact_settings_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.configure_contact_settings( request, @@ -11787,6 +11901,7 @@ def test_configure_contact_settings_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_export_registration_rest_bad_request( @@ -11865,10 +11980,13 @@ def test_export_registration_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_export_registration" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_export_registration_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_export_registration" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ExportRegistrationRequest.pb( domains.ExportRegistrationRequest() ) @@ -11892,6 +12010,7 @@ def test_export_registration_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.export_registration( request, @@ -11903,6 +12022,7 @@ def test_export_registration_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_registration_rest_bad_request( @@ -11981,10 +12101,13 @@ def test_delete_registration_rest_interceptors(null_interceptor): ), mock.patch.object( transports.DomainsRestInterceptor, "post_delete_registration" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_delete_registration_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_delete_registration" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.DeleteRegistrationRequest.pb( domains.DeleteRegistrationRequest() ) @@ -12008,6 +12131,7 @@ def test_delete_registration_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_registration( request, @@ -12019,6 +12143,7 @@ def test_delete_registration_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_retrieve_authorization_code_rest_bad_request( @@ -12105,10 +12230,14 @@ def test_retrieve_authorization_code_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_retrieve_authorization_code" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, + "post_retrieve_authorization_code_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_retrieve_authorization_code" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.RetrieveAuthorizationCodeRequest.pb( domains.RetrieveAuthorizationCodeRequest() ) @@ -12132,6 +12261,7 @@ def test_retrieve_authorization_code_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.AuthorizationCode() + post_with_metadata.return_value = domains.AuthorizationCode(), metadata client.retrieve_authorization_code( request, @@ -12143,6 +12273,7 @@ def test_retrieve_authorization_code_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_reset_authorization_code_rest_bad_request( @@ -12229,10 +12360,13 @@ def test_reset_authorization_code_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.DomainsRestInterceptor, "post_reset_authorization_code" ) as post, mock.patch.object( + transports.DomainsRestInterceptor, "post_reset_authorization_code_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.DomainsRestInterceptor, "pre_reset_authorization_code" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = domains.ResetAuthorizationCodeRequest.pb( domains.ResetAuthorizationCodeRequest() ) @@ -12256,6 +12390,7 @@ def test_reset_authorization_code_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = domains.AuthorizationCode() + post_with_metadata.return_value = domains.AuthorizationCode(), metadata client.reset_authorization_code( request, @@ -12267,6 +12402,7 @@ def test_reset_authorization_code_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest(): diff --git a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer/gapic_version.py b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer/gapic_version.py index 35c9af734238..558c8aab67c5 100644 --- a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer/gapic_version.py +++ b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.15" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/gapic_version.py b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/gapic_version.py index 35c9af734238..558c8aab67c5 100644 --- a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/gapic_version.py +++ b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.5.15" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/services/edge_container/client.py b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/services/edge_container/client.py index c186937568dc..6d60b37b82ba 100644 --- a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/services/edge_container/client.py +++ b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/services/edge_container/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -610,6 +612,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -3283,16 +3312,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -3338,16 +3371,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -3504,16 +3541,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -3559,16 +3600,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/services/edge_container/transports/rest.py b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/services/edge_container/transports/rest.py index ec50899ad0b0..33b5e96c3bd2 100644 --- a/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/services/edge_container/transports/rest.py +++ b/packages/google-cloud-edgecontainer/google/cloud/edgecontainer_v1/services/edge_container/transports/rest.py @@ -253,12 +253,35 @@ def post_create_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_create_cluster` interceptor runs + before the `post_create_cluster_with_metadata` interceptor. """ return response + def post_create_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_create_cluster_with_metadata` + interceptor in new development instead of the `post_create_cluster` interceptor. + When both interceptors are used, this `post_create_cluster_with_metadata` interceptor runs after the + `post_create_cluster` interceptor. The (possibly modified) response returned by + `post_create_cluster` will be passed to + `post_create_cluster_with_metadata`. + """ + return response, metadata + def pre_create_node_pool( self, request: service.CreateNodePoolRequest, @@ -276,12 +299,35 @@ def post_create_node_pool( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_node_pool - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_node_pool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_create_node_pool` interceptor runs + before the `post_create_node_pool_with_metadata` interceptor. """ return response + def post_create_node_pool_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_node_pool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_create_node_pool_with_metadata` + interceptor in new development instead of the `post_create_node_pool` interceptor. + When both interceptors are used, this `post_create_node_pool_with_metadata` interceptor runs after the + `post_create_node_pool` interceptor. The (possibly modified) response returned by + `post_create_node_pool` will be passed to + `post_create_node_pool_with_metadata`. + """ + return response, metadata + def pre_create_vpn_connection( self, request: service.CreateVpnConnectionRequest, @@ -301,12 +347,35 @@ def post_create_vpn_connection( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_vpn_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_vpn_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_create_vpn_connection` interceptor runs + before the `post_create_vpn_connection_with_metadata` interceptor. """ return response + def post_create_vpn_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_vpn_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_create_vpn_connection_with_metadata` + interceptor in new development instead of the `post_create_vpn_connection` interceptor. + When both interceptors are used, this `post_create_vpn_connection_with_metadata` interceptor runs after the + `post_create_vpn_connection` interceptor. The (possibly modified) response returned by + `post_create_vpn_connection` will be passed to + `post_create_vpn_connection_with_metadata`. + """ + return response, metadata + def pre_delete_cluster( self, request: service.DeleteClusterRequest, @@ -324,12 +393,35 @@ def post_delete_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_delete_cluster` interceptor runs + before the `post_delete_cluster_with_metadata` interceptor. """ return response + def post_delete_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_delete_cluster_with_metadata` + interceptor in new development instead of the `post_delete_cluster` interceptor. + When both interceptors are used, this `post_delete_cluster_with_metadata` interceptor runs after the + `post_delete_cluster` interceptor. The (possibly modified) response returned by + `post_delete_cluster` will be passed to + `post_delete_cluster_with_metadata`. + """ + return response, metadata + def pre_delete_node_pool( self, request: service.DeleteNodePoolRequest, @@ -347,12 +439,35 @@ def post_delete_node_pool( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_node_pool - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_node_pool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_delete_node_pool` interceptor runs + before the `post_delete_node_pool_with_metadata` interceptor. """ return response + def post_delete_node_pool_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_node_pool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_delete_node_pool_with_metadata` + interceptor in new development instead of the `post_delete_node_pool` interceptor. + When both interceptors are used, this `post_delete_node_pool_with_metadata` interceptor runs after the + `post_delete_node_pool` interceptor. The (possibly modified) response returned by + `post_delete_node_pool` will be passed to + `post_delete_node_pool_with_metadata`. + """ + return response, metadata + def pre_delete_vpn_connection( self, request: service.DeleteVpnConnectionRequest, @@ -372,12 +487,35 @@ def post_delete_vpn_connection( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_vpn_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_vpn_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_delete_vpn_connection` interceptor runs + before the `post_delete_vpn_connection_with_metadata` interceptor. """ return response + def post_delete_vpn_connection_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_vpn_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_delete_vpn_connection_with_metadata` + interceptor in new development instead of the `post_delete_vpn_connection` interceptor. + When both interceptors are used, this `post_delete_vpn_connection_with_metadata` interceptor runs after the + `post_delete_vpn_connection` interceptor. The (possibly modified) response returned by + `post_delete_vpn_connection` will be passed to + `post_delete_vpn_connection_with_metadata`. + """ + return response, metadata + def pre_generate_access_token( self, request: service.GenerateAccessTokenRequest, @@ -397,12 +535,37 @@ def post_generate_access_token( ) -> service.GenerateAccessTokenResponse: """Post-rpc interceptor for generate_access_token - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_generate_access_token_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_generate_access_token` interceptor runs + before the `post_generate_access_token_with_metadata` interceptor. """ return response + def post_generate_access_token_with_metadata( + self, + response: service.GenerateAccessTokenResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.GenerateAccessTokenResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for generate_access_token + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_generate_access_token_with_metadata` + interceptor in new development instead of the `post_generate_access_token` interceptor. + When both interceptors are used, this `post_generate_access_token_with_metadata` interceptor runs after the + `post_generate_access_token` interceptor. The (possibly modified) response returned by + `post_generate_access_token` will be passed to + `post_generate_access_token_with_metadata`. + """ + return response, metadata + def pre_generate_offline_credential( self, request: service.GenerateOfflineCredentialRequest, @@ -423,12 +586,38 @@ def post_generate_offline_credential( ) -> service.GenerateOfflineCredentialResponse: """Post-rpc interceptor for generate_offline_credential - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_generate_offline_credential_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_generate_offline_credential` interceptor runs + before the `post_generate_offline_credential_with_metadata` interceptor. """ return response + def post_generate_offline_credential_with_metadata( + self, + response: service.GenerateOfflineCredentialResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.GenerateOfflineCredentialResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for generate_offline_credential + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_generate_offline_credential_with_metadata` + interceptor in new development instead of the `post_generate_offline_credential` interceptor. + When both interceptors are used, this `post_generate_offline_credential_with_metadata` interceptor runs after the + `post_generate_offline_credential` interceptor. The (possibly modified) response returned by + `post_generate_offline_credential` will be passed to + `post_generate_offline_credential_with_metadata`. + """ + return response, metadata + def pre_get_cluster( self, request: service.GetClusterRequest, @@ -444,12 +633,35 @@ def pre_get_cluster( def post_get_cluster(self, response: resources.Cluster) -> resources.Cluster: """Post-rpc interceptor for get_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_get_cluster` interceptor runs + before the `post_get_cluster_with_metadata` interceptor. """ return response + def post_get_cluster_with_metadata( + self, + response: resources.Cluster, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.Cluster, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_get_cluster_with_metadata` + interceptor in new development instead of the `post_get_cluster` interceptor. + When both interceptors are used, this `post_get_cluster_with_metadata` interceptor runs after the + `post_get_cluster` interceptor. The (possibly modified) response returned by + `post_get_cluster` will be passed to + `post_get_cluster_with_metadata`. + """ + return response, metadata + def pre_get_machine( self, request: service.GetMachineRequest, @@ -465,12 +677,35 @@ def pre_get_machine( def post_get_machine(self, response: resources.Machine) -> resources.Machine: """Post-rpc interceptor for get_machine - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_machine_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_get_machine` interceptor runs + before the `post_get_machine_with_metadata` interceptor. """ return response + def post_get_machine_with_metadata( + self, + response: resources.Machine, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.Machine, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_machine + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_get_machine_with_metadata` + interceptor in new development instead of the `post_get_machine` interceptor. + When both interceptors are used, this `post_get_machine_with_metadata` interceptor runs after the + `post_get_machine` interceptor. The (possibly modified) response returned by + `post_get_machine` will be passed to + `post_get_machine_with_metadata`. + """ + return response, metadata + def pre_get_node_pool( self, request: service.GetNodePoolRequest, @@ -486,12 +721,35 @@ def pre_get_node_pool( def post_get_node_pool(self, response: resources.NodePool) -> resources.NodePool: """Post-rpc interceptor for get_node_pool - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_node_pool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_get_node_pool` interceptor runs + before the `post_get_node_pool_with_metadata` interceptor. """ return response + def post_get_node_pool_with_metadata( + self, + response: resources.NodePool, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.NodePool, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_node_pool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_get_node_pool_with_metadata` + interceptor in new development instead of the `post_get_node_pool` interceptor. + When both interceptors are used, this `post_get_node_pool_with_metadata` interceptor runs after the + `post_get_node_pool` interceptor. The (possibly modified) response returned by + `post_get_node_pool` will be passed to + `post_get_node_pool_with_metadata`. + """ + return response, metadata + def pre_get_server_config( self, request: service.GetServerConfigRequest, @@ -509,12 +767,35 @@ def post_get_server_config( ) -> resources.ServerConfig: """Post-rpc interceptor for get_server_config - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_server_config_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_get_server_config` interceptor runs + before the `post_get_server_config_with_metadata` interceptor. """ return response + def post_get_server_config_with_metadata( + self, + response: resources.ServerConfig, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.ServerConfig, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_server_config + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_get_server_config_with_metadata` + interceptor in new development instead of the `post_get_server_config` interceptor. + When both interceptors are used, this `post_get_server_config_with_metadata` interceptor runs after the + `post_get_server_config` interceptor. The (possibly modified) response returned by + `post_get_server_config` will be passed to + `post_get_server_config_with_metadata`. + """ + return response, metadata + def pre_get_vpn_connection( self, request: service.GetVpnConnectionRequest, @@ -534,12 +815,35 @@ def post_get_vpn_connection( ) -> resources.VpnConnection: """Post-rpc interceptor for get_vpn_connection - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_vpn_connection_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_get_vpn_connection` interceptor runs + before the `post_get_vpn_connection_with_metadata` interceptor. """ return response + def post_get_vpn_connection_with_metadata( + self, + response: resources.VpnConnection, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.VpnConnection, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_vpn_connection + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_get_vpn_connection_with_metadata` + interceptor in new development instead of the `post_get_vpn_connection` interceptor. + When both interceptors are used, this `post_get_vpn_connection_with_metadata` interceptor runs after the + `post_get_vpn_connection` interceptor. The (possibly modified) response returned by + `post_get_vpn_connection` will be passed to + `post_get_vpn_connection_with_metadata`. + """ + return response, metadata + def pre_list_clusters( self, request: service.ListClustersRequest, @@ -557,12 +861,35 @@ def post_list_clusters( ) -> service.ListClustersResponse: """Post-rpc interceptor for list_clusters - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_clusters_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_list_clusters` interceptor runs + before the `post_list_clusters_with_metadata` interceptor. """ return response + def post_list_clusters_with_metadata( + self, + response: service.ListClustersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.ListClustersResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_clusters + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_list_clusters_with_metadata` + interceptor in new development instead of the `post_list_clusters` interceptor. + When both interceptors are used, this `post_list_clusters_with_metadata` interceptor runs after the + `post_list_clusters` interceptor. The (possibly modified) response returned by + `post_list_clusters` will be passed to + `post_list_clusters_with_metadata`. + """ + return response, metadata + def pre_list_machines( self, request: service.ListMachinesRequest, @@ -580,12 +907,35 @@ def post_list_machines( ) -> service.ListMachinesResponse: """Post-rpc interceptor for list_machines - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_machines_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_list_machines` interceptor runs + before the `post_list_machines_with_metadata` interceptor. """ return response + def post_list_machines_with_metadata( + self, + response: service.ListMachinesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.ListMachinesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_machines + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_list_machines_with_metadata` + interceptor in new development instead of the `post_list_machines` interceptor. + When both interceptors are used, this `post_list_machines_with_metadata` interceptor runs after the + `post_list_machines` interceptor. The (possibly modified) response returned by + `post_list_machines` will be passed to + `post_list_machines_with_metadata`. + """ + return response, metadata + def pre_list_node_pools( self, request: service.ListNodePoolsRequest, @@ -603,12 +953,35 @@ def post_list_node_pools( ) -> service.ListNodePoolsResponse: """Post-rpc interceptor for list_node_pools - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_node_pools_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_list_node_pools` interceptor runs + before the `post_list_node_pools_with_metadata` interceptor. """ return response + def post_list_node_pools_with_metadata( + self, + response: service.ListNodePoolsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.ListNodePoolsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_node_pools + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_list_node_pools_with_metadata` + interceptor in new development instead of the `post_list_node_pools` interceptor. + When both interceptors are used, this `post_list_node_pools_with_metadata` interceptor runs after the + `post_list_node_pools` interceptor. The (possibly modified) response returned by + `post_list_node_pools` will be passed to + `post_list_node_pools_with_metadata`. + """ + return response, metadata + def pre_list_vpn_connections( self, request: service.ListVpnConnectionsRequest, @@ -628,12 +1001,37 @@ def post_list_vpn_connections( ) -> service.ListVpnConnectionsResponse: """Post-rpc interceptor for list_vpn_connections - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_vpn_connections_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_list_vpn_connections` interceptor runs + before the `post_list_vpn_connections_with_metadata` interceptor. """ return response + def post_list_vpn_connections_with_metadata( + self, + response: service.ListVpnConnectionsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.ListVpnConnectionsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_vpn_connections + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_list_vpn_connections_with_metadata` + interceptor in new development instead of the `post_list_vpn_connections` interceptor. + When both interceptors are used, this `post_list_vpn_connections_with_metadata` interceptor runs after the + `post_list_vpn_connections` interceptor. The (possibly modified) response returned by + `post_list_vpn_connections` will be passed to + `post_list_vpn_connections_with_metadata`. + """ + return response, metadata + def pre_update_cluster( self, request: service.UpdateClusterRequest, @@ -651,12 +1049,35 @@ def post_update_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_update_cluster` interceptor runs + before the `post_update_cluster_with_metadata` interceptor. """ return response + def post_update_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_update_cluster_with_metadata` + interceptor in new development instead of the `post_update_cluster` interceptor. + When both interceptors are used, this `post_update_cluster_with_metadata` interceptor runs after the + `post_update_cluster` interceptor. The (possibly modified) response returned by + `post_update_cluster` will be passed to + `post_update_cluster_with_metadata`. + """ + return response, metadata + def pre_update_node_pool( self, request: service.UpdateNodePoolRequest, @@ -674,12 +1095,35 @@ def post_update_node_pool( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_node_pool - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_node_pool_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_update_node_pool` interceptor runs + before the `post_update_node_pool_with_metadata` interceptor. """ return response + def post_update_node_pool_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_node_pool + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_update_node_pool_with_metadata` + interceptor in new development instead of the `post_update_node_pool` interceptor. + When both interceptors are used, this `post_update_node_pool_with_metadata` interceptor runs after the + `post_update_node_pool` interceptor. The (possibly modified) response returned by + `post_update_node_pool` will be passed to + `post_update_node_pool_with_metadata`. + """ + return response, metadata + def pre_upgrade_cluster( self, request: service.UpgradeClusterRequest, @@ -697,12 +1141,35 @@ def post_upgrade_cluster( ) -> operations_pb2.Operation: """Post-rpc interceptor for upgrade_cluster - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_upgrade_cluster_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeContainer server but before - it is returned to user code. + it is returned to user code. This `post_upgrade_cluster` interceptor runs + before the `post_upgrade_cluster_with_metadata` interceptor. """ return response + def post_upgrade_cluster_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for upgrade_cluster + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeContainer server but before it is returned to user code. + + We recommend only using this `post_upgrade_cluster_with_metadata` + interceptor in new development instead of the `post_upgrade_cluster` interceptor. + When both interceptors are used, this `post_upgrade_cluster_with_metadata` interceptor runs after the + `post_upgrade_cluster` interceptor. The (possibly modified) response returned by + `post_upgrade_cluster` will be passed to + `post_upgrade_cluster_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -1115,6 +1582,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1264,6 +1735,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_node_pool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_node_pool_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1413,6 +1888,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_vpn_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_vpn_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1554,6 +2033,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1697,6 +2180,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_node_pool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_node_pool_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1840,6 +2327,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_vpn_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_vpn_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1983,6 +2474,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_generate_access_token(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_generate_access_token_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2132,6 +2627,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_generate_offline_credential(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_generate_offline_credential_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2280,6 +2779,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2427,6 +2930,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_machine(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_machine_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2572,6 +3079,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_node_pool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_node_pool_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2716,6 +3227,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_server_config(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_server_config_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2858,6 +3373,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_vpn_connection(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_vpn_connection_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2998,6 +3517,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_clusters(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_clusters_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3138,6 +3661,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_machines(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_machines_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3278,6 +3805,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_node_pools(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_node_pools_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3422,6 +3953,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_vpn_connections(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_vpn_connections_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3571,6 +4106,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3720,6 +4259,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_node_pool(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_node_pool_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3867,6 +4410,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_upgrade_cluster(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_upgrade_cluster_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-edgecontainer/samples/generated_samples/snippet_metadata_google.cloud.edgecontainer.v1.json b/packages/google-cloud-edgecontainer/samples/generated_samples/snippet_metadata_google.cloud.edgecontainer.v1.json index 06ba325e5cbe..272d5629e396 100644 --- a/packages/google-cloud-edgecontainer/samples/generated_samples/snippet_metadata_google.cloud.edgecontainer.v1.json +++ b/packages/google-cloud-edgecontainer/samples/generated_samples/snippet_metadata_google.cloud.edgecontainer.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-edgecontainer", - "version": "0.5.15" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-edgecontainer/tests/unit/gapic/edgecontainer_v1/test_edge_container.py b/packages/google-cloud-edgecontainer/tests/unit/gapic/edgecontainer_v1/test_edge_container.py index e136119c8b89..bd2f1a7d8c62 100644 --- a/packages/google-cloud-edgecontainer/tests/unit/gapic/edgecontainer_v1/test_edge_container.py +++ b/packages/google-cloud-edgecontainer/tests/unit/gapic/edgecontainer_v1/test_edge_container.py @@ -77,6 +77,13 @@ ) from google.cloud.edgecontainer_v1.types import resources, service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -331,6 +338,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EdgeContainerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EdgeContainerClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -13870,10 +13920,13 @@ def test_list_clusters_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_list_clusters" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_list_clusters_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_list_clusters" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListClustersRequest.pb(service.ListClustersRequest()) transcode.return_value = { "method": "post", @@ -13897,6 +13950,7 @@ def test_list_clusters_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListClustersResponse() + post_with_metadata.return_value = service.ListClustersResponse(), metadata client.list_clusters( request, @@ -13908,6 +13962,7 @@ def test_list_clusters_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_cluster_rest_bad_request(request_type=service.GetClusterRequest): @@ -14020,10 +14075,13 @@ def test_get_cluster_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_get_cluster" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_get_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_get_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetClusterRequest.pb(service.GetClusterRequest()) transcode.return_value = { "method": "post", @@ -14045,6 +14103,7 @@ def test_get_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.Cluster() + post_with_metadata.return_value = resources.Cluster(), metadata client.get_cluster( request, @@ -14056,6 +14115,7 @@ def test_get_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_cluster_rest_bad_request(request_type=service.CreateClusterRequest): @@ -14291,10 +14351,13 @@ def test_create_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeContainerRestInterceptor, "post_create_cluster" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_create_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_create_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.CreateClusterRequest.pb(service.CreateClusterRequest()) transcode.return_value = { "method": "post", @@ -14316,6 +14379,7 @@ def test_create_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_cluster( request, @@ -14327,6 +14391,7 @@ def test_create_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_cluster_rest_bad_request(request_type=service.UpdateClusterRequest): @@ -14566,10 +14631,13 @@ def test_update_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeContainerRestInterceptor, "post_update_cluster" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_update_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_update_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.UpdateClusterRequest.pb(service.UpdateClusterRequest()) transcode.return_value = { "method": "post", @@ -14591,6 +14659,7 @@ def test_update_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_cluster( request, @@ -14602,6 +14671,7 @@ def test_update_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_upgrade_cluster_rest_bad_request(request_type=service.UpgradeClusterRequest): @@ -14680,10 +14750,13 @@ def test_upgrade_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeContainerRestInterceptor, "post_upgrade_cluster" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_upgrade_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_upgrade_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.UpgradeClusterRequest.pb(service.UpgradeClusterRequest()) transcode.return_value = { "method": "post", @@ -14705,6 +14778,7 @@ def test_upgrade_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.upgrade_cluster( request, @@ -14716,6 +14790,7 @@ def test_upgrade_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_cluster_rest_bad_request(request_type=service.DeleteClusterRequest): @@ -14794,10 +14869,13 @@ def test_delete_cluster_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeContainerRestInterceptor, "post_delete_cluster" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_delete_cluster_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_delete_cluster" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DeleteClusterRequest.pb(service.DeleteClusterRequest()) transcode.return_value = { "method": "post", @@ -14819,6 +14897,7 @@ def test_delete_cluster_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_cluster( request, @@ -14830,6 +14909,7 @@ def test_delete_cluster_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_generate_access_token_rest_bad_request( @@ -14914,10 +14994,14 @@ def test_generate_access_token_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_generate_access_token" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, + "post_generate_access_token_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_generate_access_token" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GenerateAccessTokenRequest.pb( service.GenerateAccessTokenRequest() ) @@ -14943,6 +15027,10 @@ def test_generate_access_token_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.GenerateAccessTokenResponse() + post_with_metadata.return_value = ( + service.GenerateAccessTokenResponse(), + metadata, + ) client.generate_access_token( request, @@ -14954,6 +15042,7 @@ def test_generate_access_token_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_generate_offline_credential_rest_bad_request( @@ -15042,10 +15131,14 @@ def test_generate_offline_credential_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_generate_offline_credential" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, + "post_generate_offline_credential_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_generate_offline_credential" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GenerateOfflineCredentialRequest.pb( service.GenerateOfflineCredentialRequest() ) @@ -15071,6 +15164,10 @@ def test_generate_offline_credential_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.GenerateOfflineCredentialResponse() + post_with_metadata.return_value = ( + service.GenerateOfflineCredentialResponse(), + metadata, + ) client.generate_offline_credential( request, @@ -15082,6 +15179,7 @@ def test_generate_offline_credential_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_node_pools_rest_bad_request(request_type=service.ListNodePoolsRequest): @@ -15166,10 +15264,13 @@ def test_list_node_pools_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_list_node_pools" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_list_node_pools_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_list_node_pools" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListNodePoolsRequest.pb(service.ListNodePoolsRequest()) transcode.return_value = { "method": "post", @@ -15193,6 +15294,7 @@ def test_list_node_pools_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListNodePoolsResponse() + post_with_metadata.return_value = service.ListNodePoolsResponse(), metadata client.list_node_pools( request, @@ -15204,6 +15306,7 @@ def test_list_node_pools_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_node_pool_rest_bad_request(request_type=service.GetNodePoolRequest): @@ -15298,10 +15401,13 @@ def test_get_node_pool_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_get_node_pool" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_get_node_pool_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_get_node_pool" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetNodePoolRequest.pb(service.GetNodePoolRequest()) transcode.return_value = { "method": "post", @@ -15323,6 +15429,7 @@ def test_get_node_pool_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.NodePool() + post_with_metadata.return_value = resources.NodePool(), metadata client.get_node_pool( request, @@ -15334,6 +15441,7 @@ def test_get_node_pool_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_node_pool_rest_bad_request(request_type=service.CreateNodePoolRequest): @@ -15509,10 +15617,13 @@ def test_create_node_pool_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeContainerRestInterceptor, "post_create_node_pool" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_create_node_pool_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_create_node_pool" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.CreateNodePoolRequest.pb(service.CreateNodePoolRequest()) transcode.return_value = { "method": "post", @@ -15534,6 +15645,7 @@ def test_create_node_pool_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_node_pool( request, @@ -15545,6 +15657,7 @@ def test_create_node_pool_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_node_pool_rest_bad_request(request_type=service.UpdateNodePoolRequest): @@ -15728,10 +15841,13 @@ def test_update_node_pool_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeContainerRestInterceptor, "post_update_node_pool" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_update_node_pool_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_update_node_pool" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.UpdateNodePoolRequest.pb(service.UpdateNodePoolRequest()) transcode.return_value = { "method": "post", @@ -15753,6 +15869,7 @@ def test_update_node_pool_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_node_pool( request, @@ -15764,6 +15881,7 @@ def test_update_node_pool_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_node_pool_rest_bad_request(request_type=service.DeleteNodePoolRequest): @@ -15846,10 +15964,13 @@ def test_delete_node_pool_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeContainerRestInterceptor, "post_delete_node_pool" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_delete_node_pool_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_delete_node_pool" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DeleteNodePoolRequest.pb(service.DeleteNodePoolRequest()) transcode.return_value = { "method": "post", @@ -15871,6 +15992,7 @@ def test_delete_node_pool_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_node_pool( request, @@ -15882,6 +16004,7 @@ def test_delete_node_pool_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_machines_rest_bad_request(request_type=service.ListMachinesRequest): @@ -15966,10 +16089,13 @@ def test_list_machines_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_list_machines" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_list_machines_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_list_machines" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListMachinesRequest.pb(service.ListMachinesRequest()) transcode.return_value = { "method": "post", @@ -15993,6 +16119,7 @@ def test_list_machines_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListMachinesResponse() + post_with_metadata.return_value = service.ListMachinesResponse(), metadata client.list_machines( request, @@ -16004,6 +16131,7 @@ def test_list_machines_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_machine_rest_bad_request(request_type=service.GetMachineRequest): @@ -16094,10 +16222,13 @@ def test_get_machine_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_get_machine" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_get_machine_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_get_machine" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetMachineRequest.pb(service.GetMachineRequest()) transcode.return_value = { "method": "post", @@ -16119,6 +16250,7 @@ def test_get_machine_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.Machine() + post_with_metadata.return_value = resources.Machine(), metadata client.get_machine( request, @@ -16130,6 +16262,7 @@ def test_get_machine_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_vpn_connections_rest_bad_request( @@ -16216,10 +16349,14 @@ def test_list_vpn_connections_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_list_vpn_connections" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, + "post_list_vpn_connections_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_list_vpn_connections" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListVpnConnectionsRequest.pb( service.ListVpnConnectionsRequest() ) @@ -16245,6 +16382,7 @@ def test_list_vpn_connections_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListVpnConnectionsResponse() + post_with_metadata.return_value = service.ListVpnConnectionsResponse(), metadata client.list_vpn_connections( request, @@ -16256,6 +16394,7 @@ def test_list_vpn_connections_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_vpn_connection_rest_bad_request( @@ -16352,10 +16491,13 @@ def test_get_vpn_connection_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_get_vpn_connection" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_get_vpn_connection_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_get_vpn_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetVpnConnectionRequest.pb( service.GetVpnConnectionRequest() ) @@ -16379,6 +16521,7 @@ def test_get_vpn_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.VpnConnection() + post_with_metadata.return_value = resources.VpnConnection(), metadata client.get_vpn_connection( request, @@ -16390,6 +16533,7 @@ def test_get_vpn_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_vpn_connection_rest_bad_request( @@ -16559,10 +16703,14 @@ def test_create_vpn_connection_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeContainerRestInterceptor, "post_create_vpn_connection" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, + "post_create_vpn_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_create_vpn_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.CreateVpnConnectionRequest.pb( service.CreateVpnConnectionRequest() ) @@ -16586,6 +16734,7 @@ def test_create_vpn_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_vpn_connection( request, @@ -16597,6 +16746,7 @@ def test_create_vpn_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_vpn_connection_rest_bad_request( @@ -16677,10 +16827,14 @@ def test_delete_vpn_connection_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeContainerRestInterceptor, "post_delete_vpn_connection" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, + "post_delete_vpn_connection_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_delete_vpn_connection" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DeleteVpnConnectionRequest.pb( service.DeleteVpnConnectionRequest() ) @@ -16704,6 +16858,7 @@ def test_delete_vpn_connection_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_vpn_connection( request, @@ -16715,6 +16870,7 @@ def test_delete_vpn_connection_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_server_config_rest_bad_request( @@ -16799,10 +16955,13 @@ def test_get_server_config_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeContainerRestInterceptor, "post_get_server_config" ) as post, mock.patch.object( + transports.EdgeContainerRestInterceptor, "post_get_server_config_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeContainerRestInterceptor, "pre_get_server_config" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetServerConfigRequest.pb(service.GetServerConfigRequest()) transcode.return_value = { "method": "post", @@ -16824,6 +16983,7 @@ def test_get_server_config_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.ServerConfig() + post_with_metadata.return_value = resources.ServerConfig(), metadata client.get_server_config( request, @@ -16835,6 +16995,7 @@ def test_get_server_config_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork/gapic_version.py b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork/gapic_version.py index 7a4d810a47da..558c8aab67c5 100644 --- a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork/gapic_version.py +++ b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.14" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/gapic_version.py b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/gapic_version.py index 7a4d810a47da..558c8aab67c5 100644 --- a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/gapic_version.py +++ b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.1.14" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/services/edge_network/client.py b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/services/edge_network/client.py index ed6c052c1936..037270a0f72c 100644 --- a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/services/edge_network/client.py +++ b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/services/edge_network/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -615,6 +617,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. @@ -3981,16 +4010,20 @@ def list_operations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def get_operation( self, @@ -4036,16 +4069,20 @@ def get_operation( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def delete_operation( self, @@ -4202,16 +4239,20 @@ def get_location( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e def list_locations( self, @@ -4257,16 +4298,20 @@ def list_locations( # Validate the universe domain. self._validate_universe_domain() - # Send the request. - response = rpc( - request, - retry=retry, - timeout=timeout, - metadata=metadata, - ) + try: + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) - # Done; return the response. - return response + # Done; return the response. + return response + except core_exceptions.GoogleAPICallError as e: + self._add_cred_info_for_auth_errors(e) + raise e DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo( diff --git a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/services/edge_network/transports/rest.py b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/services/edge_network/transports/rest.py index 15271f590f44..888d1c7e9c82 100644 --- a/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/services/edge_network/transports/rest.py +++ b/packages/google-cloud-edgenetwork/google/cloud/edgenetwork_v1/services/edge_network/transports/rest.py @@ -304,12 +304,35 @@ def post_create_interconnect_attachment( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_interconnect_attachment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_interconnect_attachment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_create_interconnect_attachment` interceptor runs + before the `post_create_interconnect_attachment_with_metadata` interceptor. """ return response + def post_create_interconnect_attachment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_interconnect_attachment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_create_interconnect_attachment_with_metadata` + interceptor in new development instead of the `post_create_interconnect_attachment` interceptor. + When both interceptors are used, this `post_create_interconnect_attachment_with_metadata` interceptor runs after the + `post_create_interconnect_attachment` interceptor. The (possibly modified) response returned by + `post_create_interconnect_attachment` will be passed to + `post_create_interconnect_attachment_with_metadata`. + """ + return response, metadata + def pre_create_network( self, request: service.CreateNetworkRequest, @@ -327,12 +350,35 @@ def post_create_network( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_network - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_network_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_create_network` interceptor runs + before the `post_create_network_with_metadata` interceptor. """ return response + def post_create_network_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_network + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_create_network_with_metadata` + interceptor in new development instead of the `post_create_network` interceptor. + When both interceptors are used, this `post_create_network_with_metadata` interceptor runs after the + `post_create_network` interceptor. The (possibly modified) response returned by + `post_create_network` will be passed to + `post_create_network_with_metadata`. + """ + return response, metadata + def pre_create_router( self, request: service.CreateRouterRequest, @@ -350,12 +396,35 @@ def post_create_router( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_router - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_router_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_create_router` interceptor runs + before the `post_create_router_with_metadata` interceptor. """ return response + def post_create_router_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_router + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_create_router_with_metadata` + interceptor in new development instead of the `post_create_router` interceptor. + When both interceptors are used, this `post_create_router_with_metadata` interceptor runs after the + `post_create_router` interceptor. The (possibly modified) response returned by + `post_create_router` will be passed to + `post_create_router_with_metadata`. + """ + return response, metadata + def pre_create_subnet( self, request: service.CreateSubnetRequest, @@ -373,12 +442,35 @@ def post_create_subnet( ) -> operations_pb2.Operation: """Post-rpc interceptor for create_subnet - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_subnet_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_create_subnet` interceptor runs + before the `post_create_subnet_with_metadata` interceptor. """ return response + def post_create_subnet_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for create_subnet + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_create_subnet_with_metadata` + interceptor in new development instead of the `post_create_subnet` interceptor. + When both interceptors are used, this `post_create_subnet_with_metadata` interceptor runs after the + `post_create_subnet` interceptor. The (possibly modified) response returned by + `post_create_subnet` will be passed to + `post_create_subnet_with_metadata`. + """ + return response, metadata + def pre_delete_interconnect_attachment( self, request: service.DeleteInterconnectAttachmentRequest, @@ -399,12 +491,35 @@ def post_delete_interconnect_attachment( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_interconnect_attachment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_interconnect_attachment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_delete_interconnect_attachment` interceptor runs + before the `post_delete_interconnect_attachment_with_metadata` interceptor. """ return response + def post_delete_interconnect_attachment_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_interconnect_attachment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_delete_interconnect_attachment_with_metadata` + interceptor in new development instead of the `post_delete_interconnect_attachment` interceptor. + When both interceptors are used, this `post_delete_interconnect_attachment_with_metadata` interceptor runs after the + `post_delete_interconnect_attachment` interceptor. The (possibly modified) response returned by + `post_delete_interconnect_attachment` will be passed to + `post_delete_interconnect_attachment_with_metadata`. + """ + return response, metadata + def pre_delete_network( self, request: service.DeleteNetworkRequest, @@ -422,12 +537,35 @@ def post_delete_network( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_network - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_network_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_delete_network` interceptor runs + before the `post_delete_network_with_metadata` interceptor. """ return response + def post_delete_network_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_network + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_delete_network_with_metadata` + interceptor in new development instead of the `post_delete_network` interceptor. + When both interceptors are used, this `post_delete_network_with_metadata` interceptor runs after the + `post_delete_network` interceptor. The (possibly modified) response returned by + `post_delete_network` will be passed to + `post_delete_network_with_metadata`. + """ + return response, metadata + def pre_delete_router( self, request: service.DeleteRouterRequest, @@ -445,12 +583,35 @@ def post_delete_router( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_router - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_router_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_delete_router` interceptor runs + before the `post_delete_router_with_metadata` interceptor. """ return response + def post_delete_router_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_router + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_delete_router_with_metadata` + interceptor in new development instead of the `post_delete_router` interceptor. + When both interceptors are used, this `post_delete_router_with_metadata` interceptor runs after the + `post_delete_router` interceptor. The (possibly modified) response returned by + `post_delete_router` will be passed to + `post_delete_router_with_metadata`. + """ + return response, metadata + def pre_delete_subnet( self, request: service.DeleteSubnetRequest, @@ -468,12 +629,35 @@ def post_delete_subnet( ) -> operations_pb2.Operation: """Post-rpc interceptor for delete_subnet - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_delete_subnet_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_delete_subnet` interceptor runs + before the `post_delete_subnet_with_metadata` interceptor. """ return response + def post_delete_subnet_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for delete_subnet + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_delete_subnet_with_metadata` + interceptor in new development instead of the `post_delete_subnet` interceptor. + When both interceptors are used, this `post_delete_subnet_with_metadata` interceptor runs after the + `post_delete_subnet` interceptor. The (possibly modified) response returned by + `post_delete_subnet` will be passed to + `post_delete_subnet_with_metadata`. + """ + return response, metadata + def pre_diagnose_interconnect( self, request: service.DiagnoseInterconnectRequest, @@ -493,12 +677,37 @@ def post_diagnose_interconnect( ) -> service.DiagnoseInterconnectResponse: """Post-rpc interceptor for diagnose_interconnect - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_diagnose_interconnect_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_diagnose_interconnect` interceptor runs + before the `post_diagnose_interconnect_with_metadata` interceptor. """ return response + def post_diagnose_interconnect_with_metadata( + self, + response: service.DiagnoseInterconnectResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.DiagnoseInterconnectResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for diagnose_interconnect + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_diagnose_interconnect_with_metadata` + interceptor in new development instead of the `post_diagnose_interconnect` interceptor. + When both interceptors are used, this `post_diagnose_interconnect_with_metadata` interceptor runs after the + `post_diagnose_interconnect` interceptor. The (possibly modified) response returned by + `post_diagnose_interconnect` will be passed to + `post_diagnose_interconnect_with_metadata`. + """ + return response, metadata + def pre_diagnose_network( self, request: service.DiagnoseNetworkRequest, @@ -516,12 +725,37 @@ def post_diagnose_network( ) -> service.DiagnoseNetworkResponse: """Post-rpc interceptor for diagnose_network - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_diagnose_network_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_diagnose_network` interceptor runs + before the `post_diagnose_network_with_metadata` interceptor. """ return response + def post_diagnose_network_with_metadata( + self, + response: service.DiagnoseNetworkResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.DiagnoseNetworkResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for diagnose_network + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_diagnose_network_with_metadata` + interceptor in new development instead of the `post_diagnose_network` interceptor. + When both interceptors are used, this `post_diagnose_network_with_metadata` interceptor runs after the + `post_diagnose_network` interceptor. The (possibly modified) response returned by + `post_diagnose_network` will be passed to + `post_diagnose_network_with_metadata`. + """ + return response, metadata + def pre_diagnose_router( self, request: service.DiagnoseRouterRequest, @@ -539,12 +773,35 @@ def post_diagnose_router( ) -> service.DiagnoseRouterResponse: """Post-rpc interceptor for diagnose_router - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_diagnose_router_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_diagnose_router` interceptor runs + before the `post_diagnose_router_with_metadata` interceptor. """ return response + def post_diagnose_router_with_metadata( + self, + response: service.DiagnoseRouterResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.DiagnoseRouterResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for diagnose_router + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_diagnose_router_with_metadata` + interceptor in new development instead of the `post_diagnose_router` interceptor. + When both interceptors are used, this `post_diagnose_router_with_metadata` interceptor runs after the + `post_diagnose_router` interceptor. The (possibly modified) response returned by + `post_diagnose_router` will be passed to + `post_diagnose_router_with_metadata`. + """ + return response, metadata + def pre_get_interconnect( self, request: service.GetInterconnectRequest, @@ -562,12 +819,35 @@ def post_get_interconnect( ) -> resources.Interconnect: """Post-rpc interceptor for get_interconnect - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_interconnect_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_get_interconnect` interceptor runs + before the `post_get_interconnect_with_metadata` interceptor. """ return response + def post_get_interconnect_with_metadata( + self, + response: resources.Interconnect, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.Interconnect, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_interconnect + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_get_interconnect_with_metadata` + interceptor in new development instead of the `post_get_interconnect` interceptor. + When both interceptors are used, this `post_get_interconnect_with_metadata` interceptor runs after the + `post_get_interconnect` interceptor. The (possibly modified) response returned by + `post_get_interconnect` will be passed to + `post_get_interconnect_with_metadata`. + """ + return response, metadata + def pre_get_interconnect_attachment( self, request: service.GetInterconnectAttachmentRequest, @@ -588,12 +868,37 @@ def post_get_interconnect_attachment( ) -> resources.InterconnectAttachment: """Post-rpc interceptor for get_interconnect_attachment - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_interconnect_attachment_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_get_interconnect_attachment` interceptor runs + before the `post_get_interconnect_attachment_with_metadata` interceptor. """ return response + def post_get_interconnect_attachment_with_metadata( + self, + response: resources.InterconnectAttachment, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + resources.InterconnectAttachment, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_interconnect_attachment + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_get_interconnect_attachment_with_metadata` + interceptor in new development instead of the `post_get_interconnect_attachment` interceptor. + When both interceptors are used, this `post_get_interconnect_attachment_with_metadata` interceptor runs after the + `post_get_interconnect_attachment` interceptor. The (possibly modified) response returned by + `post_get_interconnect_attachment` will be passed to + `post_get_interconnect_attachment_with_metadata`. + """ + return response, metadata + def pre_get_network( self, request: service.GetNetworkRequest, @@ -609,12 +914,35 @@ def pre_get_network( def post_get_network(self, response: resources.Network) -> resources.Network: """Post-rpc interceptor for get_network - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_network_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_get_network` interceptor runs + before the `post_get_network_with_metadata` interceptor. """ return response + def post_get_network_with_metadata( + self, + response: resources.Network, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.Network, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_network + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_get_network_with_metadata` + interceptor in new development instead of the `post_get_network` interceptor. + When both interceptors are used, this `post_get_network_with_metadata` interceptor runs after the + `post_get_network` interceptor. The (possibly modified) response returned by + `post_get_network` will be passed to + `post_get_network_with_metadata`. + """ + return response, metadata + def pre_get_router( self, request: service.GetRouterRequest, @@ -630,12 +958,35 @@ def pre_get_router( def post_get_router(self, response: resources.Router) -> resources.Router: """Post-rpc interceptor for get_router - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_router_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_get_router` interceptor runs + before the `post_get_router_with_metadata` interceptor. """ return response + def post_get_router_with_metadata( + self, + response: resources.Router, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.Router, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_router + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_get_router_with_metadata` + interceptor in new development instead of the `post_get_router` interceptor. + When both interceptors are used, this `post_get_router_with_metadata` interceptor runs after the + `post_get_router` interceptor. The (possibly modified) response returned by + `post_get_router` will be passed to + `post_get_router_with_metadata`. + """ + return response, metadata + def pre_get_subnet( self, request: service.GetSubnetRequest, @@ -651,12 +1002,35 @@ def pre_get_subnet( def post_get_subnet(self, response: resources.Subnet) -> resources.Subnet: """Post-rpc interceptor for get_subnet - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_subnet_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_get_subnet` interceptor runs + before the `post_get_subnet_with_metadata` interceptor. """ return response + def post_get_subnet_with_metadata( + self, + response: resources.Subnet, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.Subnet, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_subnet + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_get_subnet_with_metadata` + interceptor in new development instead of the `post_get_subnet` interceptor. + When both interceptors are used, this `post_get_subnet_with_metadata` interceptor runs after the + `post_get_subnet` interceptor. The (possibly modified) response returned by + `post_get_subnet` will be passed to + `post_get_subnet_with_metadata`. + """ + return response, metadata + def pre_get_zone( self, request: service.GetZoneRequest, @@ -672,12 +1046,35 @@ def pre_get_zone( def post_get_zone(self, response: resources.Zone) -> resources.Zone: """Post-rpc interceptor for get_zone - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_zone_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_get_zone` interceptor runs + before the `post_get_zone_with_metadata` interceptor. """ return response + def post_get_zone_with_metadata( + self, + response: resources.Zone, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[resources.Zone, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for get_zone + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_get_zone_with_metadata` + interceptor in new development instead of the `post_get_zone` interceptor. + When both interceptors are used, this `post_get_zone_with_metadata` interceptor runs after the + `post_get_zone` interceptor. The (possibly modified) response returned by + `post_get_zone` will be passed to + `post_get_zone_with_metadata`. + """ + return response, metadata + def pre_initialize_zone( self, request: service.InitializeZoneRequest, @@ -695,12 +1092,35 @@ def post_initialize_zone( ) -> service.InitializeZoneResponse: """Post-rpc interceptor for initialize_zone - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_initialize_zone_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_initialize_zone` interceptor runs + before the `post_initialize_zone_with_metadata` interceptor. """ return response + def post_initialize_zone_with_metadata( + self, + response: service.InitializeZoneResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.InitializeZoneResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for initialize_zone + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_initialize_zone_with_metadata` + interceptor in new development instead of the `post_initialize_zone` interceptor. + When both interceptors are used, this `post_initialize_zone_with_metadata` interceptor runs after the + `post_initialize_zone` interceptor. The (possibly modified) response returned by + `post_initialize_zone` will be passed to + `post_initialize_zone_with_metadata`. + """ + return response, metadata + def pre_list_interconnect_attachments( self, request: service.ListInterconnectAttachmentsRequest, @@ -721,12 +1141,38 @@ def post_list_interconnect_attachments( ) -> service.ListInterconnectAttachmentsResponse: """Post-rpc interceptor for list_interconnect_attachments - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_interconnect_attachments_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_list_interconnect_attachments` interceptor runs + before the `post_list_interconnect_attachments_with_metadata` interceptor. """ return response + def post_list_interconnect_attachments_with_metadata( + self, + response: service.ListInterconnectAttachmentsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.ListInterconnectAttachmentsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_interconnect_attachments + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_list_interconnect_attachments_with_metadata` + interceptor in new development instead of the `post_list_interconnect_attachments` interceptor. + When both interceptors are used, this `post_list_interconnect_attachments_with_metadata` interceptor runs after the + `post_list_interconnect_attachments` interceptor. The (possibly modified) response returned by + `post_list_interconnect_attachments` will be passed to + `post_list_interconnect_attachments_with_metadata`. + """ + return response, metadata + def pre_list_interconnects( self, request: service.ListInterconnectsRequest, @@ -746,12 +1192,37 @@ def post_list_interconnects( ) -> service.ListInterconnectsResponse: """Post-rpc interceptor for list_interconnects - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_interconnects_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_list_interconnects` interceptor runs + before the `post_list_interconnects_with_metadata` interceptor. """ return response + def post_list_interconnects_with_metadata( + self, + response: service.ListInterconnectsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.ListInterconnectsResponse, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for list_interconnects + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_list_interconnects_with_metadata` + interceptor in new development instead of the `post_list_interconnects` interceptor. + When both interceptors are used, this `post_list_interconnects_with_metadata` interceptor runs after the + `post_list_interconnects` interceptor. The (possibly modified) response returned by + `post_list_interconnects` will be passed to + `post_list_interconnects_with_metadata`. + """ + return response, metadata + def pre_list_networks( self, request: service.ListNetworksRequest, @@ -769,12 +1240,35 @@ def post_list_networks( ) -> service.ListNetworksResponse: """Post-rpc interceptor for list_networks - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_networks_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_list_networks` interceptor runs + before the `post_list_networks_with_metadata` interceptor. """ return response + def post_list_networks_with_metadata( + self, + response: service.ListNetworksResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.ListNetworksResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_networks + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_list_networks_with_metadata` + interceptor in new development instead of the `post_list_networks` interceptor. + When both interceptors are used, this `post_list_networks_with_metadata` interceptor runs after the + `post_list_networks` interceptor. The (possibly modified) response returned by + `post_list_networks` will be passed to + `post_list_networks_with_metadata`. + """ + return response, metadata + def pre_list_routers( self, request: service.ListRoutersRequest, @@ -792,12 +1286,35 @@ def post_list_routers( ) -> service.ListRoutersResponse: """Post-rpc interceptor for list_routers - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_routers_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_list_routers` interceptor runs + before the `post_list_routers_with_metadata` interceptor. """ return response + def post_list_routers_with_metadata( + self, + response: service.ListRoutersResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.ListRoutersResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_routers + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_list_routers_with_metadata` + interceptor in new development instead of the `post_list_routers` interceptor. + When both interceptors are used, this `post_list_routers_with_metadata` interceptor runs after the + `post_list_routers` interceptor. The (possibly modified) response returned by + `post_list_routers` will be passed to + `post_list_routers_with_metadata`. + """ + return response, metadata + def pre_list_subnets( self, request: service.ListSubnetsRequest, @@ -815,12 +1332,35 @@ def post_list_subnets( ) -> service.ListSubnetsResponse: """Post-rpc interceptor for list_subnets - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_subnets_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_list_subnets` interceptor runs + before the `post_list_subnets_with_metadata` interceptor. """ return response + def post_list_subnets_with_metadata( + self, + response: service.ListSubnetsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.ListSubnetsResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_subnets + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_list_subnets_with_metadata` + interceptor in new development instead of the `post_list_subnets` interceptor. + When both interceptors are used, this `post_list_subnets_with_metadata` interceptor runs after the + `post_list_subnets` interceptor. The (possibly modified) response returned by + `post_list_subnets` will be passed to + `post_list_subnets_with_metadata`. + """ + return response, metadata + def pre_list_zones( self, request: service.ListZonesRequest, @@ -838,12 +1378,35 @@ def post_list_zones( ) -> service.ListZonesResponse: """Post-rpc interceptor for list_zones - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_zones_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_list_zones` interceptor runs + before the `post_list_zones_with_metadata` interceptor. """ return response + def post_list_zones_with_metadata( + self, + response: service.ListZonesResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.ListZonesResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for list_zones + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_list_zones_with_metadata` + interceptor in new development instead of the `post_list_zones` interceptor. + When both interceptors are used, this `post_list_zones_with_metadata` interceptor runs after the + `post_list_zones` interceptor. The (possibly modified) response returned by + `post_list_zones` will be passed to + `post_list_zones_with_metadata`. + """ + return response, metadata + def pre_update_router( self, request: service.UpdateRouterRequest, @@ -861,12 +1424,35 @@ def post_update_router( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_router - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_router_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_update_router` interceptor runs + before the `post_update_router_with_metadata` interceptor. """ return response + def post_update_router_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_router + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_update_router_with_metadata` + interceptor in new development instead of the `post_update_router` interceptor. + When both interceptors are used, this `post_update_router_with_metadata` interceptor runs after the + `post_update_router` interceptor. The (possibly modified) response returned by + `post_update_router` will be passed to + `post_update_router_with_metadata`. + """ + return response, metadata + def pre_update_subnet( self, request: service.UpdateSubnetRequest, @@ -884,12 +1470,35 @@ def post_update_subnet( ) -> operations_pb2.Operation: """Post-rpc interceptor for update_subnet - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_update_subnet_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EdgeNetwork server but before - it is returned to user code. + it is returned to user code. This `post_update_subnet` interceptor runs + before the `post_update_subnet_with_metadata` interceptor. """ return response + def post_update_subnet_with_metadata( + self, + response: operations_pb2.Operation, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[operations_pb2.Operation, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for update_subnet + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EdgeNetwork server but before it is returned to user code. + + We recommend only using this `post_update_subnet_with_metadata` + interceptor in new development instead of the `post_update_subnet` interceptor. + When both interceptors are used, this `post_update_subnet_with_metadata` interceptor runs after the + `post_update_subnet` interceptor. The (possibly modified) response returned by + `post_update_subnet` will be passed to + `post_update_subnet_with_metadata`. + """ + return response, metadata + def pre_get_location( self, request: locations_pb2.GetLocationRequest, @@ -1312,6 +1921,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_interconnect_attachment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_create_interconnect_attachment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1463,6 +2079,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_network(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_network_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1616,6 +2236,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_router(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_router_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1769,6 +2393,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_subnet(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_create_subnet_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1917,6 +2545,13 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_interconnect_attachment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_delete_interconnect_attachment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2060,6 +2695,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_network(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_network_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2205,6 +2844,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_router(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_router_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2350,6 +2993,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_delete_subnet(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_delete_subnet_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2497,6 +3144,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_diagnose_interconnect(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_diagnose_interconnect_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2645,6 +3296,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_diagnose_network(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_diagnose_network_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2788,6 +3443,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_diagnose_router(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_diagnose_router_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -2932,6 +3591,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_interconnect(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_interconnect_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3081,6 +3744,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_interconnect_attachment(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_interconnect_attachment_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3227,6 +3894,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_network(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_network_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3369,6 +4040,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_router(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_router_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3511,6 +4186,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_subnet(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_subnet_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3654,6 +4333,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_zone(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_get_zone_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3801,6 +4484,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_initialize_zone(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_initialize_zone_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -3950,6 +4637,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_interconnect_attachments(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_list_interconnect_attachments_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4097,6 +4791,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_interconnects(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_interconnects_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4246,6 +4944,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_networks(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_networks_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4393,6 +5095,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_routers(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_routers_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4540,6 +5246,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_subnets(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_subnets_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4685,6 +5395,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_zones(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_list_zones_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4838,6 +5552,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_router(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_router_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -4991,6 +5709,10 @@ def __call__( json_format.Parse(response.content, resp, ignore_unknown_fields=True) resp = self._interceptor.post_update_subnet(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_update_subnet_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-edgenetwork/samples/generated_samples/snippet_metadata_google.cloud.edgenetwork.v1.json b/packages/google-cloud-edgenetwork/samples/generated_samples/snippet_metadata_google.cloud.edgenetwork.v1.json index c64210ad1d46..077d9ced2941 100644 --- a/packages/google-cloud-edgenetwork/samples/generated_samples/snippet_metadata_google.cloud.edgenetwork.v1.json +++ b/packages/google-cloud-edgenetwork/samples/generated_samples/snippet_metadata_google.cloud.edgenetwork.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-edgenetwork", - "version": "0.1.14" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-edgenetwork/tests/unit/gapic/edgenetwork_v1/test_edge_network.py b/packages/google-cloud-edgenetwork/tests/unit/gapic/edgenetwork_v1/test_edge_network.py index 549dcf28e633..8699c408fccb 100644 --- a/packages/google-cloud-edgenetwork/tests/unit/gapic/edgenetwork_v1/test_edge_network.py +++ b/packages/google-cloud-edgenetwork/tests/unit/gapic/edgenetwork_v1/test_edge_network.py @@ -74,6 +74,13 @@ ) from google.cloud.edgenetwork_v1.types import resources, service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -313,6 +320,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EdgeNetworkClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EdgeNetworkClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -17841,10 +17891,13 @@ def test_initialize_zone_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_initialize_zone" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_initialize_zone_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_initialize_zone" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.InitializeZoneRequest.pb(service.InitializeZoneRequest()) transcode.return_value = { "method": "post", @@ -17868,6 +17921,7 @@ def test_initialize_zone_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.InitializeZoneResponse() + post_with_metadata.return_value = service.InitializeZoneResponse(), metadata client.initialize_zone( request, @@ -17879,6 +17933,7 @@ def test_initialize_zone_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_zones_rest_bad_request(request_type=service.ListZonesRequest): @@ -17963,10 +18018,13 @@ def test_list_zones_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_list_zones" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_list_zones_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_list_zones" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListZonesRequest.pb(service.ListZonesRequest()) transcode.return_value = { "method": "post", @@ -17988,6 +18046,7 @@ def test_list_zones_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListZonesResponse() + post_with_metadata.return_value = service.ListZonesResponse(), metadata client.list_zones( request, @@ -17999,6 +18058,7 @@ def test_list_zones_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_zone_rest_bad_request(request_type=service.GetZoneRequest): @@ -18083,10 +18143,13 @@ def test_get_zone_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_get_zone" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_get_zone_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_get_zone" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetZoneRequest.pb(service.GetZoneRequest()) transcode.return_value = { "method": "post", @@ -18108,6 +18171,7 @@ def test_get_zone_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.Zone() + post_with_metadata.return_value = resources.Zone(), metadata client.get_zone( request, @@ -18119,6 +18183,7 @@ def test_get_zone_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_networks_rest_bad_request(request_type=service.ListNetworksRequest): @@ -18203,10 +18268,13 @@ def test_list_networks_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_list_networks" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_list_networks_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_list_networks" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListNetworksRequest.pb(service.ListNetworksRequest()) transcode.return_value = { "method": "post", @@ -18230,6 +18298,7 @@ def test_list_networks_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListNetworksResponse() + post_with_metadata.return_value = service.ListNetworksResponse(), metadata client.list_networks( request, @@ -18241,6 +18310,7 @@ def test_list_networks_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_network_rest_bad_request(request_type=service.GetNetworkRequest): @@ -18331,10 +18401,13 @@ def test_get_network_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_get_network" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_get_network_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_get_network" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetNetworkRequest.pb(service.GetNetworkRequest()) transcode.return_value = { "method": "post", @@ -18356,6 +18429,7 @@ def test_get_network_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.Network() + post_with_metadata.return_value = resources.Network(), metadata client.get_network( request, @@ -18367,6 +18441,7 @@ def test_get_network_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_diagnose_network_rest_bad_request(request_type=service.DiagnoseNetworkRequest): @@ -18450,10 +18525,13 @@ def test_diagnose_network_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_diagnose_network" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_diagnose_network_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_diagnose_network" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DiagnoseNetworkRequest.pb(service.DiagnoseNetworkRequest()) transcode.return_value = { "method": "post", @@ -18477,6 +18555,7 @@ def test_diagnose_network_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.DiagnoseNetworkResponse() + post_with_metadata.return_value = service.DiagnoseNetworkResponse(), metadata client.diagnose_network( request, @@ -18488,6 +18567,7 @@ def test_diagnose_network_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_network_rest_bad_request(request_type=service.CreateNetworkRequest): @@ -18641,10 +18721,13 @@ def test_create_network_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_create_network" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_create_network_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_create_network" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.CreateNetworkRequest.pb(service.CreateNetworkRequest()) transcode.return_value = { "method": "post", @@ -18666,6 +18749,7 @@ def test_create_network_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_network( request, @@ -18677,6 +18761,7 @@ def test_create_network_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_network_rest_bad_request(request_type=service.DeleteNetworkRequest): @@ -18759,10 +18844,13 @@ def test_delete_network_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_delete_network" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_delete_network_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_delete_network" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DeleteNetworkRequest.pb(service.DeleteNetworkRequest()) transcode.return_value = { "method": "post", @@ -18784,6 +18872,7 @@ def test_delete_network_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_network( request, @@ -18795,6 +18884,7 @@ def test_delete_network_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_subnets_rest_bad_request(request_type=service.ListSubnetsRequest): @@ -18879,10 +18969,13 @@ def test_list_subnets_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_list_subnets" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_list_subnets_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_list_subnets" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListSubnetsRequest.pb(service.ListSubnetsRequest()) transcode.return_value = { "method": "post", @@ -18906,6 +18999,7 @@ def test_list_subnets_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListSubnetsResponse() + post_with_metadata.return_value = service.ListSubnetsResponse(), metadata client.list_subnets( request, @@ -18917,6 +19011,7 @@ def test_list_subnets_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_subnet_rest_bad_request(request_type=service.GetSubnetRequest): @@ -19017,10 +19112,13 @@ def test_get_subnet_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_get_subnet" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_get_subnet_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_get_subnet" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetSubnetRequest.pb(service.GetSubnetRequest()) transcode.return_value = { "method": "post", @@ -19042,6 +19140,7 @@ def test_get_subnet_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.Subnet() + post_with_metadata.return_value = resources.Subnet(), metadata client.get_subnet( request, @@ -19053,6 +19152,7 @@ def test_get_subnet_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_subnet_rest_bad_request(request_type=service.CreateSubnetRequest): @@ -19211,10 +19311,13 @@ def test_create_subnet_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_create_subnet" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_create_subnet_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_create_subnet" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.CreateSubnetRequest.pb(service.CreateSubnetRequest()) transcode.return_value = { "method": "post", @@ -19236,6 +19339,7 @@ def test_create_subnet_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_subnet( request, @@ -19247,6 +19351,7 @@ def test_create_subnet_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_subnet_rest_bad_request(request_type=service.UpdateSubnetRequest): @@ -19413,10 +19518,13 @@ def test_update_subnet_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_update_subnet" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_update_subnet_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_update_subnet" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.UpdateSubnetRequest.pb(service.UpdateSubnetRequest()) transcode.return_value = { "method": "post", @@ -19438,6 +19546,7 @@ def test_update_subnet_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_subnet( request, @@ -19449,6 +19558,7 @@ def test_update_subnet_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_subnet_rest_bad_request(request_type=service.DeleteSubnetRequest): @@ -19531,10 +19641,13 @@ def test_delete_subnet_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_delete_subnet" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_delete_subnet_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_delete_subnet" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DeleteSubnetRequest.pb(service.DeleteSubnetRequest()) transcode.return_value = { "method": "post", @@ -19556,6 +19669,7 @@ def test_delete_subnet_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_subnet( request, @@ -19567,6 +19681,7 @@ def test_delete_subnet_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_interconnects_rest_bad_request( @@ -19653,10 +19768,13 @@ def test_list_interconnects_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_list_interconnects" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_list_interconnects_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_list_interconnects" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListInterconnectsRequest.pb( service.ListInterconnectsRequest() ) @@ -19682,6 +19800,7 @@ def test_list_interconnects_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListInterconnectsResponse() + post_with_metadata.return_value = service.ListInterconnectsResponse(), metadata client.list_interconnects( request, @@ -19693,6 +19812,7 @@ def test_list_interconnects_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_interconnect_rest_bad_request(request_type=service.GetInterconnectRequest): @@ -19791,10 +19911,13 @@ def test_get_interconnect_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_get_interconnect" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_get_interconnect_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_get_interconnect" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetInterconnectRequest.pb(service.GetInterconnectRequest()) transcode.return_value = { "method": "post", @@ -19816,6 +19939,7 @@ def test_get_interconnect_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.Interconnect() + post_with_metadata.return_value = resources.Interconnect(), metadata client.get_interconnect( request, @@ -19827,6 +19951,7 @@ def test_get_interconnect_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_diagnose_interconnect_rest_bad_request( @@ -19912,10 +20037,14 @@ def test_diagnose_interconnect_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_diagnose_interconnect" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, + "post_diagnose_interconnect_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_diagnose_interconnect" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DiagnoseInterconnectRequest.pb( service.DiagnoseInterconnectRequest() ) @@ -19941,6 +20070,10 @@ def test_diagnose_interconnect_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.DiagnoseInterconnectResponse() + post_with_metadata.return_value = ( + service.DiagnoseInterconnectResponse(), + metadata, + ) client.diagnose_interconnect( request, @@ -19952,6 +20085,7 @@ def test_diagnose_interconnect_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_interconnect_attachments_rest_bad_request( @@ -20038,10 +20172,14 @@ def test_list_interconnect_attachments_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_list_interconnect_attachments" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, + "post_list_interconnect_attachments_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_list_interconnect_attachments" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListInterconnectAttachmentsRequest.pb( service.ListInterconnectAttachmentsRequest() ) @@ -20067,6 +20205,10 @@ def test_list_interconnect_attachments_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListInterconnectAttachmentsResponse() + post_with_metadata.return_value = ( + service.ListInterconnectAttachmentsResponse(), + metadata, + ) client.list_interconnect_attachments( request, @@ -20078,6 +20220,7 @@ def test_list_interconnect_attachments_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_interconnect_attachment_rest_bad_request( @@ -20178,10 +20321,14 @@ def test_get_interconnect_attachment_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_get_interconnect_attachment" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, + "post_get_interconnect_attachment_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_get_interconnect_attachment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetInterconnectAttachmentRequest.pb( service.GetInterconnectAttachmentRequest() ) @@ -20207,6 +20354,7 @@ def test_get_interconnect_attachment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.InterconnectAttachment() + post_with_metadata.return_value = resources.InterconnectAttachment(), metadata client.get_interconnect_attachment( request, @@ -20218,6 +20366,7 @@ def test_get_interconnect_attachment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_interconnect_attachment_rest_bad_request( @@ -20381,10 +20530,14 @@ def test_create_interconnect_attachment_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_create_interconnect_attachment" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, + "post_create_interconnect_attachment_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_create_interconnect_attachment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.CreateInterconnectAttachmentRequest.pb( service.CreateInterconnectAttachmentRequest() ) @@ -20408,6 +20561,7 @@ def test_create_interconnect_attachment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_interconnect_attachment( request, @@ -20419,6 +20573,7 @@ def test_create_interconnect_attachment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_interconnect_attachment_rest_bad_request( @@ -20503,10 +20658,14 @@ def test_delete_interconnect_attachment_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_delete_interconnect_attachment" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, + "post_delete_interconnect_attachment_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_delete_interconnect_attachment" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DeleteInterconnectAttachmentRequest.pb( service.DeleteInterconnectAttachmentRequest() ) @@ -20530,6 +20689,7 @@ def test_delete_interconnect_attachment_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_interconnect_attachment( request, @@ -20541,6 +20701,7 @@ def test_delete_interconnect_attachment_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_routers_rest_bad_request(request_type=service.ListRoutersRequest): @@ -20625,10 +20786,13 @@ def test_list_routers_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_list_routers" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_list_routers_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_list_routers" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListRoutersRequest.pb(service.ListRoutersRequest()) transcode.return_value = { "method": "post", @@ -20652,6 +20816,7 @@ def test_list_routers_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListRoutersResponse() + post_with_metadata.return_value = service.ListRoutersResponse(), metadata client.list_routers( request, @@ -20663,6 +20828,7 @@ def test_list_routers_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_router_rest_bad_request(request_type=service.GetRouterRequest): @@ -20757,10 +20923,13 @@ def test_get_router_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_get_router" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_get_router_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_get_router" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetRouterRequest.pb(service.GetRouterRequest()) transcode.return_value = { "method": "post", @@ -20782,6 +20951,7 @@ def test_get_router_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = resources.Router() + post_with_metadata.return_value = resources.Router(), metadata client.get_router( request, @@ -20793,6 +20963,7 @@ def test_get_router_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_diagnose_router_rest_bad_request(request_type=service.DiagnoseRouterRequest): @@ -20876,10 +21047,13 @@ def test_diagnose_router_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_diagnose_router" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_diagnose_router_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_diagnose_router" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DiagnoseRouterRequest.pb(service.DiagnoseRouterRequest()) transcode.return_value = { "method": "post", @@ -20903,6 +21077,7 @@ def test_diagnose_router_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.DiagnoseRouterResponse() + post_with_metadata.return_value = service.DiagnoseRouterResponse(), metadata client.diagnose_router( request, @@ -20914,6 +21089,7 @@ def test_diagnose_router_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_create_router_rest_bad_request(request_type=service.CreateRouterRequest): @@ -21098,10 +21274,13 @@ def test_create_router_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_create_router" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_create_router_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_create_router" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.CreateRouterRequest.pb(service.CreateRouterRequest()) transcode.return_value = { "method": "post", @@ -21123,6 +21302,7 @@ def test_create_router_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.create_router( request, @@ -21134,6 +21314,7 @@ def test_create_router_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_update_router_rest_bad_request(request_type=service.UpdateRouterRequest): @@ -21326,10 +21507,13 @@ def test_update_router_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_update_router" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_update_router_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_update_router" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.UpdateRouterRequest.pb(service.UpdateRouterRequest()) transcode.return_value = { "method": "post", @@ -21351,6 +21535,7 @@ def test_update_router_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.update_router( request, @@ -21362,6 +21547,7 @@ def test_update_router_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_delete_router_rest_bad_request(request_type=service.DeleteRouterRequest): @@ -21444,10 +21630,13 @@ def test_delete_router_rest_interceptors(null_interceptor): ), mock.patch.object( transports.EdgeNetworkRestInterceptor, "post_delete_router" ) as post, mock.patch.object( + transports.EdgeNetworkRestInterceptor, "post_delete_router_with_metadata" + ) as post_with_metadata, mock.patch.object( transports.EdgeNetworkRestInterceptor, "pre_delete_router" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.DeleteRouterRequest.pb(service.DeleteRouterRequest()) transcode.return_value = { "method": "post", @@ -21469,6 +21658,7 @@ def test_delete_router_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = operations_pb2.Operation() + post_with_metadata.return_value = operations_pb2.Operation(), metadata client.delete_router( request, @@ -21480,6 +21670,7 @@ def test_delete_router_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_location_rest_bad_request(request_type=locations_pb2.GetLocationRequest): diff --git a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph/gapic_version.py b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph/gapic_version.py index 0106eadcd8d9..558c8aab67c5 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph/gapic_version.py +++ b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.3.14" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/gapic_version.py b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/gapic_version.py index 0106eadcd8d9..558c8aab67c5 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/gapic_version.py +++ b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/gapic_version.py @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. # -__version__ = "0.3.14" # {x-release-please-version} +__version__ = "0.0.0" # {x-release-please-version} diff --git a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/services/enterprise_knowledge_graph_service/client.py b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/services/enterprise_knowledge_graph_service/client.py index 209d1b899e30..5f8b9d2d40f5 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/services/enterprise_knowledge_graph_service/client.py +++ b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/services/enterprise_knowledge_graph_service/client.py @@ -14,6 +14,8 @@ # limitations under the License. # from collections import OrderedDict +from http import HTTPStatus +import json import logging as std_logging import os import re @@ -583,6 +585,33 @@ def _validate_universe_domain(self): # NOTE (b/349488459): universe validation is disabled until further notice. return True + def _add_cred_info_for_auth_errors( + self, error: core_exceptions.GoogleAPICallError + ) -> None: + """Adds credential info string to error details for 401/403/404 errors. + + Args: + error (google.api_core.exceptions.GoogleAPICallError): The error to add the cred info. + """ + if error.code not in [ + HTTPStatus.UNAUTHORIZED, + HTTPStatus.FORBIDDEN, + HTTPStatus.NOT_FOUND, + ]: + return + + cred = self._transport._credentials + + # get_cred_info is only available in google-auth>=2.35.0 + if not hasattr(cred, "get_cred_info"): + return + + # ignore the type check since pypy test fails when get_cred_info + # is not available + cred_info = cred.get_cred_info() # type: ignore + if cred_info and hasattr(error._details, "append"): + error._details.append(json.dumps(cred_info)) + @property def api_endpoint(self): """Return the API endpoint used by the client instance. diff --git a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/services/enterprise_knowledge_graph_service/transports/rest.py b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/services/enterprise_knowledge_graph_service/transports/rest.py index 2df11d1722ab..3a5fa42d565e 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/services/enterprise_knowledge_graph_service/transports/rest.py +++ b/packages/google-cloud-enterpriseknowledgegraph/google/cloud/enterpriseknowledgegraph_v1/services/enterprise_knowledge_graph_service/transports/rest.py @@ -175,12 +175,37 @@ def post_create_entity_reconciliation_job( ) -> service.EntityReconciliationJob: """Post-rpc interceptor for create_entity_reconciliation_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_create_entity_reconciliation_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EnterpriseKnowledgeGraphService server but before - it is returned to user code. + it is returned to user code. This `post_create_entity_reconciliation_job` interceptor runs + before the `post_create_entity_reconciliation_job_with_metadata` interceptor. """ return response + def post_create_entity_reconciliation_job_with_metadata( + self, + response: service.EntityReconciliationJob, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.EntityReconciliationJob, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for create_entity_reconciliation_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EnterpriseKnowledgeGraphService server but before it is returned to user code. + + We recommend only using this `post_create_entity_reconciliation_job_with_metadata` + interceptor in new development instead of the `post_create_entity_reconciliation_job` interceptor. + When both interceptors are used, this `post_create_entity_reconciliation_job_with_metadata` interceptor runs after the + `post_create_entity_reconciliation_job` interceptor. The (possibly modified) response returned by + `post_create_entity_reconciliation_job` will be passed to + `post_create_entity_reconciliation_job_with_metadata`. + """ + return response, metadata + def pre_delete_entity_reconciliation_job( self, request: service.DeleteEntityReconciliationJobRequest, @@ -216,12 +241,37 @@ def post_get_entity_reconciliation_job( ) -> service.EntityReconciliationJob: """Post-rpc interceptor for get_entity_reconciliation_job - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_get_entity_reconciliation_job_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EnterpriseKnowledgeGraphService server but before - it is returned to user code. + it is returned to user code. This `post_get_entity_reconciliation_job` interceptor runs + before the `post_get_entity_reconciliation_job_with_metadata` interceptor. """ return response + def post_get_entity_reconciliation_job_with_metadata( + self, + response: service.EntityReconciliationJob, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.EntityReconciliationJob, Sequence[Tuple[str, Union[str, bytes]]] + ]: + """Post-rpc interceptor for get_entity_reconciliation_job + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EnterpriseKnowledgeGraphService server but before it is returned to user code. + + We recommend only using this `post_get_entity_reconciliation_job_with_metadata` + interceptor in new development instead of the `post_get_entity_reconciliation_job` interceptor. + When both interceptors are used, this `post_get_entity_reconciliation_job_with_metadata` interceptor runs after the + `post_get_entity_reconciliation_job` interceptor. The (possibly modified) response returned by + `post_get_entity_reconciliation_job` will be passed to + `post_get_entity_reconciliation_job_with_metadata`. + """ + return response, metadata + def pre_list_entity_reconciliation_jobs( self, request: service.ListEntityReconciliationJobsRequest, @@ -242,12 +292,38 @@ def post_list_entity_reconciliation_jobs( ) -> service.ListEntityReconciliationJobsResponse: """Post-rpc interceptor for list_entity_reconciliation_jobs - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_list_entity_reconciliation_jobs_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EnterpriseKnowledgeGraphService server but before - it is returned to user code. + it is returned to user code. This `post_list_entity_reconciliation_jobs` interceptor runs + before the `post_list_entity_reconciliation_jobs_with_metadata` interceptor. """ return response + def post_list_entity_reconciliation_jobs_with_metadata( + self, + response: service.ListEntityReconciliationJobsResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[ + service.ListEntityReconciliationJobsResponse, + Sequence[Tuple[str, Union[str, bytes]]], + ]: + """Post-rpc interceptor for list_entity_reconciliation_jobs + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EnterpriseKnowledgeGraphService server but before it is returned to user code. + + We recommend only using this `post_list_entity_reconciliation_jobs_with_metadata` + interceptor in new development instead of the `post_list_entity_reconciliation_jobs` interceptor. + When both interceptors are used, this `post_list_entity_reconciliation_jobs_with_metadata` interceptor runs after the + `post_list_entity_reconciliation_jobs` interceptor. The (possibly modified) response returned by + `post_list_entity_reconciliation_jobs` will be passed to + `post_list_entity_reconciliation_jobs_with_metadata`. + """ + return response, metadata + def pre_lookup( self, request: service.LookupRequest, @@ -263,12 +339,35 @@ def pre_lookup( def post_lookup(self, response: service.LookupResponse) -> service.LookupResponse: """Post-rpc interceptor for lookup - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_lookup_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EnterpriseKnowledgeGraphService server but before - it is returned to user code. + it is returned to user code. This `post_lookup` interceptor runs + before the `post_lookup_with_metadata` interceptor. """ return response + def post_lookup_with_metadata( + self, + response: service.LookupResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.LookupResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for lookup + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EnterpriseKnowledgeGraphService server but before it is returned to user code. + + We recommend only using this `post_lookup_with_metadata` + interceptor in new development instead of the `post_lookup` interceptor. + When both interceptors are used, this `post_lookup_with_metadata` interceptor runs after the + `post_lookup` interceptor. The (possibly modified) response returned by + `post_lookup` will be passed to + `post_lookup_with_metadata`. + """ + return response, metadata + def pre_lookup_public_kg( self, request: service.LookupPublicKgRequest, @@ -286,12 +385,35 @@ def post_lookup_public_kg( ) -> service.LookupPublicKgResponse: """Post-rpc interceptor for lookup_public_kg - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_lookup_public_kg_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EnterpriseKnowledgeGraphService server but before - it is returned to user code. + it is returned to user code. This `post_lookup_public_kg` interceptor runs + before the `post_lookup_public_kg_with_metadata` interceptor. """ return response + def post_lookup_public_kg_with_metadata( + self, + response: service.LookupPublicKgResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.LookupPublicKgResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for lookup_public_kg + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EnterpriseKnowledgeGraphService server but before it is returned to user code. + + We recommend only using this `post_lookup_public_kg_with_metadata` + interceptor in new development instead of the `post_lookup_public_kg` interceptor. + When both interceptors are used, this `post_lookup_public_kg_with_metadata` interceptor runs after the + `post_lookup_public_kg` interceptor. The (possibly modified) response returned by + `post_lookup_public_kg` will be passed to + `post_lookup_public_kg_with_metadata`. + """ + return response, metadata + def pre_search( self, request: service.SearchRequest, @@ -307,12 +429,35 @@ def pre_search( def post_search(self, response: service.SearchResponse) -> service.SearchResponse: """Post-rpc interceptor for search - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EnterpriseKnowledgeGraphService server but before - it is returned to user code. + it is returned to user code. This `post_search` interceptor runs + before the `post_search_with_metadata` interceptor. """ return response + def post_search_with_metadata( + self, + response: service.SearchResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.SearchResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EnterpriseKnowledgeGraphService server but before it is returned to user code. + + We recommend only using this `post_search_with_metadata` + interceptor in new development instead of the `post_search` interceptor. + When both interceptors are used, this `post_search_with_metadata` interceptor runs after the + `post_search` interceptor. The (possibly modified) response returned by + `post_search` will be passed to + `post_search_with_metadata`. + """ + return response, metadata + def pre_search_public_kg( self, request: service.SearchPublicKgRequest, @@ -330,12 +475,35 @@ def post_search_public_kg( ) -> service.SearchPublicKgResponse: """Post-rpc interceptor for search_public_kg - Override in a subclass to manipulate the response + DEPRECATED. Please use the `post_search_public_kg_with_metadata` + interceptor instead. + + Override in a subclass to read or manipulate the response after it is returned by the EnterpriseKnowledgeGraphService server but before - it is returned to user code. + it is returned to user code. This `post_search_public_kg` interceptor runs + before the `post_search_public_kg_with_metadata` interceptor. """ return response + def post_search_public_kg_with_metadata( + self, + response: service.SearchPublicKgResponse, + metadata: Sequence[Tuple[str, Union[str, bytes]]], + ) -> Tuple[service.SearchPublicKgResponse, Sequence[Tuple[str, Union[str, bytes]]]]: + """Post-rpc interceptor for search_public_kg + + Override in a subclass to read or manipulate the response or metadata after it + is returned by the EnterpriseKnowledgeGraphService server but before it is returned to user code. + + We recommend only using this `post_search_public_kg_with_metadata` + interceptor in new development instead of the `post_search_public_kg` interceptor. + When both interceptors are used, this `post_search_public_kg_with_metadata` interceptor runs after the + `post_search_public_kg` interceptor. The (possibly modified) response returned by + `post_search_public_kg` will be passed to + `post_search_public_kg_with_metadata`. + """ + return response, metadata + @dataclasses.dataclass class EnterpriseKnowledgeGraphServiceRestStub: @@ -676,6 +844,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_create_entity_reconciliation_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_create_entity_reconciliation_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -936,6 +1111,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_get_entity_reconciliation_job(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_get_entity_reconciliation_job_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1085,6 +1267,13 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_list_entity_reconciliation_jobs(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + ( + resp, + _, + ) = self._interceptor.post_list_entity_reconciliation_jobs_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1233,6 +1422,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_lookup(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_lookup_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1379,6 +1572,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_lookup_public_kg(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_lookup_public_kg_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1525,6 +1722,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER @@ -1671,6 +1872,10 @@ def __call__( json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) resp = self._interceptor.post_search_public_kg(resp) + response_metadata = [(k, str(v)) for k, v in response.headers.items()] + resp, _ = self._interceptor.post_search_public_kg_with_metadata( + resp, response_metadata + ) if CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( logging.DEBUG ): # pragma: NO COVER diff --git a/packages/google-cloud-enterpriseknowledgegraph/samples/generated_samples/snippet_metadata_google.cloud.enterpriseknowledgegraph.v1.json b/packages/google-cloud-enterpriseknowledgegraph/samples/generated_samples/snippet_metadata_google.cloud.enterpriseknowledgegraph.v1.json index 4e07ff14c814..2c25c85585a4 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/samples/generated_samples/snippet_metadata_google.cloud.enterpriseknowledgegraph.v1.json +++ b/packages/google-cloud-enterpriseknowledgegraph/samples/generated_samples/snippet_metadata_google.cloud.enterpriseknowledgegraph.v1.json @@ -8,7 +8,7 @@ ], "language": "PYTHON", "name": "google-cloud-enterpriseknowledgegraph", - "version": "0.3.14" + "version": "0.1.0" }, "snippets": [ { diff --git a/packages/google-cloud-enterpriseknowledgegraph/tests/unit/gapic/enterpriseknowledgegraph_v1/test_enterprise_knowledge_graph_service.py b/packages/google-cloud-enterpriseknowledgegraph/tests/unit/gapic/enterpriseknowledgegraph_v1/test_enterprise_knowledge_graph_service.py index b5e9bfca2832..4968b334a5b3 100644 --- a/packages/google-cloud-enterpriseknowledgegraph/tests/unit/gapic/enterpriseknowledgegraph_v1/test_enterprise_knowledge_graph_service.py +++ b/packages/google-cloud-enterpriseknowledgegraph/tests/unit/gapic/enterpriseknowledgegraph_v1/test_enterprise_knowledge_graph_service.py @@ -66,6 +66,13 @@ ) from google.cloud.enterpriseknowledgegraph_v1.types import job_state, service +CRED_INFO_JSON = { + "credential_source": "/path/to/file", + "credential_type": "service account credentials", + "principal": "service-account@example.com", +} +CRED_INFO_STRING = json.dumps(CRED_INFO_JSON) + async def mock_async_gen(data, chunk_size=1): for i in range(0, len(data)): # pragma: NO COVER @@ -360,6 +367,49 @@ def test__get_universe_domain(): assert str(excinfo.value) == "Universe Domain cannot be an empty string." +@pytest.mark.parametrize( + "error_code,cred_info_json,show_cred_info", + [ + (401, CRED_INFO_JSON, True), + (403, CRED_INFO_JSON, True), + (404, CRED_INFO_JSON, True), + (500, CRED_INFO_JSON, False), + (401, None, False), + (403, None, False), + (404, None, False), + (500, None, False), + ], +) +def test__add_cred_info_for_auth_errors(error_code, cred_info_json, show_cred_info): + cred = mock.Mock(["get_cred_info"]) + cred.get_cred_info = mock.Mock(return_value=cred_info_json) + client = EnterpriseKnowledgeGraphServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=["foo"]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + if show_cred_info: + assert error.details == ["foo", CRED_INFO_STRING] + else: + assert error.details == ["foo"] + + +@pytest.mark.parametrize("error_code", [401, 403, 404, 500]) +def test__add_cred_info_for_auth_errors_no_get_cred_info(error_code): + cred = mock.Mock([]) + assert not hasattr(cred, "get_cred_info") + client = EnterpriseKnowledgeGraphServiceClient(credentials=cred) + client._transport._credentials = cred + + error = core_exceptions.GoogleAPICallError("message", details=[]) + error.code = error_code + + client._add_cred_info_for_auth_errors(error) + assert error.details == [] + + @pytest.mark.parametrize( "client_class,transport_name", [ @@ -7035,11 +7085,15 @@ def test_create_entity_reconciliation_job_rest_interceptors(null_interceptor): transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "post_create_entity_reconciliation_job", ) as post, mock.patch.object( + transports.EnterpriseKnowledgeGraphServiceRestInterceptor, + "post_create_entity_reconciliation_job_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "pre_create_entity_reconciliation_job", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.CreateEntityReconciliationJobRequest.pb( service.CreateEntityReconciliationJobRequest() ) @@ -7065,6 +7119,7 @@ def test_create_entity_reconciliation_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.EntityReconciliationJob() + post_with_metadata.return_value = service.EntityReconciliationJob(), metadata client.create_entity_reconciliation_job( request, @@ -7076,6 +7131,7 @@ def test_create_entity_reconciliation_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_get_entity_reconciliation_job_rest_bad_request( @@ -7167,11 +7223,15 @@ def test_get_entity_reconciliation_job_rest_interceptors(null_interceptor): transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "post_get_entity_reconciliation_job", ) as post, mock.patch.object( + transports.EnterpriseKnowledgeGraphServiceRestInterceptor, + "post_get_entity_reconciliation_job_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "pre_get_entity_reconciliation_job", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.GetEntityReconciliationJobRequest.pb( service.GetEntityReconciliationJobRequest() ) @@ -7197,6 +7257,7 @@ def test_get_entity_reconciliation_job_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.EntityReconciliationJob() + post_with_metadata.return_value = service.EntityReconciliationJob(), metadata client.get_entity_reconciliation_job( request, @@ -7208,6 +7269,7 @@ def test_get_entity_reconciliation_job_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_list_entity_reconciliation_jobs_rest_bad_request( @@ -7293,11 +7355,15 @@ def test_list_entity_reconciliation_jobs_rest_interceptors(null_interceptor): transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "post_list_entity_reconciliation_jobs", ) as post, mock.patch.object( + transports.EnterpriseKnowledgeGraphServiceRestInterceptor, + "post_list_entity_reconciliation_jobs_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "pre_list_entity_reconciliation_jobs", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.ListEntityReconciliationJobsRequest.pb( service.ListEntityReconciliationJobsRequest() ) @@ -7323,6 +7389,10 @@ def test_list_entity_reconciliation_jobs_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.ListEntityReconciliationJobsResponse() + post_with_metadata.return_value = ( + service.ListEntityReconciliationJobsResponse(), + metadata, + ) client.list_entity_reconciliation_jobs( request, @@ -7334,6 +7404,7 @@ def test_list_entity_reconciliation_jobs_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_cancel_entity_reconciliation_job_rest_bad_request( @@ -7641,10 +7712,14 @@ def test_lookup_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "post_lookup" ) as post, mock.patch.object( + transports.EnterpriseKnowledgeGraphServiceRestInterceptor, + "post_lookup_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "pre_lookup" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.LookupRequest.pb(service.LookupRequest()) transcode.return_value = { "method": "post", @@ -7666,6 +7741,7 @@ def test_lookup_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.LookupResponse() + post_with_metadata.return_value = service.LookupResponse(), metadata client.lookup( request, @@ -7677,6 +7753,7 @@ def test_lookup_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_search_rest_bad_request(request_type=service.SearchRequest): @@ -7756,10 +7833,14 @@ def test_search_rest_interceptors(null_interceptor): ) as transcode, mock.patch.object( transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "post_search" ) as post, mock.patch.object( + transports.EnterpriseKnowledgeGraphServiceRestInterceptor, + "post_search_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "pre_search" ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.SearchRequest.pb(service.SearchRequest()) transcode.return_value = { "method": "post", @@ -7781,6 +7862,7 @@ def test_search_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.SearchResponse() + post_with_metadata.return_value = service.SearchResponse(), metadata client.search( request, @@ -7792,6 +7874,7 @@ def test_search_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_lookup_public_kg_rest_bad_request(request_type=service.LookupPublicKgRequest): @@ -7872,11 +7955,15 @@ def test_lookup_public_kg_rest_interceptors(null_interceptor): transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "post_lookup_public_kg", ) as post, mock.patch.object( + transports.EnterpriseKnowledgeGraphServiceRestInterceptor, + "post_lookup_public_kg_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "pre_lookup_public_kg", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.LookupPublicKgRequest.pb(service.LookupPublicKgRequest()) transcode.return_value = { "method": "post", @@ -7900,6 +7987,7 @@ def test_lookup_public_kg_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.LookupPublicKgResponse() + post_with_metadata.return_value = service.LookupPublicKgResponse(), metadata client.lookup_public_kg( request, @@ -7911,6 +7999,7 @@ def test_lookup_public_kg_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_search_public_kg_rest_bad_request(request_type=service.SearchPublicKgRequest): @@ -7991,11 +8080,15 @@ def test_search_public_kg_rest_interceptors(null_interceptor): transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "post_search_public_kg", ) as post, mock.patch.object( + transports.EnterpriseKnowledgeGraphServiceRestInterceptor, + "post_search_public_kg_with_metadata", + ) as post_with_metadata, mock.patch.object( transports.EnterpriseKnowledgeGraphServiceRestInterceptor, "pre_search_public_kg", ) as pre: pre.assert_not_called() post.assert_not_called() + post_with_metadata.assert_not_called() pb_message = service.SearchPublicKgRequest.pb(service.SearchPublicKgRequest()) transcode.return_value = { "method": "post", @@ -8019,6 +8112,7 @@ def test_search_public_kg_rest_interceptors(null_interceptor): ] pre.return_value = request, metadata post.return_value = service.SearchPublicKgResponse() + post_with_metadata.return_value = service.SearchPublicKgResponse(), metadata client.search_public_kg( request, @@ -8030,6 +8124,7 @@ def test_search_public_kg_rest_interceptors(null_interceptor): pre.assert_called_once() post.assert_called_once() + post_with_metadata.assert_called_once() def test_initialize_client_w_rest():