Skip to main content

Official Dwolla V2 API client

Project description

DwollaV2
========

.. figure:: https://travis-ci.org/Dwolla/dwolla-v2-python.svg
:alt: Build Status

Build Status
Dwolla V2 Python client.

`API Documentation <https://docsv2.dwolla.com>`__

Installation
------------

``dwollav2`` is available on
`PyPi <https://pypi.python.org/pypi/dwollav2>`__, and therefore can be
installed automagically via
`pip <https://pip.pypa.io/en/stable/installing/>`__.

::

pip install dwollav2

``dwollav2.Client``
-------------------

Basic usage
~~~~~~~~~~~

Create a client using your application's consumer key and secret found
on the applications page
(`Sandbox <https://dashboard-sandbox.dwolla.com/applications>`__,
`Production <https://dashboard.dwolla.com/applications>`__).

.. code:: python

client = dwollav2.Client(id = os.environ['DWOLLA_APP_KEY'], secret = os.environ['DWOLLA_APP_SECRET'])

Using the sandbox environment (optional)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code:: python

client = dwollav2.Client(
key = os.environ['DWOLLA_APP_KEY'],
secret = os.environ['DWOLLA_APP_SECRET'],
environment = 'sandbox'
)

``environment`` defaults to ``'production'``.

Configure an ``on_grant`` callback (optional)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

An ``on_grant`` callback is useful for storing new tokens when they are
granted. The ``on_grant`` callback is called with the ``Token`` that was
just granted by the server.

.. code:: python

client = dwollav2.Client(
key = os.environ['DWOLLA_APP_KEY'],
secret = os.environ['DWOLLA_APP_SECRET'],
on_grant = lambda t: save(t)
)

It is highly recommended that you encrypt any token data you store.

``Token``
---------

Tokens can be used to make requests to the Dwolla V2 API.

Application tokens
~~~~~~~~~~~~~~~~~~

Application access tokens are used to authenticate against the API on
behalf of a consumer application. Application tokens can be used to
access resources in the API that either belong to the application itself
(``webhooks``, ``events``, ``webhook-subscriptions``) or the partner
Account that owns the consumer application (``accounts``, ``customers``,
``funding-sources``, etc.). Application tokens are obtained by using the
```client_credentials`` <https://tools.ietf.org/html/rfc6749#section-4.4>`__
OAuth grant type:

.. code:: python

application_token = client.Auth.client()

*Application tokens do not include a ``refresh_token``. When an
application token expires, generate a new one using
``client.Auth.client()``.*

Initializing pre-existing tokens:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

``Token``\ s can be initialized with the following attributes:

.. code:: python

client.Token(access_token = '...',
expires_in = 123)

Requests
--------

``Token``\ s can make requests using the ``#get``, ``#post``, and
``#delete`` methods.

.. code:: python

# GET api.dwolla.com/resource?foo=bar
token.get('resource', foo = 'bar')

# POST api.dwolla.com/resource {"foo":"bar"}
token.post('resource', foo = 'bar')

# POST api.dwolla.com/resource multipart/form-data foo=...
token.post('resource', foo = ('mclovin.jpg', open('mclovin.jpg', 'rb'), 'image/jpeg'))

# PUT api.dwolla.com/resource {"foo":"bar"}
token.put('resource', foo = 'bar')

# DELETE api.dwolla.com/resource
token.delete('resource')

Setting headers
^^^^^^^^^^^^^^^

To set additional headers on a request you can pass a ``dict`` of
headers as the 3rd argument.

For example:

.. code:: python

token.post('customers', { 'firstName': 'John', 'lastName': 'Doe', 'email': 'jd@doe.com' },
{ 'Idempotency-Key': 'a52fcf63-0730-41c3-96e8-7147b5d1fb01' })

Responses
---------

Requests return a ``Response``.

.. code:: python

res = token.get('/')

res.status
# => 200

res.headers
# => {'server'=>'cloudflare-nginx', 'date'=>'Mon, 28 Mar 2016 15:30:23 GMT', 'content-type'=>'application/vnd.dwolla.v1.hal+json; charset=UTF-8', 'content-length'=>'150', 'connection'=>'close', 'set-cookie'=>'__cfduid=d9dcd0f586c166d36cbd45b992bdaa11b1459179023; expires=Tue, 28-Mar-17 15:30:23 GMT; path=/; domain=.dwolla.com; HttpOnly', 'x-request-id'=>'69a4e612-5dae-4c52-a6a0-2f921e34a88a', 'cf-ray'=>'28ac1f81875941e3-MSP'}

