Skip to content

python client for the Button Order API

License

Notifications You must be signed in to change notification settings

button/button-client-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

button-client-python Build Status

This module is a thin client for interacting with Button's API.

Please see the full API Docs for more information. For help, check out our Support page or get in touch.

Supported runtimes

  • cPython 2.7, 3.4, 3.5, 3.6, 3.7

Dependencies

  • None

Usage

pip install pybutton

To create a client capable of making network requests, instantiate a pybutton.Client with your API key.

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:

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:

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

All
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.
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
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
import hashlib
from pybutton import Client

client = Client('sk-XXX')

hashed_email = hashlib.sha256('[email protected]'.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
from pybutton import Client

client = Client('sk-XXX')

response = client.orders.get('btnorder-XXX')

print(response)
# <class pybutton.Response total: 50, currency: 'USD', ...>
Update
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
from pybutton import Client

client = Client('sk-XXX')

response = client.orders.delete('btnorder-XXX')

print(response)
# <class pybutton.Response >

Links

Create
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
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
import hashlib
from pybutton import Client

client = Client('sk-XXX')

hashed_email = hashlib.sha256('[email protected]'.lower().strip()).hexdigest()

response = client.customers.create({
    'id': 'customer-1234',
    'email_sha256': hashed_email,
})

print(response)
# <class pybutton.Response id: customer-1234, ...>
Get
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.
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
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.

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.

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 for more details.

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)