Conversation
83a7fcf to
d43dedf
Compare
griffinmyers
left a comment
There was a problem hiding this comment.
This looks fantastic, @gckwan! I've requested a few cosmetic changes and the move to urlparse... after which I think we'll be ready to ship!
Because the API is backwards compatible, we'll also want to bump the package minor version and add a note to the CHANGELOG
|
|
||
| .. code:: python | ||
|
|
||
| client = Client("sk-XXX", { |
There was a problem hiding this comment.
Can you include from pybutton import Client? I'm trying to keep all code snippets atomically copy+pasteable
| 'hostname': 'api.testsite.com', | ||
| 'port': 80, | ||
| 'secure': False, | ||
| 'timeout': 5 |
There was a problem hiding this comment.
maybe 'timeout': 5 # seconds just to make sure people copy+pasting know the units... It's fairly common that timeouts are expressed in ms.
| https://app.usebutton.com/settings/organization. | ||
|
|
||
| config (dict): Configuration options for the client. Options include: | ||
| timeout: The time in ms for network requests to abort. Defaults to None. |
There was a problem hiding this comment.
nit: match ordering of README
| ''' | ||
|
|
||
| def __init__(self, api_key): | ||
| def __init__(self, api_key, config={}): |
There was a problem hiding this comment.
Python function (and bound method) definitions hold the memory for any default parameters. This means if you somehow mutate a default parameter argument (and believe me it happens) you'll be mutating the default for all following invocations. The "pythonic" move here is to default to None:
def __init__(self, api_key, config=None):
if config is None:
config = {}There was a problem hiding this comment.
weird! good to know, thanks.
|
|
||
| self.orders = Orders(api_key, config) | ||
|
|
||
| def _config_with_defaults(self, config): |
There was a problem hiding this comment.
Because this method doesn't actually need to be bound to self, we can just have this as a function in the file.
|
|
||
| def _request_url(self, path): | ||
| protocol = 'https://' if self.config['secure'] else 'http://' | ||
| return '{0}{1}:{2}{3}'.format(protocol, self.config['hostname'], self.config['port'], path) |
There was a problem hiding this comment.
I think at this point it makes sense to get some help from the python stdlib:
import urlparse
# 'http://api.usebutton.com/12/12'
urlparse.urlunsplit(('http', 'api.usebutton.com', '/12/12', '', ''))
# also 'http://api.usebutton.com/12/12'
urlparse.urlunsplit(('http', 'api.usebutton.com', '12/12', '', ''))| def __init__(self, api_key): | ||
| def __init__(self, api_key, config): | ||
| self.api_key = api_key | ||
| self.config = config |
There was a problem hiding this comment.
even though you're going to end up repeating it a lot, I think a docstring here explaining config makes sense (especially given all the keys are required at this point)
There was a problem hiding this comment.
Totally. Added config to the docstring above.
| # {'status': open, 'btn_ref': None, 'line_items': [], ...} | ||
|
|
||
| Configuration | ||
| --------- |
88f267e to
d950bfc
Compare
d950bfc to
05084cf
Compare
|
@griffinmyers Ping! No rush, but ready for another look whenever you have free time. |
|
👋 @gckwan cool! will take a look today! |
griffinmyers
left a comment
There was a problem hiding this comment.
A couple style nits, specifically please run the linter flake8. I saw a couple violations. You can get your own copy with pip install flake8.
Upshot: I tested locally and everything looks great functionality wise!
| @@ -1,2 +1,5 @@ | |||
| 1.0.2 August 11, 2016 | |||
| - Initial Release | |||
| 1.1.0 September 28, 2016 | |||
There was a problem hiding this comment.
nit: changelog should be sorted reverse chronological order
| 'hostname': config.get('hostname', 'api.usebutton.com'), | ||
| 'port': config.get('port', defaultPort) | ||
| } | ||
| def _config_with_defaults(config): |
There was a problem hiding this comment.
nit: because this isn't a private method to anything we can drop the _ prefix on the function name.
| 'secure': secure, | ||
| 'timeout': config.get('timeout'), | ||
| 'hostname': config.get('hostname', 'api.usebutton.com'), | ||
| 'port': config.get('port', defaultPort) |
There was a problem hiding this comment.
nit: as weird as it may seem, the python community seems to prefer trailing commas for multi-line dict/list elements. config.get('port', defaultPort),
There was a problem hiding this comment.
I actually like trailing commas, myself! No need to add/remove commas when reordering values/adding new lines.
There was a problem hiding this comment.
The airbnb styleguide is pro-trailing commas too: https://github.com/airbnb/javascript#commas--dangling
There was a problem hiding this comment.
still need to add trailing commas! I've seen some in README / tests we should make sure get them as well.
There was a problem hiding this comment.
Derp, got too focused on the flake8 output. Adding them now.
| protocol = 'https://' if self.config['secure'] else 'http://' | ||
| return '{0}{1}:{2}{3}'.format(protocol, self.config['hostname'], self.config['port'], path) | ||
| protocol = 'https' if self.config['secure'] else 'http' | ||
| return urlparse.urlunsplit((protocol, '{0}:{1}'.format(self.config['hostname'], self.config['port']), path, '', '')) |
There was a problem hiding this comment.
nit: I try go give best effort to keeping under 80 columns. This could easily be split up with 1 argument per line or maybe by allocating the hostname/port string ahead of the #urlunsplit call
|
flake8 should pass now :) |
| raise ButtonClientError('Invalid response: {0}'.format(response)) | ||
|
|
||
| __all__ = [Request, urlopen, HTTPError, request] | ||
| def request_url(secure, hostname, port, path): |
There was a problem hiding this comment.
because this is the exact same implementation as the one on line 117, we can simply import each urlunsplit in the if/else and the define request_url and __all__ at the bottom of the file, once. Also, would you mind adding a Args/Returns to the docstring on this because it's used external to this file?
|
Looks awesome! When you merge, please select the Squash and merge option. Then we can publish! |
Description
Add hostname, secure, port, timeout options
Test Plan