-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add rest transport generation for clients with optional flag #688
Changes from all commits
c1a6f89
bd7c32d
cd3a7f1
b41db31
ce69e7d
89fa08b
86f3a9c
234cc09
35ac276
c8155a5
55a815c
ac0bdef
e79e8c7
824ad11
2d11e19
b5c6d06
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -719,6 +719,8 @@ def _client_output(self, enable_asyncio: bool): | |
# Return the usual output. | ||
return self.output | ||
|
||
# TODO(yon-mg): remove or rewrite: don't think it performs as intended | ||
# e.g. doesn't work with basic case of gRPC transcoding | ||
@property | ||
def field_headers(self) -> Sequence[str]: | ||
"""Return the field headers defined for this method.""" | ||
|
@@ -737,6 +739,35 @@ def field_headers(self) -> Sequence[str]: | |
|
||
return next((tuple(pattern.findall(verb)) for verb in potential_verbs if verb), ()) | ||
|
||
@property | ||
def http_opt(self) -> Optional[Dict[str, str]]: | ||
"""Return the http option for this method. | ||
|
||
e.g. {'verb': 'post' | ||
'url': '/some/path' | ||
'body': '*'} | ||
|
||
""" | ||
http: List[Tuple[descriptor_pb2.FieldDescriptorProto, str]] | ||
http = self.options.Extensions[annotations_pb2.http].ListFields() | ||
|
||
if len(http) < 1: | ||
return None | ||
|
||
http_method = http[0] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on our offline discussion, I suggest s/ |
||
answer: Dict[str, str] = { | ||
'verb': http_method[0].name, | ||
'url': http_method[1], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider having "template" in the name: maybe |
||
} | ||
if len(http) > 1: | ||
body_spec = http[1] | ||
answer[body_spec[0].name] = body_spec[1] | ||
|
||
# TODO(yon-mg): handle nested fields & fields past body i.e. 'additional bindings' | ||
# TODO(yon-mg): enums for http verbs? | ||
return answer | ||
|
||
# TODO(yon-mg): refactor as there may be more than one method signature | ||
@utils.cached_property | ||
def flattened_fields(self) -> Mapping[str, Field]: | ||
"""Return the signature defined for this method.""" | ||
|
@@ -786,6 +817,7 @@ def grpc_stub_type(self) -> str: | |
server='stream' if self.server_streaming else 'unary', | ||
) | ||
|
||
# TODO(yon-mg): figure out why idempotent is reliant on http annotation | ||
@utils.cached_property | ||
def idempotent(self) -> bool: | ||
"""Return True if we know this method is idempotent, False otherwise. | ||
|
@@ -980,6 +1012,10 @@ def grpc_transport_name(self): | |
def grpc_asyncio_transport_name(self): | ||
return self.name + "GrpcAsyncIOTransport" | ||
|
||
@property | ||
def rest_transport_name(self): | ||
return self.name + "RestTransport" | ||
|
||
@property | ||
def has_lro(self) -> bool: | ||
"""Return whether the service has a long-running method.""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -151,6 +151,9 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport): | |
) | ||
|
||
self._stubs = {} # type: Dict[str, Callable] | ||
{%- if service.has_lro %} | ||
self._operations_client = None | ||
{%- endif %} | ||
|
||
# Run the base constructor. | ||
super().__init__( | ||
|
@@ -172,7 +175,7 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport): | |
**kwargs) -> grpc.Channel: | ||
"""Create and return a gRPC channel object. | ||
Args: | ||
address (Optionsl[str]): The host for the channel to use. | ||
software-dov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
address (Optional[str]): The host for the channel to use. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was this changed (looks unrelated to your changes)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I approve of fixing typos on the fly! |
||
credentials (Optional[~.Credentials]): The | ||
authorization credentials to attach to requests. These | ||
credentials identify this application to the service. If | ||
|
@@ -220,13 +223,13 @@ class {{ service.name }}GrpcTransport({{ service.name }}Transport): | |
client. | ||
""" | ||
# Sanity check: Only create a new client if we do not already have one. | ||
if 'operations_client' not in self.__dict__: | ||
self.__dict__['operations_client'] = operations_v1.OperationsClient( | ||
if self._operations_client is None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. won't There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a little bit complicated. Some values can be falsy even if they are non-null, e.g. empty lists and strings. |
||
self._operations_client = operations_v1.OperationsClient( | ||
self.grpc_channel | ||
) | ||
|
||
# Return the client from cache. | ||
return self.__dict__['operations_client'] | ||
return self._operations_client | ||
{%- endif %} | ||
{%- for method in service.methods.values() %} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -205,6 +205,9 @@ class {{ service.grpc_asyncio_transport_name }}({{ service.name }}Transport): | |
) | ||
|
||
self._stubs = {} | ||
{%- if service.has_lro %} | ||
self._operations_client = None | ||
{%- endif %} | ||
|
||
@property | ||
def grpc_channel(self) -> aio.Channel: | ||
|
@@ -225,13 +228,13 @@ class {{ service.grpc_asyncio_transport_name }}({{ service.name }}Transport): | |
client. | ||
""" | ||
# Sanity check: Only create a new client if we do not already have one. | ||
if 'operations_client' not in self.__dict__: | ||
self.__dict__['operations_client'] = operations_v1.OperationsAsyncClient( | ||
if self._operations_client is None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are you changing this code (looks unrelated to http transport stuff)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #688 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 for consistency |
||
self._operations_client = operations_v1.OperationsAsyncClient( | ||
self.grpc_channel | ||
) | ||
|
||
# Return the client from cache. | ||
return self.__dict__['operations_client'] | ||
return self._operations_client | ||
{%- endif %} | ||
{%- for method in service.methods.values() %} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think a type declaration or a comment saying this is a
List[Tuple[FieldDescriptor, str]]
would be helpful.