button-client-python |Build Status|
This module is a thin client for interacting with Button's API.
Please see the full API Docs <https://www.usebutton.com/developers/api-reference>
__ for more
information. For help, check out our
Support <https://www.usebutton.com/support>
__ page or get in touch <https://www.usebutton.com/contact>
__.
Supported runtimes
^^^^^^^^^^^^^^^^^^
- cPython
2.7
, 3.4
, 3.5
, 3.6
, 3.7
Dependencies
^^^^^^^^^^^^
Usage
.. code:: bash
pip install pybutton
To create a client capable of making network requests, instantiate a
pybutton.Client
with your API key <https://app.usebutton.com/settings/organization>
__.
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
The client will always attempt to raise a pybutton.ButtonClientError
or a subclass in an error condition.
All API requests will return a pybutton.response.Response
instance,
which supports accessing data via the #data
method. For instance:
.. code:: python
from pybutton import Client
from pybutton import ButtonClientError, HTTPResponseError
client = Client("sk-XXX")
try:
response = client.orders.get("btnorder-XXX")
except HTTPResponseError as e:
print('API request failed: http status {}'.format(e.status_code))
except ButtonClientError as e:
print(e)
else:
print(response)
# <class pybutton.Response status: open, btn_ref: None, line_items: [], ...>
print(response.data())
# {'status': open, 'btn_ref': None, 'line_items': [], ...}
Configuration
You may optionally supply a config argument with your API key:
.. code:: python
from pybutton import Client
client = Client("sk-XXX", {
'hostname': 'api.testsite.com',
'port': 80,
'secure': False,
'timeout': 5, # seconds
})
The supported options are as follows:
hostname
: Defaults to api.usebutton.com
.port
: Defaults to 443
if config.secure
, else defaults to 80
.secure
: Whether or not to use HTTPS. Defaults to True
. N.B: Button's API is only exposed through HTTPS. This option is provided purely as a convenience for testing and development.timeout
: The time in seconds that may elapse before network requests abort. Defaults to None
.
Resources
We currently expose the following resources to manage:
Accounts
_Merchants
_Orders
_Customers
_Links
_Transactions
_
Accounts
All
'''
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.accounts.all()
print(response)
# <class pybutton.Response [2 elements]>
Transactions (per-account)
''''''''''''''''''''''''''
Along with the required account ID, you may also
pass the following optional arguments:
* ``cursor`` (string): An API cursor to fetch a specific set of results.
* ``start`` (ISO-8601 datetime string): Fetch transactions after this time.
* ``end`` (ISO-8601 datetime string): Fetch transactions before this time.
* ``time_field`` (string): Which time field ``start`` and ``end`` filter on.
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.accounts.transactions(
'acc-123',
start='2016-07-15T00:00:00.000Z',
end='2016-09-30T00:00:00.000Z'
)
print(response)
# <class pybutton.Response [100 elements]>
Merchants
All
'''
You may pass the following optional arguments:
status
(string): Partnership status to filter by. One of ('approved', 'pending', or 'available')currency
(ISO-4217 string): Currency code to filter returned rates by
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.merchants.all()
print(response)
# <class pybutton.Response [23 elements]>
Orders
**n.b: all currency values should be reported in the smallest possible
unit of that denomination, i.e. $1.00 should be reported as 100
(i.e. 100 pennies)**
Create
''''''
.. code:: python
import hashlib
from pybutton import Client
client = Client('sk-XXX')
hashed_email = hashlib.sha256('user@example.com'.lower().strip()).hexdigest()
response = client.orders.create({
'total': 50,
'currency': 'USD',
'order_id': '2007',
'purchase_date': '2017-07-25T08:23:52Z',
'finalization_date': '2017-08-02T19:26:08Z',
'btn_ref': 'srctok-XXX',
'customer': {
'id': 'mycustomer-1234',
'email_sha256': hashed_email,
},
})
print(response)
# <class pybutton.Response total: 50, currency: 'USD', ...>
Get
'''
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.orders.get('btnorder-XXX')
print(response)
# <class pybutton.Response total: 50, currency: 'USD', ...>
Update
''''''
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.orders.update('btnorder-XXX', {
'total': 60,
})
print(response)
# <class pybutton.Response total: 60, currency: 'USD', ...>
Delete
''''''
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.orders.delete('btnorder-XXX')
print(response)
# <class pybutton.Response >
Links
Create
''''''
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.links.create({
'url': 'https://www.jet.com',
"experience": {
'btn_pub_ref': 'my-pub-ref',
'btn_pub_user': 'user-id',
},
})
print(response)
# <class pybutton.Response merchant_id: org-XXXXXXXXXXXXXXX, ...>
Get Info
''''''''
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.links.get_info({
"url": "https://www.jet.com",
})
print(response)
# <class pybutton.Response merchant_id: org-XXXXXXXXXXXXXXX, ...>
Customers
Create
''''''
.. code:: python
import hashlib
from pybutton import Client
client = Client('sk-XXX')
hashed_email = hashlib.sha256('user@example.com'.lower().strip()).hexdigest()
response = client.customers.create({
'id': 'customer-1234',
'email_sha256': hashed_email,
})
print(response)
# <class pybutton.Response id: customer-1234, ...>
Get
'''
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.customers.get('customer-1234')
print(response)
# <class pybutton.Response id: customer-1234, ...>
Transactions
All
'''
You may pass the following optional arguments:
cursor
(string): An API cursor to fetch a specific set of results.start
(ISO-8601 datetime string): Fetch transactions after this time.end
(ISO-8601 datetime string): Fetch transactions before this time.time_field
(string): Which time field start
and end
filter on.
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.transactions(
start='2016-07-15T00:00:00.000Z',
end='2016-09-30T00:00:00.000Z',
time_field='modified_date',
)
print(response)
# <class pybutton.Response [100 elements]>
Response
Methods
data
''''
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.orders.get('btnorder-XXX')
print(response.data())
# {'total': 50, 'currency': 'USD', 'status': 'open' ... }
response = client.accounts.all()
print(response.data())
# [{'id': 'acc-123', ... }, {'id': 'acc-234', ... }]
next_cursor
'''''''''''
For any paged resource, ``next_cursor()`` will return a cursor to
supply for the next page of results. If ``next_cursor()`` returns ``None``,
there are no more results.
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.accounts.transactions('acc-123')
cursor = response.next_cursor()
# loop through and print all transactions
while cursor:
response = client.accounts.transactions('acc-123', cursor=cursor)
print(response.data())
cursor = response.next_cursor()
prev_cursor
'''''''''''
For any paged resource, ``prev_cursor()`` will return a cursor to
supply for the next page of results. If ``prev_cursor()`` returns
``None``, there are no more previous results.
.. code:: python
from pybutton import Client
client = Client('sk-XXX')
response = client.accounts.transactions('acc-123', cursor='xyz')
print(response)
# <class pybutton.Response [25 elements]>
cursor = response.prev_cursor()
response = client.accounts.transactions('acc-123', cursor=cursor)
print(response)
# <class pybutton.Response [100 elements]>
Utils
---------
Utils houses generic helpers useful in a Button Integration.
#is_webhook_authentic
Used to verify that requests sent to a webhook endpoint are from Button and that
their payload can be trusted. Returns True
if a webhook request body matches
the sent signature and False
otherwise. See Webhook Security <https://www.usebutton.com/developers/webhooks/#security>
__ for more details.
.. code:: python
import os
from pybutton.utils import is_webhook_authentic
is_webhook_authentic(
os.environ['WEBHOOK_SECRET'],
request.data,
request.headers.get('X-Button-Signature')
)
Contributing
- Building the egg:
python setup.py bdist_egg
- Building the wheel:
python setup.py bdist_wheel --universal
- Building the sdist:
python setup.py sdist
- Installing locally:
python setup.py install
- Running tests:
python setup.py test
(you'll need to pip install flake8==3.3.0
) - Running lint directly:
flake8 pybutton
- Running tests on all versions:
tox
(need to pip install tox
and something like pyenv local 2.7.10 3.4.6 3.5.3 3.6.0
if using pyenv
)
.. |Build Status| image:: https://travis-ci.org/button/button-client-python.svg?branch=master
:target: https://travis-ci.org/button/button-client-python