The official python client library for the Plaid API.
This module was recently refactored and released with breaking changes as version 1.0.x.
Table of Contents
Install
Via pip:
Via source:
git clone git@github.com:plaid/plaid-python.git python setup.py install
Documentation
The module supports all Plaid API endpoints. For complete information about the API, head to the docs.
Getting Started
Configuration
from plaid import Client Client.config({ 'url': 'https://tartan.plaid.com' })
By default, all non-200 responses will throw an error.
For more information on Plaid response codes, head to codes.
from plaid import Client from plaid import errors as plaid_errors client = Client(client_id='***', secret='***') try: response = client.connect('bofa', { 'username': '[something_invalid]', 'password': '***' }) except plaid_errors.UnauthorizedError: # handle this
If you would prefer to handle non-20x status codes yourself, you can configure the client to suppress these exceptions
import json from plaid import Client Client.config({ 'url': 'https://tartan.plaid.com', 'suppress_http_errors': True, }) response = client.connect('bofa', { 'username': '[something_invalid]', 'password': '***' }) if response.ok: content = json.loads(response.content) else: # handle non-20x status codes
Public Endpoints
Public endpoints (category and institution information) require no authentication and can be accessed as follows:
from plaid import Client from plaid import errors as plaid_errors from plaid.utils import json client = Client() institutions = json.loads(client.institutions().content) institutions = json.loads(client.categories().content)
Authenticated Endpoints
Authenticated endpoints require a valid client_id and secret to access. You can use the sandbox client_id and secret for testing (test_id and test_secret) during development mode.
Add Connect user
from plaid import Client from plaid import errors as plaid_errors from plaid.utils import json client = Client(client_id='***', secret='***') account_type = 'bofa' try: response = client.connect(account_type, { 'username': '***', 'password': '***' }) except plaid_errors.PlaidError: pass else: connect_data = json.loads(response.content)
MFA add Connect User
from plaid import Client from plaid import errors as plaid_errors from plaid.utils import json client = Client(client_id='***', secret='***') account_type = 'bofa' try: response = client.connect(account_type, { 'username': '***', 'password': '***' }) except plaid_errors.PlaidError, e: pass else: if response.status_code == 200: # User connected data = json.loads(response.content) elif response.stat_code == 201: # MFA required try: mfa_response = answer_mfa(json.loads(response.content)) except plaid_errors.PlaidError, e: pass else: # check for 200 vs 201 responses # 201 indicates that additional MFA steps required def answer_mfa(data): if data['type'] == 'questions': # Ask your user for the answer to the question[s]. # Although questions is a list, there is only ever a # single element in this list, at present return answer_question([q['question'] for q in data['mfa']]) elif data['type'] == 'list': return answer_list(data['mfa']) elif data['type'] == 'selection': return answer_selections(data['mfa']) else: raise Exception('Unknown mfa type from Plaid') def answer_question(questions): # We have magically inferred the answer # so we respond immediately # In the real world, we would present questions[0] # to our user and submit their response answer = 'dogs' return client.connect_step(account_type, answer) def answer_list(devices): # You should specify the device to which the passcode is sent. # The available devices are present in the devices list return client.connect_step('bofa', None, options={ 'send_method': {'type': 'phone'} }) def answer_selections(selections): # We have magically inferred the answers # so we respond immediately # In the real world, we would present the selection # questions and choices to our user and submit their responses # in a JSON-encoded array with answers provided # in the same order as the given questions answer = json.dumps(['Yes', 'No']) return client.connect_step(account_type, answer)
Add Auth User
Effectively the same as Connect.
client = Client(client_id='***', secret='***') response = client.auth('bofa', { 'username': '***', 'password': '***' })
MFA add Auth User
Effectively the same as Connect.
client = Client(client_id='***', secret='***') response = client.auth('bofa', { 'username': '***', 'password': '***' }) mfa_response = client.auth_step('bofa', 'my_answer')
Upgrade Account
Add a product (auth or connect to the user)
client = Client(client_id='***', secret='***', access_token='usertoken') response = client.upgrade('connect')
Delete User
client = Client(client_id='***', secret='***', access_token='usertoken') client.connect_delete() ## deletes Connect user # OR client.auth_delete() ## deletes Auth user
Exchange
Exchange a public_token from Plaid Link for a Plaid access token and then
retrieve account data:
client = Client(client_id='***', secret='***') response = client.exchange_token('test,chase,connected') # client.access_token should now be populated with a # valid access_token; we can make authenticated requests client.auth('chase', { 'username': '***', 'password': '***' })
Get Accounts
User previously Auth-ed
client = Client(client_id='***', secret='***', access_token='usertoken') accounts = json.loads(client.auth_get().content)
Get Account Balances
User previously added
client = Client(client_id='***', secret='***', access_token='usertoken') response = client.balance()
Get Transactions
User previously Connected-ed
client = Client(client_id='***', secret='***', access_token='usertoken') response = client.connect_get() json.loads(response.content)
Attribution & Maintenance
This repository was originally authored by Chris Forrette. Version 1.0.0 was authored by Ben Plesser.
Support
Open an issue!
Contribute
All pull requests should be linted with flakes8 and tested by running:
Contributors
- PK - fixes and Google App Engine Support