-
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 proper handling of query/path/body parameters for rest transport #702
Changes from 27 commits
c1a6f89
bd7c32d
cd3a7f1
b41db31
ce69e7d
89fa08b
86f3a9c
234cc09
35ac276
c8155a5
55a815c
ac0bdef
e79e8c7
824ad11
2d11e19
b5c6d06
221cd44
475f903
f08ca32
efa0ed6
d3e08c0
df88ef9
67c6bd1
37e3d28
c964fba
85be88d
5d1c6a3
f6c64cc
a4f34e7
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 |
---|---|---|
|
@@ -133,31 +133,59 @@ class {{ service.name }}RestTransport({{ service.name }}Transport): | |
{%- endif %} | ||
""" | ||
|
||
{%- if 'body' in method.http_opt.keys() %} | ||
# Jsonify the input | ||
data = {{ method.output.ident }}.to_json( | ||
{%- if method.http_opt['body'] == '*' %} | ||
{# TODO(yon-mg): refactor when implementing grpc transcoding | ||
- parse request pb & assign body, path params | ||
- shove leftovers into query params | ||
- make sure dotted nested fields preserved | ||
- format url and send the request | ||
#} | ||
{%- if 'body' in method.http_opt %} | ||
# Jsonify the request body | ||
{%- if method.http_opt['body'] != '*' %} | ||
body = {{ method.input.fields[method.http_opt['body']].type.ident }}.to_json( | ||
request.{{ method.http_opt['body'] }}, | ||
including_default_value_fields=False | ||
) | ||
{%- else %} | ||
body = {{ method.input.ident }}.to_json( | ||
request | ||
{%- else %} | ||
request.body | ||
{%- endif %} | ||
) | ||
{%- endif %} | ||
{%- endif %} | ||
|
||
{# TODO(yon-mg): Write helper method for handling grpc transcoding url #} | ||
# TODO(yon-mg): need to handle grpc transcoding and parse url correctly | ||
# current impl assumes simpler version of grpc transcoding | ||
# Send the request | ||
# current impl assumes basic case of grpc transcoding | ||
url = 'https://{host}{{ method.http_opt['url'] }}'.format( | ||
host=self._host, | ||
{%- for field in method.input.fields.keys() %} | ||
{%- for field in method.path_params %} | ||
{{ field }}=request.{{ field }}, | ||
{%- endfor %} | ||
) | ||
|
||
{# TODO(yon-mg): move all query param logic out of wrappers into here to handle | ||
nested fields correctly (can't just use set of top level fields | ||
#} | ||
# TODO(yon-mg): handle nested fields corerctly rather than using only top level fields | ||
# not required for GCE | ||
query_params = { | ||
{%- for field in method.query_params %} | ||
'{{ field|camel_case }}': request.{{ field }}, | ||
vchudnov-g marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{%- endfor %} | ||
} | ||
# TODO(yon-mg): further discussion needed whether 'python truthiness' is appropriate here | ||
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. Thanks for the TODO on truthiness! |
||
# discards default values | ||
# TODO(yon-mg): add test for proper url encoded strings | ||
query_params = ((k, v) for k, v in query_params.items() if v) | ||
for i, (param_name, param_value) in enumerate(query_params): | ||
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. nit: Do consider the string.Join suggestion from earlier (but it's certainly not a blocker) |
||
q = '?' if i == 0 else '&' | ||
url += "{q}{name}={value}".format(q=q, name=param_name, value=param_value.replace(' ', '+')) | ||
vchudnov-g marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Send the request | ||
{% if not method.void %}response = {% endif %}self._session.{{ method.http_opt['verb'] }}( | ||
url, | ||
{%- if 'body' in method.http_opt.keys() %} | ||
json=data, | ||
url | ||
{%- if 'body' in method.http_opt %}, | ||
json=body, | ||
{%- endif %} | ||
) | ||
{%- if not method.void %} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,3 +45,19 @@ def to_snake_case(s: str) -> str: | |
|
||
# Done; return the camel-cased string. | ||
return s.lower() | ||
|
||
|
||
def to_camel_case(s: str) -> str: | ||
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. Are there any built-in/standard python functions which do the same? Please prefer using standard ones to custom, if there are any. 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'm fairly certain there is no standard library function for to camel-case. |
||
'''Convert any string to camel case. | ||
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. nit: In this and the previous, pre-existing function, we're not touching spaces, right? Might be worth mentioning that. |
||
|
||
This is provided to templates as the ``camel_case`` filter. | ||
|
||
Args: | ||
s (str): The input string, provided in any sane case system | ||
|
||
Returns: | ||
str: The string in lower camel case. | ||
''' | ||
|
||
items = re.split(r'[_-]', to_snake_case(s)) | ||
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'm surprised by the hyphen Opinion, @software-dov ? 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 actually might handle it: I didn't check. As far as use, it doesn't get used but I wouldn't want a future user to attempt o try it and have it fail. 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. My vote: write a test for 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. If 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 doubt it would break anything since it's additive but this is why I didn't change 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. But the generator has already produced libraries that were published, so if one of those had a hyphen somewhere, it made it through |
||
return items[0].lower() + "".join(x.capitalize() for x in items[1:]) |
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.
Just curious: why can't
query_params
andpath_params
return the same type, rather than aSet
and aSequence
?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 suppose they could. Just thought it's more appropriate since ordering seems important for
path_params
but not forquery_params
.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.
As discussed. That seems reasonable, but a complication is that repeated fields map to repeated query params. In that case, a sequence may be best. (If order doesn't matter, a multiset might be enough, but we can't assume that order doesn't matter for repeated fields)
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.
You are right set is not appropriate even if order doesn't matter but I should mention though that once query param logic is moved out, this won't matter anymore.
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.
True!