A Python JSON Client for the LinkedIn API

The LinkedIn API is fairly robust and well documented, but is lacking a good JSON-based Python API for interacting with it. I recently opened-sourced LinkedIn-API-JSON-Client to fill this gap. It currently implements all the user profile related API calls, and is used in production by Votizen.com. This is a simple tutorial for how you can use it for your application as well.

Getting ready

You will need Python 2.x running in a virtual environment with PIP installed, and have setup an application on the LinkedIn Developers Site. The LinkedIn-API-JSON_Client library requires a LinkedIn provided Key and Secret for oauth.

How do it…

To install the package:

pip install git+https://github.com/mattsnider/LinkedIn-API-JSON-Client.git#egg=linkedin_json_client

Instantiate the client library:

from linkedin_json_client.api import LinkedInJsonAPI
my_key = 'mysecretkey'
my_secret = 'mysecretsecret'
li_client = LinkedInJsonAPI(my_key, my_secret)

The following steps show how to use the OAuth protocol to have a user authorize your app. First get the authentication URL for a user and redirect their browser to that URL:

from urllib import urlencode
from linkedin_json_client.constants import LinkedInScope
    request_token_dict = li_client.get_request_token(scope=[
        LinkedInScope.BASIC_PROFILE, LinkedInScope.EMAIL_ADDRESS])
    url = '%s?%s' % (li_client.authorize_path, urlencode(request_token_dict))
    # store your request token in the user session for use in callback
    request.session['li_request_token'] = request_token_dict
except (HTTPError, socket.error):
    # failed to connect to LinkedIn, handle this in your application

When you setup the application on LinkedIn, you specified a callback URL for authorization. That URL controller should compare the stored request token against an OAuth verifier token, provided by LinkedIn in the request::

oauth_verifier = request.GET.get('oauth_verifier')
request_token = request.session.get('li_request_token')

oauth_problem = request.GET.get('oauth_problem')
if oauth_problem or request_token is None:
    if oauth_problem == 'user_refused':
        # user refused auth, handle in your application
    # some other problem, handle in your application
    access_token = li_client.get_access_token(request_token, oauth_verifier)
    # user successfully authorized, store this access_token and associate with the user for use with API

With the access token, make calls against the API:

from linkedin_json_client.constants import BasicProfileFields, BasicProfileSelectors
    json_object = li_client.get_user_profile(access_token, [BasicProfileSelectors.FIRST_NAME, BasicProfileSelectors.LAST_NAME, BasicProfileSelectors.ID])

except LinkedInApiJsonClientError, e:
    print e

How it works…

Once the package is installed, initialized, and a user wants to authorize your app with LinkedIn, you call li_client.get_request_token to create an OAuth request token. Provide the scope argument with a list of values from linkedin_json_client.constants.LinkedInScope to authorize the portions of the API that you plan on using. LinkedIn recommends only using two scopes, but any number can be used (for example Votizen requires five). The OAuth request token should be stored in the session for verification after the user authorizes your app, then the user should be redirected to the authorization URL, where LinkedIn will handle authentication.

If the user authenticates, LinkedIn will redirect to the callback URL you specified when you setup your app and provide the oauth_verifier GET parameter. If the user does not authenticate or something else goes wrong then oauth_verifier will not be present and instead oauth_problem may be set. If oauth_verifier is available, pass it and the OAuth request token (stored on the session earlier) to li_client.get_access_token. This will return an OAuth access token to be used for making API calls on behalf of the authorizing user.

This example uses the OAuth access token to make a request to get the profile of the authorizing user, requesting their first name, last name, and LinkedIn identifier. All selectors and JSON key names are derived from LinkedIn Developers Documentation: Profile Fields, and turned into handy constants for convenience (linkedin_json_client.constants). Keep in mind that the JSON API will camel-case the field names, but the selectors are all lowercase with dashes (ie. firstName versus first-name).

Lastly, if something goes wrong with any API call, except authorization, a LinkedInApiJsonClientError is raised, describing what went wrong. Catching this will prevent your application from crashing and allow your application to recover or try again.

There’s more…

Full documentation is available on github, LinkedIn-API-JSON-Client. I will be registering with the Python Package Index soon, but github will always have the most up-to-date version.

This API is loosely based on the XML LinkedIn-Client-Library, originally written by Aaron Brenzel.