Skip to content
This repository was archived by the owner on Jul 6, 2023. It is now read-only.

Commit bc1bc92

Browse files
chore: Update gapic-generator-python to v1.8.5 (#194)
* feat: enable "rest" transport in Python for services supporting numeric enums PiperOrigin-RevId: 508143576 Source-Link: googleapis/googleapis@7a702a9 Source-Link: https://github.com/googleapis/googleapis-gen/commit/6ad1279c0e7aa787ac6b66c9fd4a210692edffcd Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNmFkMTI3OWMwZTdhYTc4N2FjNmI2NmM5ZmQ0YTIxMDY5MmVkZmZjZCJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: Update gapic-generator-python to v1.8.5 PiperOrigin-RevId: 511892190 Source-Link: googleapis/googleapis@a45d9c0 Source-Link: https://github.com/googleapis/googleapis-gen/commit/1907294b1d8365ea24f8c5f2e059a64124c4ed3b Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMTkwNzI5NGIxZDgzNjVlYTI0ZjhjNWYyZTA1OWE2NDEyNGM0ZWQzYiJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: Victor Chudnovsky <vchudnov@google.com>
1 parent 0fdd6c7 commit bc1bc92

File tree

23 files changed

+2160
-12
lines changed

23 files changed

+2160
-12
lines changed

google/cloud/servicecontrol_v1/gapic_metadata.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
]
2727
}
2828
}
29+
},
30+
"rest": {
31+
"libraryClient": "QuotaControllerClient",
32+
"rpcs": {
33+
"AllocateQuota": {
34+
"methods": [
35+
"allocate_quota"
36+
]
37+
}
38+
}
2939
}
3040
}
3141
},
@@ -60,6 +70,21 @@
6070
]
6171
}
6272
}
73+
},
74+
"rest": {
75+
"libraryClient": "ServiceControllerClient",
76+
"rpcs": {
77+
"Check": {
78+
"methods": [
79+
"check"
80+
]
81+
},
82+
"Report": {
83+
"methods": [
84+
"report"
85+
]
86+
}
87+
}
6388
}
6489
}
6590
}

google/cloud/servicecontrol_v1/services/quota_controller/client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
from .transports.base import DEFAULT_CLIENT_INFO, QuotaControllerTransport
5252
from .transports.grpc import QuotaControllerGrpcTransport
5353
from .transports.grpc_asyncio import QuotaControllerGrpcAsyncIOTransport
54+
from .transports.rest import QuotaControllerRestTransport
5455

5556

5657
class QuotaControllerClientMeta(type):
@@ -66,6 +67,7 @@ class QuotaControllerClientMeta(type):
6667
) # type: Dict[str, Type[QuotaControllerTransport]]
6768
_transport_registry["grpc"] = QuotaControllerGrpcTransport
6869
_transport_registry["grpc_asyncio"] = QuotaControllerGrpcAsyncIOTransport
70+
_transport_registry["rest"] = QuotaControllerRestTransport
6971

