Skip to content

Commit bc92bc2

Browse files
feat: add common resource path helpers; expose client transport as property (#37)
1 parent 4d1c8cf commit bc92bc2

File tree

18 files changed

+2075
-1052
lines changed

18 files changed

+2075
-1052
lines changed

docs/errorreporting_v1beta1/types.rst

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ Types for Google Cloud Errorreporting v1beta1 API
33

44
.. automodule:: google.cloud.errorreporting_v1beta1.types
55
:members:
6+
:show-inheritance:

google/cloud/errorreporting_v1beta1/services/error_group_service/async_client.py

+56-10
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,51 @@ class ErrorGroupServiceAsyncClient:
4545
DEFAULT_MTLS_ENDPOINT = ErrorGroupServiceClient.DEFAULT_MTLS_ENDPOINT
4646

4747
error_group_path = staticmethod(ErrorGroupServiceClient.error_group_path)
48+
parse_error_group_path = staticmethod(
49+
ErrorGroupServiceClient.parse_error_group_path
50+
)
51+
52+
common_billing_account_path = staticmethod(
53+
ErrorGroupServiceClient.common_billing_account_path
54+
)
55+
parse_common_billing_account_path = staticmethod(
56+
ErrorGroupServiceClient.parse_common_billing_account_path
57+
)
58+
59+
common_folder_path = staticmethod(ErrorGroupServiceClient.common_folder_path)
60+
parse_common_folder_path = staticmethod(
61+
ErrorGroupServiceClient.parse_common_folder_path
62+
)
63+
64+
common_organization_path = staticmethod(
65+
ErrorGroupServiceClient.common_organization_path
66+
)
67+
parse_common_organization_path = staticmethod(
68+
ErrorGroupServiceClient.parse_common_organization_path
69+
)
70+
71+
common_project_path = staticmethod(ErrorGroupServiceClient.common_project_path)
72+
parse_common_project_path = staticmethod(
73+
ErrorGroupServiceClient.parse_common_project_path
74+
)
75+
76+
common_location_path = staticmethod(ErrorGroupServiceClient.common_location_path)
77+
parse_common_location_path = staticmethod(
78+
ErrorGroupServiceClient.parse_common_location_path
79+
)
4880

4981
from_service_account_file = ErrorGroupServiceClient.from_service_account_file
5082
from_service_account_json = from_service_account_file
5183

84+
@property
85+
def transport(self) -> ErrorGroupServiceTransport:
86+
"""Return the transport used by the client instance.
87+
88+
Returns:
89+
ErrorGroupServiceTransport: The transport used by the client instance.
90+
"""
91+
return self._client.transport
92+
5293
get_transport_class = functools.partial(
5394
type(ErrorGroupServiceClient).get_transport_class, type(ErrorGroupServiceClient)
5495
)
@@ -75,16 +116,19 @@ def __init__(
75116
client_options (ClientOptions): Custom options for the client. It
76117
won't take effect if a ``transport`` instance is provided.
77118
(1) The ``api_endpoint`` property can be used to override the
78-
default endpoint provided by the client. GOOGLE_API_USE_MTLS
119+
default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
79120
environment variable can also be used to override the endpoint:
80121
"always" (always use the default mTLS endpoint), "never" (always
81-
use the default regular endpoint, this is the default value for
82-
the environment variable) and "auto" (auto switch to the default
83-
mTLS endpoint if client SSL credentials is present). However,
84-
the ``api_endpoint`` property takes precedence if provided.
85-
(2) The ``client_cert_source`` property is used to provide client
86-
SSL credentials for mutual TLS transport. If not provided, the
87-
default SSL credentials will be used if present.
122+
use the default regular endpoint) and "auto" (auto switch to the
123+
default mTLS endpoint if client certificate is present, this is
124+
the default value). However, the ``api_endpoint`` property takes
125+
precedence if provided.
126+
(2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
127+
is "true", then the ``client_cert_source`` property can be used
128+
to provide client certificate for mutual TLS transport. If
129+
not provided, the default SSL client certificate will be used if
130+
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
131+
set, no client certificate will be used.
88132
89133
Raises:
90134
google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport
@@ -139,7 +183,8 @@ async def get_group(
139183
# Create or coerce a protobuf request object.
140184
# Sanity check: If we got a request object, we should *not* have
141185
# gotten any keyword arguments that map to the request.
142-
if request is not None and any([group_name]):
186+
has_flattened_params = any([group_name])
187+
if request is not None and has_flattened_params:
143188
raise ValueError(
144189
"If the `request` argument is set, then none of "
145190
"the individual field arguments should be set."
@@ -213,7 +258,8 @@ async def update_group(
213258
# Create or coerce a protobuf request object.
214259
# Sanity check: If we got a request object, we should *not* have
215260
# gotten any keyword arguments that map to the request.
216-
if request is not None and any([group]):
261+
has_flattened_params = any([group])
262+
if request is not None and has_flattened_params:
217263
raise ValueError(
218264
"If the `request` argument is set, then none of "
219265
"the individual field arguments should be set."

google/cloud/errorreporting_v1beta1/services/error_group_service/client.py

+127-37
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,19 @@
1616
#
1717

1818
from collections import OrderedDict
19+
from distutils import util
1920
import os
2021
import re
21-
from typing import Callable, Dict, Sequence, Tuple, Type, Union
22+
from typing import Callable, Dict, Optional, Sequence, Tuple, Type, Union
2223
import pkg_resources
2324

24-
import google.api_core.client_options as ClientOptions # type: ignore
25+
from google.api_core import client_options as client_options_lib # type: ignore
2526
from google.api_core import exceptions # type: ignore
2627
from google.api_core import gapic_v1 # type: ignore
2728
from google.api_core import retry as retries # type: ignore
2829
from google.auth import credentials # type: ignore
2930
from google.auth.transport import mtls # type: ignore
31+
from google.auth.transport.grpc import SslCredentials # type: ignore
3032
from google.auth.exceptions import MutualTLSChannelError # type: ignore
3133
from google.oauth2 import service_account # type: ignore
3234

@@ -130,6 +132,15 @@ def from_service_account_file(cls, filename: str, *args, **kwargs):
130132

131133
from_service_account_json = from_service_account_file
132134

135+
@property
136+
def transport(self) -> ErrorGroupServiceTransport:
137+
"""Return the transport used by the client instance.
138+
139+
Returns:
140+
ErrorGroupServiceTransport: The transport used by the client instance.
141+
"""
142+
return self._transport
143+
133144
@staticmethod
134145
def error_group_path(project: str, group: str,) -> str:
135146
"""Return a fully-qualified error_group string."""
@@ -141,12 +152,71 @@ def parse_error_group_path(path: str) -> Dict[str, str]:
141152
m = re.match(r"^projects/(?P<project>.+?)/groups/(?P<group>.+?)$", path)
142153
return m.groupdict() if m else {}
143154

155+
@staticmethod
156+
def common_billing_account_path(billing_account: str,) -> str:
157+
"""Return a fully-qualified billing_account string."""
158+
return "billingAccounts/{billing_account}".format(
159+
billing_account=billing_account,
160+
)
161+
162+
@staticmethod
163+
def parse_common_billing_account_path(path: str) -> Dict[str, str]:
164+
"""Parse a billing_account path into its component segments."""
165+
m = re.match(r"^billingAccounts/(?P<billing_account>.+?)$", path)
166+
return m.groupdict() if m else {}
167+
168+
@staticmethod
169+
def common_folder_path(folder: str,) -> str:
170+
"""Return a fully-qualified folder string."""
171+
return "folders/{folder}".format(folder=folder,)
172+
173+
@staticmethod
174+
def parse_common_folder_path(path: str) -> Dict[str, str]:
175+
"""Parse a folder path into its component segments."""
176+
m = re.match(r"^folders/(?P<folder>.+?)$", path)
177+
return m.groupdict() if m else {}
178+
179+
@staticmethod
180+
def common_organization_path(organization: str,) -> str:
181+
"""Return a fully-qualified organization string."""
182+
return "organizations/{organization}".format(organization=organization,)
183+
184+
@staticmethod
185+
def parse_common_organization_path(path: str) -> Dict[str, str]:
186+
"""Parse a organization path into its component segments."""
187+
m = re.match(r"^organizations/(?P<organization>.+?)$", path)
188+
return m.groupdict() if m else {}
189+
190+
@staticmethod
191+
def common_project_path(project: str,) -> str:
192+
"""Return a fully-qualified project string."""
193+
return "projects/{project}".format(project=project,)
194+
195+
@staticmethod
196+
def parse_common_project_path(path: str) -> Dict[str, str]:
197+
"""Parse a project path into its component segments."""
198+
m = re.match(r"^projects/(?P<project>.+?)$", path)
199+
return m.groupdict() if m else {}
200+
201+
@staticmethod
202+
def common_location_path(project: str, location: str,) -> str:
203+
"""Return a fully-qualified location string."""
204+
return "projects/{project}/locations/{location}".format(
205+
project=project, location=location,
206+
)
207+
208+
@staticmethod
209+
def parse_common_location_path(path: str) -> Dict[str, str]:
210+
"""Parse a location path into its component segments."""
211+
m = re.match(r"^projects/(?P<project>.+?)/locations/(?P<location>.+?)$", path)
212+
return m.groupdict() if m else {}
213+
144214
def __init__(
145215
self,
146216
*,
147-
credentials: credentials.Credentials = None,
148-
transport: Union[str, ErrorGroupServiceTransport] = None,
149-
client_options: ClientOptions = None,
217+
credentials: Optional[credentials.Credentials] = None,
218+
transport: Union[str, ErrorGroupServiceTransport, None] = None,
219+
client_options: Optional[client_options_lib.ClientOptions] = None,
150220
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
151221
) -> None:
152222
"""Instantiate the error group service client.
@@ -160,53 +230,74 @@ def __init__(
160230
transport (Union[str, ~.ErrorGroupServiceTransport]): The
161231
transport to use. If set to None, a transport is chosen
162232
automatically.
163-
client_options (ClientOptions): Custom options for the client. It
164-
won't take effect if a ``transport`` instance is provided.
233+
client_options (client_options_lib.ClientOptions): Custom options for the
234+
client. It won't take effect if a ``transport`` instance is provided.
165235
(1) The ``api_endpoint`` property can be used to override the
166-
default endpoint provided by the client. GOOGLE_API_USE_MTLS
236+
default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
167237
environment variable can also be used to override the endpoint:
168238
"always" (always use the default mTLS endpoint), "never" (always
169-
use the default regular endpoint, this is the default value for
170-
the environment variable) and "auto" (auto switch to the default
171-
mTLS endpoint if client SSL credentials is present). However,
172-
the ``api_endpoint`` property takes precedence if provided.
173-
(2) The ``client_cert_source`` property is used to provide client
174-
SSL credentials for mutual TLS transport. If not provided, the
175-
default SSL credentials will be used if present.
176-
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
177-
The client info used to send a user-agent string along with
178-
API requests. If ``None``, then default info will be used.
179-
Generally, you only need to set this if you're developing
239+
use the default regular endpoint) and "auto" (auto switch to the
240+
default mTLS endpoint if client certificate is present, this is
241+
the default value). However, the ``api_endpoint`` property takes
242+
precedence if provided.
243+
(2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
244+
is "true", then the ``client_cert_source`` property can be used
245+
to provide client certificate for mutual TLS transport. If
246+
not provided, the default SSL client certificate will be used if
247+
present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
248+
set, no client certificate will be used.
249+
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
250+
The client info used to send a user-agent string along with
251+
API requests. If ``None``, then default info will be used.
252+
Generally, you only need to set this if you're developing
180253
your own client library.
181254
182255
Raises:
183256
google.auth.exceptions.MutualTLSChannelError: If mutual TLS transport
184257
creation failed for any reason.
185258
"""
186259
if isinstance(client_options, dict):
187-
client_options = ClientOptions.from_dict(client_options)
260+
client_options = client_options_lib.from_dict(client_options)
188261
if client_options is None:
189-
client_options = ClientOptions.ClientOptions()
262+
client_options = client_options_lib.ClientOptions()
263+
264+
# Create SSL credentials for mutual TLS if needed.
265+
use_client_cert = bool(
266+
util.strtobool(os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"))
267+
)
190268

191-
if client_options.api_endpoint is None:
192-
use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS", "never")
269+
ssl_credentials = None
270+
is_mtls = False
271+
if use_client_cert:
272+
if client_options.client_cert_source:
273+
import grpc # type: ignore
274+
275+
cert, key = client_options.client_cert_source()
276+
ssl_credentials = grpc.ssl_channel_credentials(
277+
certificate_chain=cert, private_key=key
278+
)
279+
is_mtls = True
280+
else:
281+
creds = SslCredentials()
282+
is_mtls = creds.is_mtls
283+
ssl_credentials = creds.ssl_credentials if is_mtls else None
284+
285+
# Figure out which api endpoint to use.
286+
if client_options.api_endpoint is not None:
287+
api_endpoint = client_options.api_endpoint
288+
else:
289+
use_mtls_env = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
193290
if use_mtls_env == "never":
194-
client_options.api_endpoint = self.DEFAULT_ENDPOINT
291+
api_endpoint = self.DEFAULT_ENDPOINT
195292
elif use_mtls_env == "always":
196-
client_options.api_endpoint = self.DEFAULT_MTLS_ENDPOINT
293+
api_endpoint = self.DEFAULT_MTLS_ENDPOINT
197294
elif use_mtls_env == "auto":
198-
has_client_cert_source = (
199-
client_options.client_cert_source is not None
200-
or mtls.has_default_client_cert_source()
201-
)
202-
client_options.api_endpoint = (
203-
self.DEFAULT_MTLS_ENDPOINT
204-
if has_client_cert_source
205-
else self.DEFAULT_ENDPOINT
295+
api_endpoint = (
296+
self.DEFAULT_MTLS_ENDPOINT if is_mtls else self.DEFAULT_ENDPOINT
206297
)
207298
else:
208299
raise MutualTLSChannelError(
209-
"Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
300+
"Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
210301
)
211302

212303
# Save or instantiate the transport.
@@ -230,10 +321,9 @@ def __init__(
230321
self._transport = Transport(
231322
credentials=credentials,
232323
credentials_file=client_options.credentials_file,
233-
host=client_options.api_endpoint,
324+
host=api_endpoint,
234325
scopes=client_options.scopes,
235-
api_mtls_endpoint=client_options.api_endpoint,
236-
client_cert_source=client_options.client_cert_source,
326+
ssl_channel_credentials=ssl_credentials,
237327
quota_project_id=client_options.quota_project_id,
238328
client_info=client_info,
239329
)

0 commit comments

Comments
 (0)