res.body['_links']['events']['href']
# => 'https://api-sandbox.dwolla.com/events'

Errors
------

If the server returns an error, a ``dwollav2.Error`` (or one of its
subclasses) will be raised. ``dwollav2.Error``\ s are similar to
``Response``\ s.

.. code:: python

try:
token.get('/not-found')
except dwollav2.NotFoundError:
e.status
# => 404

e.headers
# => {"server"=>"cloudflare-nginx", "date"=>"Mon, 28 Mar 2016 15:35:32 GMT", "content-type"=>"application/vnd.dwolla.v1.hal+json; profile=\"http://nocarrier.co.uk/profiles/vnd.error/\"; charset=UTF-8", "content-length"=>"69", "connection"=>"close", "set-cookie"=>"__cfduid=da1478bfdf3e56275cd8a6a741866ccce1459179332; expires=Tue, 28-Mar-17 15:35:32 GMT; path=/; domain=.dwolla.com; HttpOnly", "access-control-allow-origin"=>"*", "x-request-id"=>"667fca74-b53d-43db-bddd-50426a011881", "cf-ray"=>"28ac270abca64207-MSP"}

e.body.code
# => "NotFound"
except dwollav2.Error:
# ...

``dwollav2.Error`` subclasses:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*See https://docsv2.dwolla.com/#errors for more info.*

- ``dwollav2.AccessDeniedError``
- ``dwollav2.InvalidCredentialsError``
- ``dwollav2.NotFoundError``
- ``dwollav2.BadRequestError``
- ``dwollav2.InvalidGrantError``
- ``dwollav2.RequestTimeoutError``
- ``dwollav2.ExpiredAccessTokenError``
- ``dwollav2.InvalidRequestError``
- ``dwollav2.ServerError``
- ``dwollav2.ForbiddenError``
- ``dwollav2.InvalidResourceStateError``
- ``dwollav2.TemporarilyUnavailableError``
- ``dwollav2.InvalidAccessTokenError``
- ``dwollav2.InvalidScopeError``
- ``dwollav2.UnauthorizedClientError``
- ``dwollav2.InvalidAccountStatusError``
- ``dwollav2.InvalidScopesError``
- ``dwollav2.UnsupportedGrantTypeError``
- ``dwollav2.InvalidApplicationStatusError``
- ``dwollav2.InvalidVersionError``
- ``dwollav2.UnsupportedResponseTypeError``
- ``dwollav2.InvalidClientError``
- ``dwollav2.MethodNotAllowedError``
- ``dwollav2.ValidationError``
- ``dwollav2.TooManyRequestsError``
- ``dwollav2.ConflictError``

Development
-----------

After checking out the repo, run ``pip install -r requirements.txt`` to
install dependencies. Then, run ``python setup.py test`` to run the
tests.

To install this gem onto your local machine, run ``pip install -e .``.

Contributing
------------

Bug reports and pull requests are welcome on GitHub at
https://github.com/Dwolla/dwolla-v2-python.

License
-------

The package is available as open source under the terms of the `MIT
License <https://github.com/Dwolla/dwolla-v2-python>`__.

Changelog
---------

- **1.2.4** Create a new session for each Token.
- **1.2.3** Check if IOBase when checking to see if something is a
file.
- **1.2.2** Strip domain from URLs provided to token.\* methods.
- **1.2.1** Update sandbox URLs from uat => sandbox.
- **1.2.0** Refer to Client id as key.
- **1.1.8** Support ``verified_account`` and ``dwolla_landing`` auth
flags
- **1.1.7** Use session over connections for `performance
improvement <http://docs.python-requests.org/en/master/user/advanced/#session-objects>`__
(`#8 <https://github.com/Dwolla/dwolla-v2-python/pull/8>`__ - Thanks
@bfeeser!)
- **1.1.5** Fix file upload bug when using with Python 2
(`#6 <https://github.com/Dwolla/dwolla-v2-python/issues/6>`__)
- **1.1.2** Add ``TooManyRequestsError`` and ``ConflictError``
- **1.1.1** Add MANIFEST.in
- **1.1.0** Support per-request headers

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
dwollav2-1.3.0.tar.gz (10.2 kB) Copy SHA256 hash SHA256 Source None

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page