Metadata query params#29
Conversation
| # 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)]) |
There was a problem hiding this comment.
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
| 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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Is there a chance we could unit test those two methods? I trust the global test but this might save some pain later.
| self.assertEqual(estimate.data.order.mass_g, 1000622) | ||
| self.assertEqual(estimate.data.mass_g, 1000622) |
There was a problem hiding this comment.
I confirmed this change is correct with Brendan
| 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) |
There was a problem hiding this comment.
I confirmed this change is correct with Brendan
|
|
||
| ### Added | ||
|
|
||
| - Fixed ability to create Orders with `metadata` |
pcothenet
left a comment
There was a problem hiding this comment.
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` |
There was a problem hiding this comment.
Can you add the new ETH parameter here as well?
|
|
||
| # 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)]) |
There was a problem hiding this comment.
We'll probably want to address the fact that this is duplicated several times over?
There was a problem hiding this comment.
I suppose but this logic does seem useful to have in each case so there aren't duplicate params in the list
| 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 |
There was a problem hiding this comment.
Is there a chance we could unit test those two methods? I trust the global test but this might save some pain later.
| encoded_params = client.encoded_query_params([('mass_g', 100)]) | ||
| self.assertEqual(encoded_params, "?mass_g=100") |
There was a problem hiding this comment.
@pcothenet unit tests added 🥳 and they caught a small issue of adding an extra & to the url
What
Why
Clients want the ability to query orders via metadata.
SDK Release Checklist