Python OAuth Client

This tutorial describes how to use Intuit OAuth 2.0 endpoints to authorize your app’s access to your user’s QuickBooks company data when developing with Python OAuth client library.

See Authentication and authorization for general information on OAuth.

Install the library

Intuit’s Python OAuth library is meant to work with Intuit’s OAuth and OpenID implementation and works for works for Python 2.7+. The AuthClient object can be used for User Info API, Accounting API and Payments API. It supports the following:

  • Generate Authorization URL
  • Get OAuth2 Bearer Token
  • Get User Info
  • Validate OpenID token
  • Refresh OAuth2 Token
  • Revoke OAuth2 Token

It can be installed with pip :

1
pip install intuit-oauth
Generate Authorization URL

Instantiate AuthClient object which takes in app’s ClientID, ClientSecret, Redirect URL and the right environment. Valid values for environment include sandbox and production. redirect_uri should be set in your Intuit Developer app’s Keys tab under the right environment. Use the auth_client object to generate authorization URL by specifying list of intuitlib.enums.Scopes. Both these steps are shown below in code:

1
2
3
4
5
from intuitlib.client import AuthClient
from intuitlib.enums import Scopes

auth_client = AuthClient( client_id, client_secret, redirect_uri, environment )
url = auth_client.get_authorization_url([Scopes.Accounting])

Redirect your users by browser to the url generated above. After user connects to the app, the callback URL has params for state, auth_code and realm_id (realm_id for Accounting and Payments scopes only).

Get tokens and expiry details

The auth_code from URL params from callback response is used to get bearer tokens as shown below. Optionally, realm_id is passed to set this property for auth_client object.

1
auth_client.get_bearer_token(auth_code, realm_id=realm_id)

After successful response, access_token, expires_in, refresh_token and x_refresh_token_expires_in properties of auth_client object are set. For OpenID scope, id_token property is also set.

Use tokens for QuickBooks Online API call

All that is required to make a QuickBooks Online API Call is OAuth2 access_token and realm_id. Here’s a sample API call to show how to use access_token to get CompanyInfo for Accounting API.

1
2
3
4
5
6
7
8
base_url = 'https://sandbox-quickbooks.api.intuit.com'
url = '{0}/v3/company/{1}/companyinfo/{1}'.format(base_url, auth_client.realm_id)
auth_header = 'Bearer {0}'.format(auth_client.access_token)
headers = {
    'Authorization': auth_header,
    'Accept': 'application/json'
}
response = requests.get(url, headers=headers)
Get User Info for OpenId scope

User Info is returned by this method for OpenID scope only:

1
response = auth_client.get_user_info()

Or by passing the access_token as a parameter:

1
response = auth_client.get_user_info(access_token='EnterAccessTokenHere')
Refresh tokens

Your app must keep track of when a stored access token can be used and when the token must be refreshed. Use the refresh method to refresh the token. If auth_client.refresh_token property is already set, this can be done by:

1
auth_client.refresh()

Or by passing the refresh_token as a parameter:

1
auth_client.refresh(refresh_token='EnterRefreshTokenHere')
Revoke tokens

If auth_client.refresh_token or auth_client.access_token property is already set, this can be done by:

1
auth_client.revoke()

Alternatively, pass the refresh_token or access_token as a parameter:

1
auth_client.revoke(token='EnterAccessOrRefreshTokenHere')

If successfully revoked, this method returns True

Error Handling & Logging

In case of HTTP Errors, the client raises intuitlib.exceptions.AuthClientError which has properties status_code, intuit_tid, timestamp, etc which can used for troubleshooting or while contacting Support

1
2
3
4
5
6
7
8
9
from intuitlib.exceptions import AuthClientError

try:
    auth_client.get_bearer_token(auth_code, realm_id=realm_id)
except AuthClientError as e:
    # just printing here but it can be used for retry workflows, logging, etc
    print(e.status_code)
    print(e.content)
    print(e.intuit_tid)