7072
def get_transport_class(
7173
cls,

google/cloud/servicecontrol_v1/services/quota_controller/transports/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@
1919
from .base import QuotaControllerTransport
2020
from .grpc import QuotaControllerGrpcTransport
2121
from .grpc_asyncio import QuotaControllerGrpcAsyncIOTransport
22+
from .rest import QuotaControllerRestInterceptor, QuotaControllerRestTransport
2223

2324
# Compile a registry of transports.
2425
_transport_registry = OrderedDict() # type: Dict[str, Type[QuotaControllerTransport]]
2526
_transport_registry["grpc"] = QuotaControllerGrpcTransport
2627
_transport_registry["grpc_asyncio"] = QuotaControllerGrpcAsyncIOTransport
28+
_transport_registry["rest"] = QuotaControllerRestTransport
2729

2830
__all__ = (
2931
"QuotaControllerTransport",
3032
"QuotaControllerGrpcTransport",
3133
"QuotaControllerGrpcAsyncIOTransport",
34+
"QuotaControllerRestTransport",
35+
"QuotaControllerRestInterceptor",
3236
)
Lines changed: 309 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright 2022 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
import dataclasses
18+
import json # type: ignore
19+
import re
20+
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
21+
import warnings
22+
23+
from google.api_core import gapic_v1, path_template, rest_helpers, rest_streaming
24+
from google.api_core import exceptions as core_exceptions
25+
from google.api_core import retry as retries
26+
from google.auth import credentials as ga_credentials # type: ignore
27+
from google.auth.transport.grpc import SslCredentials # type: ignore
28+
from google.auth.transport.requests import AuthorizedSession # type: ignore
29+
from google.protobuf import json_format
30+
import grpc # type: ignore
31+
from requests import __version__ as requests_version
32+
33+
try:
34+
OptionalRetry = Union[retries.Retry, gapic_v1.method._MethodDefault]
35+
except AttributeError: # pragma: NO COVER
36+
OptionalRetry = Union[retries.Retry, object] # type: ignore
37+
38+
39+
from google.cloud.servicecontrol_v1.types import quota_controller
40+
41+
from .base import DEFAULT_CLIENT_INFO as BASE_DEFAULT_CLIENT_INFO
42+
from .base import QuotaControllerTransport
43+
44+
DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(
45+
gapic_version=BASE_DEFAULT_CLIENT_INFO.gapic_version,
46+
grpc_version=None,
47+
rest_version=requests_version,
48+
)
49+
50+
51+
class QuotaControllerRestInterceptor:
52+
"""Interceptor for QuotaController.
53+
54+
Interceptors are used to manipulate requests, request metadata, and responses
55+
in arbitrary ways.
56+
Example use cases include:
57+
* Logging
58+
* Verifying requests according to service or custom semantics
59+
* Stripping extraneous information from responses
60+
61+
These use cases and more can be enabled by injecting an
62+
instance of a custom subclass when constructing the QuotaControllerRestTransport.
63+
64+
.. code-block:: python
65+
class MyCustomQuotaControllerInterceptor(QuotaControllerRestInterceptor):
66+
def pre_allocate_quota(self, request, metadata):
67+
logging.log(f"Received request: {request}")
68+
return request, metadata
69+
70+
def post_allocate_quota(self, response):
71+
logging.log(f"Received response: {response}")
72+
return response
73+
74+
transport = QuotaControllerRestTransport(interceptor=MyCustomQuotaControllerInterceptor())
75+
client = QuotaControllerClient(transport=transport)
76+
77+
78+
"""
79+
80+
def pre_allocate_quota(
81+
self,
82+
request: quota_controller.AllocateQuotaRequest,
83+
metadata: Sequence[Tuple[str, str]],
84+
) -> Tuple[quota_controller.AllocateQuotaRequest, Sequence[Tuple[str, str]]]:
85+
"""Pre-rpc interceptor for allocate_quota
86+
87+
Override in a subclass to manipulate the request or metadata
88+
before they are sent to the QuotaController server.
89+
"""
90+
return request, metadata
91+
92+
def post_allocate_quota(
93+
self, response: quota_controller.AllocateQuotaResponse
94+
) -> quota_controller.AllocateQuotaResponse:
95+
"""Post-rpc interceptor for allocate_quota
96+
97+
Override in a subclass to manipulate the response
98+
after it is returned by the QuotaController server but before
99+
it is returned to user code.
100+
"""
101+
return response
102+
103+
104+
@dataclasses.dataclass
105+
class QuotaControllerRestStub:
106+
_session: AuthorizedSession
107+
_host: str
108+
_interceptor: QuotaControllerRestInterceptor
109+
110+
111+
class QuotaControllerRestTransport(QuotaControllerTransport):
112+
"""REST backend transport for QuotaController.
113+
114+
`Google Quota Control API </service-control/overview>`__
115+
116+
Allows clients to allocate and release quota against a `managed
117+
service <https://cloud.google.com/service-management/reference/rpc/google.api/servicemanagement.v1#google.api.servicemanagement.v1.ManagedService>`__.
118+
119+
This class defines the same methods as the primary client, so the
120+
primary client can load the underlying transport implementation
121+
and call it.
122+
123+
It sends JSON representations of protocol buffers over HTTP/1.1
124+
125+
"""
126+
127+
def __init__(
128+
self,
129+
*,
130+
host: str = "servicecontrol.googleapis.com",
131+
credentials: Optional[ga_credentials.Credentials] = None,
132+
credentials_file: Optional[str] = None,
133+
scopes: Optional[Sequence[str]] = None,
134+
client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
135+
quota_project_id: Optional[str] = None,
136+
client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO,
137+
always_use_jwt_access: Optional[bool] = False,
138+
url_scheme: str = "https",
139+
interceptor: Optional[QuotaControllerRestInterceptor] = None,
140+
api_audience: Optional[str] = None,
141+
) -> None:
142+
"""Instantiate the transport.
143+
144+
Args:
145+
host (Optional[str]):
146+
The hostname to connect to.
147+
credentials (Optional[google.auth.credentials.Credentials]): The
148+
authorization credentials to attach to requests. These
149+
credentials identify the application to the service; if none
150+
are specified, the client will attempt to ascertain the
151+
credentials from the environment.
152+
153+
credentials_file (Optional[str]): A file with credentials that can
154+
be loaded with :func:`google.auth.load_credentials_from_file`.
155+
This argument is ignored if ``channel`` is provided.
156+
scopes (Optional(Sequence[str])): A list of scopes. This argument is
157+
ignored if ``channel`` is provided.
158+
client_cert_source_for_mtls (Callable[[], Tuple[bytes, bytes]]): Client
159+
certificate to configure mutual TLS HTTP channel. It is ignored
160+
if ``channel`` is provided.
161+
quota_project_id (Optional[str]): An optional project to use for billing
162+
and quota.
163+
client_info (google.api_core.gapic_v1.client_info.ClientInfo):
164+
The client info used to send a user-agent string along with
165+
API requests. If ``None``, then default info will be used.
166+
Generally, you only need to set this if you are developing
167+
your own client library.
168+
always_use_jwt_access (Optional[bool]): Whether self signed JWT should
169+
be used for service account credentials.
170+
url_scheme: the protocol scheme for the API endpoint. Normally
171+
"https", but for testing or local servers,
172+
"http" can be specified.
173+
"""
174+
# Run the base constructor
175+
# TODO(yon-mg): resolve other ctor params i.e. scopes, quota, etc.
176+
# TODO: When custom host (api_endpoint) is set, `scopes` must *also* be set on the
177+
# credentials object
178+
maybe_url_match = re.match("^(?P<scheme>http(?:s)?://)?(?P<host>.*)$", host)
179+
if maybe_url_match is None:
180+
raise ValueError(
181+
f"Unexpected hostname structure: {host}"
182+
) # pragma: NO COVER
183+
184+
url_match_items = maybe_url_match.groupdict()
185+
186+
host = f"{url_scheme}://{host}" if not url_match_items["scheme"] else host
187+
188+
super().__init__(
189+
host=host,
190+
credentials=credentials,
191+
client_info=client_info,
192+
always_use_jwt_access=always_use_jwt_access,
193+
api_audience=api_audience,
194+
)
195+
self._session = AuthorizedSession(
196+
self._credentials, default_host=self.DEFAULT_HOST
197+
)
198+
if client_cert_source_for_mtls:
199+
self._session.configure_mtls_channel(client_cert_source_for_mtls)
200+
self._interceptor = interceptor or QuotaControllerRestInterceptor()
201+
self._prep_wrapped_messages(client_info)
202+
203+
class _AllocateQuota(QuotaControllerRestStub):
204+
def __hash__(self):
205+
return hash("AllocateQuota")
206+
207+
def __call__(
208+
self,
209+
request: quota_controller.AllocateQuotaRequest,
210+
*,
211+
retry: OptionalRetry = gapic_v1.method.DEFAULT,
212+
timeout: Optional[float] = None,
213+
metadata: Sequence[Tuple[str, str]] = (),
214+
) -> quota_controller.AllocateQuotaResponse:
215+
r"""Call the allocate quota method over HTTP.
216+
217+
Args:
218+
request (~.quota_controller.AllocateQuotaRequest):
219+
The request object. Request message for the AllocateQuota
220+
method.
221+
222+
retry (google.api_core.retry.Retry): Designation of what errors, if any,
223+
should be retried.
224+
timeout (float): The timeout for this request.
225+
metadata (Sequence[Tuple[str, str]]): Strings which should be
226+
sent along with the request as metadata.
227+
228+
Returns:
229+
~.quota_controller.AllocateQuotaResponse:
230+
Response message for the
231+
AllocateQuota method.
232+
233+
"""
234+
235+
http_options: List[Dict[str, str]] = [
236+
{
237+
"method": "post",
238+
"uri": "/v1/services/{service_name}:allocateQuota",
239+
"body": "*",
240+
},
241+
]
242+
request, metadata = self._interceptor.pre_allocate_quota(request, metadata)
243+
pb_request = quota_controller.AllocateQuotaRequest.pb(request)
244+
transcoded_request = path_template.transcode(http_options, pb_request)
245+
246+
# Jsonify the request body
247+
248+
body = json_format.MessageToJson(
249+
transcoded_request["body"],
250+
including_default_value_fields=False,
251+
use_integers_for_enums=True,
252+
)
253+
uri = transcoded_request["uri"]
254+
method = transcoded_request["method"]
255+
256+
# Jsonify the query params
257+
query_params = json.loads(
258+
json_format.MessageToJson(
259+
transcoded_request["query_params"],
260+
including_default_value_fields=False,
261+
use_integers_for_enums=True,
262+
)
263+
)
264+
265+
query_params["$alt"] = "json;enum-encoding=int"
266+
267+
# Send the request
268+
headers = dict(metadata)
269+
headers["Content-Type"] = "application/json"
270+
response = getattr(self._session, method)(
271+
"{host}{uri}".format(host=self._host, uri=uri),
272+
timeout=timeout,
273+
headers=headers,
274+
params=rest_helpers.flatten_query_params(query_params, strict=True),
275+
data=body,
276+
)
277+
278+
# In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception
279+
# subclass.
280+
if response.status_code >= 400:
281+
raise core_exceptions.from_http_response(response)
282+
283+
# Return the response
284+
resp = quota_controller.AllocateQuotaResponse()
285+
pb_resp = quota_controller.AllocateQuotaResponse.pb(resp)
286+
287+
json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True)
288+
resp = self._interceptor.post_allocate_quota(resp)
289+
return resp
290+
291+
@property
292+
def allocate_quota(
293+
self,
294+
) -> Callable[
295+
[quota_controller.AllocateQuotaRequest], quota_controller.AllocateQuotaResponse
296+
]:
297+
# The return type is fine, but mypy isn't sophisticated enough to determine what's going on here.
298+
# In C++ this would require a dynamic_cast
299+
return self._AllocateQuota(self._session, self._host, self._interceptor) # type: ignore
300+
301+
@property
302+
def kind(self) -> str:
303+
return "rest"
304+
305+
def close(self):
306+
self._session.close()
307+
308+
309+
__all__ = ("QuotaControllerRestTransport",)

google/cloud/servicecontrol_v1/services/service_controller/client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
from .transports.base import DEFAULT_CLIENT_INFO, ServiceControllerTransport
5252
from .transports.grpc import ServiceControllerGrpcTransport
5353
from .transports.grpc_asyncio import ServiceControllerGrpcAsyncIOTransport
54+
from .transports.rest import ServiceControllerRestTransport
5455

5556

5657
class ServiceControllerClientMeta(type):
@@ -66,6 +67,7 @@ class ServiceControllerClientMeta(type):
6667
) # type: Dict[str, Type[ServiceControllerTransport]]
6768
_transport_registry["grpc"] = ServiceControllerGrpcTransport
6869
_transport_registry["grpc_asyncio"] = ServiceControllerGrpcAsyncIOTransport
70+
_transport_registry["rest"] = ServiceControllerRestTransport
6971

7072
def get_transport_class(
7173
cls,

0 commit comments

Comments
 (0)