Skip to content

Metadata query params #29

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

Merged
merged 11 commits into from
Aug 18, 2021
Merged

Metadata query params #29

merged 11 commits into from
Aug 18, 2021

Conversation

kleinjm
Copy link
Contributor

@kleinjm kleinjm commented Aug 11, 2021

What

  • Generating the SDK after changes to the swagger.json file
  • Adds ability to query orders index with metadata
  • Fixes the creation of orders with metadata

Why

Clients want the ability to query orders via metadata.

SDK Release Checklist

  • Have you added an integration test for the changes?
  • Have you built the library locally and made queries against it successfully?
  • Did you update the changelog?
  • Did you bump the package version?
  • For breaking changes, did you plan for the release of the new SDK versions and deploy the API to production?

@kleinjm kleinjm requested review from pcothenet and removed request for pcothenet August 11, 2021 23:14
Comment on lines +723 to +730
# do not add duplicate keys to query_params list
existing_keys = []
for param in query_params:
existing_keys.append(param[0])

for key in kwargs:
if key not in existing_keys:
query_params.append([key, kwargs.get(key)])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the place in which this new logic is most relevant. Previously, a named query param would appear twice because all args were added to the params list even if they already matched one of the conditionals above

Comment on lines 114 to 164
def recursive_urlencode(self, d):
"""URL-encode a multidimensional dictionary.

>>> data = {'a': 'b&c', 'd': {'e': {'f&g': 'h*i'}}, 'j': 'k'}
>>> recursive_urlencode(data)
u'a=b%26c&j=k&d[e][f%26g]=h%2Ai'
"""

def recursion(d, base=[]):
pairs = []

for key, value in d.items():
new_base = base + [key]
if hasattr(value, "values"):
pairs += recursion(value, new_base)
else:
new_pair = None
if len(new_base) > 1:
first = urllib.parse.quote(new_base.pop(0))
rest = map(lambda x: urllib.parse.quote(x), new_base)
new_pair = "%s[%s]=%s" % (
first,
"][".join(rest),
urllib.parse.quote(str(value)),
)
else:
new_pair = "%s=%s" % (
urllib.parse.quote(str(key)),
urllib.parse.quote(str(value)),
)
pairs.append(new_pair)
return pairs

return "&".join(recursion(d))

def encoded_query_params(self, query_params):
if not query_params:
return ""

final_query_params = ""
for key, value in query_params:
if isinstance(value, dict):
nested_param = {}
nested_param[key] = value
final_query_params += self.recursive_urlencode(nested_param)
query_params.remove((key, value))

if query_params:
final_query_params += "&" + urlencode(query_params)

return "?" + final_query_params
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is all custom code. I took recursive_urlencode from a stackoverflow answer and modified it to work with python3.
encoded_query_params is a method I wrote

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a chance we could unit test those two methods? I trust the global test but this might save some pain later.

Comment on lines +56 to +57
self.assertEqual(estimate.data.order.mass_g, 1000622)
self.assertEqual(estimate.data.mass_g, 1000622)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirmed this change is correct with Brendan

@@ -75,7 +75,7 @@ def test_create_and_retrieve_shipping_estimate(self):
)
self.assertEqual(estimate.data.order, None)
self.assertEqual(estimate.data.type, "shipping")
self.assertEqual(estimate.data.mass_g, 373)
self.assertEqual(estimate.data.mass_g, 249)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirmed this change is correct with Brendan

@kleinjm kleinjm requested a review from pcothenet August 17, 2021 19:29

### Added

- Fixed ability to create Orders with `metadata`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

@pcothenet pcothenet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall. This library does like repeating itself though.

Open question about unit-testing the query params method.

### Added

- Fixed ability to create Orders with `metadata`
- Add support for querying Orders by `metadata`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the new ETH parameter here as well?

Comment on lines +1062 to +1070

# do not add duplicate keys to query_params list
existing_keys = []
for param in query_params:
existing_keys.append(param[0])

for key in kwargs:
query_params.append([key, kwargs.get(key)])
if key not in existing_keys:
query_params.append([key, kwargs.get(key)])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll probably want to address the fact that this is duplicated several times over?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose but this logic does seem useful to have in each case so there aren't duplicate params in the list

Comment on lines 114 to 164
def recursive_urlencode(self, d):
"""URL-encode a multidimensional dictionary.

>>> data = {'a': 'b&c', 'd': {'e': {'f&g': 'h*i'}}, 'j': 'k'}
>>> recursive_urlencode(data)
u'a=b%26c&j=k&d[e][f%26g]=h%2Ai'
"""

def recursion(d, base=[]):
pairs = []

for key, value in d.items():
new_base = base + [key]
if hasattr(value, "values"):
pairs += recursion(value, new_base)
else:
new_pair = None
if len(new_base) > 1:
first = urllib.parse.quote(new_base.pop(0))
rest = map(lambda x: urllib.parse.quote(x), new_base)
new_pair = "%s[%s]=%s" % (
first,
"][".join(rest),
urllib.parse.quote(str(value)),
)
else:
new_pair = "%s=%s" % (
urllib.parse.quote(str(key)),
urllib.parse.quote(str(value)),
)
pairs.append(new_pair)
return pairs

return "&".join(recursion(d))

def encoded_query_params(self, query_params):
if not query_params:
return ""

final_query_params = ""
for key, value in query_params:
if isinstance(value, dict):
nested_param = {}
nested_param[key] = value
final_query_params += self.recursive_urlencode(nested_param)
query_params.remove((key, value))

if query_params:
final_query_params += "&" + urlencode(query_params)

return "?" + final_query_params
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a chance we could unit test those two methods? I trust the global test but this might save some pain later.

Comment on lines 53 to 54
encoded_params = client.encoded_query_params([('mass_g', 100)])
self.assertEqual(encoded_params, "?mass_g=100")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pcothenet unit tests added 🥳 and they caught a small issue of adding an extra & to the url

@kleinjm kleinjm merged commit 968663f into main Aug 18, 2021
@kleinjm kleinjm deleted the jklein/metadata_query branch August 18, 2021 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants