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, }) client = Client(client_id='***', secret='***') response = client.connect('bofa', { 'username': '[something_invalid]', 'password': '***' }) if response.ok: user = response.json() 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(client_id='***', secret='***') institutions = client.institutions().json() categories = client.categories().json()
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 = response.json()
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 = response.json() elif response.stat_code == 201: # MFA required try: mfa_response = answer_mfa(response.json()) 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 = client.auth_get().json()
Get Account Balances
User previously added
client = Client(client_id='***', secret='***', access_token='usertoken') response = client.balance()
Get Transactions
User previously Connect-ed
client = Client(client_id='***', secret='***', access_token='usertoken') response = client.connect_get() transactions = response.json()
Get Info
User previously Info-ed
client = Client(client_id='***', secret='***', access_token='usertoken') response = client.info_get() info = response.json()
Get Income
User previously Income-ed
client = Client(client_id='***', secret='***', access_token='usertoken') response = client.income_get() income = response.json()
Get Risk
User previously Risk-ed
client = Client(client_id='***', secret='***', access_token='usertoken') response = client.risk_get() risk = response.json()
Attribution & Maintenance
This repository was originally authored by Chris Forrette. Version 1.0.0 was authored by Ben Plesser.
Support
Open an issue!
Known Issues
SSLError: EOF occurred in violation of protocol (_ssl.c:581)(plaid#62) - Work around is installingpyopenssl ndg-httpsclient pyasn1
Contribute
All pull requests should be linted with flake8 and tested by running:
Contributors
- @chrisforrette (Chris Forrette)
- @gae123