Skip to content

Commit 44b7ff2

Browse files
lukesneeringercrwilcox
authored andcommitted
Add methods to api_core used by new autogenerator. (#6267)
* Add dispatch and deserialize methods. This adds convenience methods used by client libraries produced by gapic-generator-python. * Mark test as Python 3 only. * Fix import order. * Address @theacodes feedback. * Move dispatch to gapic_v2; alias remaining gapic_v1 modules. * Fix import order.
1 parent 108f9d4 commit 44b7ff2

File tree

5 files changed

+120
-0
lines changed

5 files changed

+120
-0
lines changed

google/api_core/gapic_v2/__init__.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2018 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from google.api_core.gapic_v1 import client_info
16+
from google.api_core.gapic_v1 import config
17+
from google.api_core.gapic_v1 import method
18+
from google.api_core.gapic_v1 import routing_header
19+
from google.api_core.gapic_v2 import dispatch
20+
21+
__all__ = [
22+
'client_info',
23+
'config',
24+
'dispatch',
25+
'method',
26+
'routing_header',
27+
]

google/api_core/gapic_v2/dispatch.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2018 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import functools
16+
17+
18+
def dispatch(func):
19+
"""Return a decorated method that dispatches on the second argument.
20+
21+
This is the equivalent of :meth:`functools.singledispatch`, but for
22+
bound methods.
23+
"""
24+
base_dispatcher = functools.singledispatch(func)
25+
26+
# Define a wrapper function that works off args[1] instead of args[0].
27+
# This is needed because we are overloading *methods*, and their first
28+
# argument is always `self`.
29+
@functools.wraps(base_dispatcher)
30+
def wrapper(*args, **kwargs):
31+
return base_dispatcher.dispatch(args[1].__class__)(*args, **kwargs)
32+
33+
# The register function is not changed, so let singledispatch do the work.
34+
wrapper.register = base_dispatcher.register
35+
36+
# Done; return the decorated method.
37+
return wrapper

google/api_core/operation.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ def metadata(self):
9494
return protobuf_helpers.from_any_pb(
9595
self._metadata_type, self._operation.metadata)
9696

97+
@classmethod
98+
def deserialize(self, payload):
99+
"""Deserialize a ``google.longrunning.Operation`` protocol buffer.
100+
101+
Args:
102+
payload (bytes): A serialized operation protocol buffer.
103+
104+
Returns:
105+
~.operations_pb2.Operation: An Operation protobuf object.
106+
"""
107+
return operations_pb2.Operation.FromString(payload)
108+
97109
def _set_result_from_operation(self):
98110
"""Set the result or exception from the operation if it is complete."""
99111
# This must be done in a lock to prevent the polling thread

tests/unit/gapic/test_dispatch.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright 2018 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import pytest
16+
import six
17+
18+
from google.api_core.gapic_v2.dispatch import dispatch
19+
20+
21+
@pytest.mark.skipif(six.PY2, reason='dispatch only works on Python 3.')
22+
def test_dispatch():
23+
class Foo(object):
24+
@dispatch
25+
def bar(self, number, letter):
26+
return 'Brought by the letter {} and the number {}.'.format(
27+
letter, number,
28+
)
29+
30+
@bar.register(str)
31+
def _bar_with_string(self, letter):
32+
return self.bar(11, letter)
33+
34+
foo = Foo()
35+
assert foo.bar(8, 'L') == 'Brought by the letter L and the number 8.'
36+
assert foo.bar('Z') == 'Brought by the letter Z and the number 11.'

tests/unit/test_operation.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,11 @@ def test_from_gapic():
221221
assert future._metadata_type == struct_pb2.Struct
222222
assert future.operation.name == TEST_OPERATION_NAME
223223
assert future.done
224+
225+
226+
def test_deserialize():
227+
op = make_operation_proto(name='foobarbaz')
228+
serialized = op.SerializeToString()
229+
deserialized_op = operation.Operation.deserialize(serialized)
230+
assert op.name == deserialized_op.name
231+
assert type(op) is type(deserialized_op)

0 commit comments

Comments
 (0)