The official python client library for the Plaid API.
This module was recently refactored and released with breaking changes as version 1.0.x
.
Via pip:
pip install plaid-python
Via source:
git clone [email protected]:plaid/plaid-python.git
python setup.py install
The module supports all Plaid API endpoints. For complete information about the API, head to the docs.
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 (category 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='***')
categories = client.categories().json()
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.
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()
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)
Effectively the same as Connect.
client = Client(client_id='***', secret='***')
response = client.auth('bofa', {
'username': '***',
'password': '***'
})
Effectively the same as Connect.
client = Client(client_id='***', secret='***')
response = client.auth('bofa', {
'username': '***',
'password': '***'
})
mfa_response = client.auth_step('bofa', 'my_answer')
Add a product (auth or connect to the user)
client = Client(client_id='***', secret='***', access_token='usertoken')
response = client.upgrade('connect')
client = Client(client_id='***', secret='***', access_token='usertoken')
client.connect_delete() ## deletes Connect user
# OR
client.auth_delete() ## deletes Auth user
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': '***'
})
User previously Auth-ed
client = Client(client_id='***', secret='***', access_token='usertoken')
accounts = client.auth_get().json()
User previously added
client = Client(client_id='***', secret='***', access_token='usertoken')
response = client.balance()
User previously Connect-ed
client = Client(client_id='***', secret='***', access_token='usertoken')
response = client.connect_get()
transactions = response.json()
User previously Info-ed
client = Client(client_id='***', secret='***', access_token='usertoken')
response = client.info_get()
info = response.json()
User previously Income-ed
client = Client(client_id='***', secret='***', access_token='usertoken')
response = client.income_get()
income = response.json()
User previously Risk-ed
client = Client(client_id='***', secret='***', access_token='usertoken')
response = client.risk_get()
risk = response.json()
To search through or retrieve a list of all financial institutions supported by Plaid, use the /institutions/all/search
and /institutions/all
endpoints:
client = Client(client_id='***', secret='***')
# Search for an institution matching the name 'redwood credit' that supports Connect
institutionSearchResults = client.institution_all_search('redwood credit', 'connect'):
# Pull 200 institutions with, offseting 0 institutions
institutions = client.institutions_all(count=200, offset=0).json()
# Pull 50 institutions that support both Auth and Connect
institutions = client.institutions_all(count=50, offset=0, products=["auth","connect"]).json()
# Pull a single institution
singleInstitution = client.institution('ins_100003').json()
For additional information, please see the API Institutions docs.
Note: Use of the institution_search()
and institutions()
methods has been deprecated. Use institution_all_search()
and institutions_all()
methods instead.
This repository was originally authored by Chris Forrette. Version 1.0.0 was authored by Ben Plesser.
Open an issue!
SSLError: EOF occurred in violation of protocol (_ssl.c:581)
(plaid#62) - Work around is installingpyopenssl ndg-httpsclient pyasn1
All pull requests should be linted with flake8 and tested by running:
$ make test
- @chrisforrette (Chris Forrette)
- @gae123