bannerColor WARNING_YELLOW templateName stackForums

LinkedIn API Python library

23 posts / 0 new
Last post
Aaron Brenzel's picture
Joined: 2010-04-28
May 20, 2010
LinkedIn API Python library

Hey guys,I've been browsing around for Python wrappers for the LinkedIn API and have only been able to find this one: http://code.google.com/p/python-linkedin/.  Not sure how actively updated it is, and it's GPLed, so I've decided to open source my own library under the MIT for anyone who's interested.It's maintained at Github at this URL: http://github.com/mrgaaron/LinkedIn-Client-Library.The OAuth2 module dependency is included in the directory structure with its license (also MIT), but the other main dependency, lxml, must be installed manually.  This is because lxml is statically linked to its constituent C libraries in *nix systems and needs to be built with that in mind.  Windows users get a nice binary install.  lxml is available here: http://www.codespeak.net/lxml/I've been using it in a development environment for the last several weeks and it's been performing well, but I'm sure there are issues still hiding in the code and things that could be implemented better.  I'm hosting with Github in the hopes that any fellow Python hackers will help me add to and improve the library going forward.  Aside from docstrings the documentation isn't there yet, so I'll throw in a little tutorial on the part everyone seems to have the toughest time with: logging into with OAuth.1.  First, of course, we need to instantiate the API object with our consumer key and secret:     consumer_key = 'mykey'     consumer_secret = 'mysecret'     APIClient = LinkedInAPI(consumer_key, consumer_secret)2.  The first step for a new user is to retrieve a request token.  This is done like so:     request_token = APIClient.get_request_token()3.  Then, we generate the URL to send the user to for authentication (I know the first line is a little ugly, I will probably simplify this soon):     authorization_url = APIClient.base_url + APIClient.authorize_path     url = "%s?oauth_token=%s" % (authorization_url, request_token['oauth_token'])4.  Once the user has authenticated, you will need to collect the oauth_verifier returned by the LinkedIn server in the URL.  This can be done     either by having the user type it in themselves or collecting the URL argument on the redirect from LinkedIn.  However you decided to get it,     this is how you use it:     access_token = APIClient.get_access_token(request_token, oauth_verifier)That's it!  You can use this access token for every request this particular user makes, for as long as they have authorized you to use it.From here, you can use the methods on the LinkedAPI object to accomplish tasks such as using the search API, getting network updates, or sending messages.  All methods that "do something" like that are documented with docstrings, although I hope to have fuller documentation written soon.  Every "do something" method must have the access token passed as its first argument.  The rest of the arguments depend on which method you're calling.All returns (with a few exceptions for methods that create content) are mapped in the form of standard Python objects, including errors from LinkedIn.  This means for now that this library does not raise exceptions based on errors returned from LinkedIn (standard Python exceptions still work normally).  The fields returned by the API are mapped to object attributes, which can be altered on the fly as your application requires.  All LinkedIn Data objects can also be converted to either JSON or XML with the jsonify() and xmlify() methods as you prefer.  All edits to attributes will be reflected in the JSON or XML generated in this way.  For instance, if I requested the profile of "Bob Johnson" and change the name like this: Profile.first_name = 'Joe', then the JSON and XML generated by the object's methods later on will reflect that change.I am fairly confident in the jsonify() methods but xmlify() may do some weird things still.  One issue I know about is that it does not handle subnodes very well, as in the XML returned by asking for positions or education on a profile.  Use with caution for now.Other known issues can be found in the issues.txt document in the root directory.  I'd appreciate any help from the community on getting those solved.  One final note: the "analysis" directory is very rough and is intended to support NLP and graph theory analyses on API returns.  So far I only have a rough sketch of the NLP methods and it requires NLTK (Natural Language Toolkit - can be found at http://www.nltk.org)be installed to import.This is a work in progress, but I'm hoping we can turn this into a monster library for working with LinkedIn's very cool API.

Özgür Vatansever's picture
Joined: 2010-06-07
Jun 7, 2010

Hi Aaron;Congrats for your great job. Your library provides more functionality -like updating/getting your network details- than the orther Linkedin interface.BTW, the other LinkedIn python interface located in the url  http://code.google.com/p/python-linkedin/ is now licensed under the MIT license.Regards.

Holden Robbins's picture
Joined: 2011-02-13
Feb 13, 2011

Was digging around trying to find a library that would work with Google App Engine.  Unfortuantely use of lxml precludes this. :/At least until they put some effort into: http://code.google.com/p/googleappengine/issues/detail?id=18

Kirsten Hunter's picture
Joined: 2011-06-30
Feb 14, 2011

There's an existing library which works with GAE:  Integrating LinkedIn with Google App Engine (Python)

karthik jayapal's picture
Joined: 2011-03-14
Mar 16, 2011

Thanks for the wrapper dude.I have a question, How do i set the callback url (apart from the linked in app settings) ?In python-linkedin, i can pass it as a param when creating the linkedin obj like below:

api = linkedin.LinkedIn(KEY, SECRET, RETURN_URL)

Do you have a way to do this? i tried to get it from the code. There is an option to set it in Token class, which is used only when getting the access token.

Joined: 2011-07-06
Jul 20, 2011

Hello,
Thanks a lot for this API, the open source is very useful.

I have a problem, I would like to dynamically collect the "oauth_verifier" in the URL but I don't know how.
I read the previous message without finding which option I have to set.

Could you give me an advice, I'm not very use to work with Python, I might missed an element.
Thanks for your help

Regard
Marc

Joined: 2011-07-18
Jul 20, 2011

Hi Marc, I done like this:

APIClient = LinkedInAPI(consumer_key, consumer_secret)
request_token = APIClient.get_request_token()
authorization_url = APIClient.base_url + APIClient.authorize_path
url = "%s?oauth_token=%s" % (authorization_url, request_token['oauth_token'])
oauth_verifier = [your number]
access_token = APIClient.get_access_token(request_token, oauth_verifier)

first a program like this:

APIClient = LinkedInAPI(consumer_key, consumer_secret)
request_token = APIClient.get_request_token()
authorization_url = APIClient.base_url + APIClient.authorize_path
url = "%s?oauth_token=%s" % (authorization_url, request_token['oauth_token'])
print url

take the url and put in your browser and take oauth_verifier. Then execute the program, without print url but completing the code with your number.

Joined: 2011-07-06
Jul 20, 2011

Hello,
thanks for the answer, but I already know that. Even more, I added
webbrowser.open(url)
to directly open the URL in a browser.

I asked a way to take the "oauth_verifier" without using a browser directly from the program, without user's action (except to allow access). Does this way is possible ?

Kirsten Hunter's picture
Joined: 2011-06-30
Jul 26, 2011

You can't authenticate via LinkedIn without a browser.

Joined: 2011-08-17
Aug 25, 2011

access_token = APIClient.get_access_token(request_token, oauth_verifier)
Can I use this access_token to get other user's basic information?

Kirsten Hunter's picture
Joined: 2011-06-30
- (Reply to #10) Aug 26, 2011

You can get information about the user's connections as detailed on the Connections API documentation. Please read through all of the documentation on the REST API to understand all of the calls available to you.

Partha Sundaram's picture
Joined: 2011-10-08
Oct 10, 2011

I had the same problem as Marc. The library as is does not handle callback URL's. I made a simple fix to the oauth.py in the library.

Add the following statement in oauth.py in Line Number 604
parameters['oauth_callback'] = CALLBACK_URL

This sets the call-back URL. So when you actually send the user for authorizing, the user gets redirected back to your app. Here's a sample skeleton of my app using web.py framework

urls = (

'/hello', 'Index',
'/haha','Authd')

app = web.application(urls, globals())

render = web.template.render('templates/')

api = LinkedInAPI(Key, Secret)
params = {'first-name': 'John', 'last-name': 'Smith'}
field_selector_string = '(people:(id,first-name,last-name,headline,public-profile-url),num-results)'

request_token = api.get_request_token()
authorization_url = api.base_url + api.authorize_path
url = "%s?oauth_token=%s" % (authorization_url, request_token['oauth_token'])

class Index(object):

def GET(self):

#return render.hello_form()
raise web.seeother(url)
print "get hit"

class Authd(object):
def GET(self):
access_token = api.get_access_token(request_token, web.input().oauth_verifier)
results = api.search(access_token, params, field_selector_string)
print results

if __name__ == "__main__":

app.run()

Partha Sundaram's picture
Joined: 2011-10-08
Oct 10, 2011

sorry, typo in my previous response - it's not oauth.py, it is oauth2/__init__.py. Hope this helps.

Graham Perry's picture
Joined: 2011-07-18
Oct 11, 2011

Apologies for this but I am new to Python:

I run the LinkedIn program but get this error message:

Traceback (most recent call last):
File "C:/Python27/anotherlinkedin.py", line 1, in <module>
import liclient
File "C:\Python27\lib\site-packages\liclient\__init__.py", line 7, in <module>
from parsers.lixml import LinkedInXMLParser
File "C:\Python27\lib\site-packages\liclient\parsers\lixml.py", line 1, in <module>
from lxml import etree
File "parsertarget.pxi", line 4, in init lxml.etree (src/lxml\lxml.etree.c:162043)
File "C:\Python27\lib\inspect.py", line 39, in <module>
import tokenize
File "C:\Python27\lib\tokenize.py", line 38, in <module>
COMMENT = N_TOKENS
NameError: name 'N_TOKENS' is not defined

I'm sure it's something obvious - can anyone spot the problem?

The program is:

import liclient

consumer_key = 'Bla Bla Bla'
consumer_secret = 'Bla Bla Bla'
APIClient = LinkedInAPI(consumer_key, consumer_secret)
request_token = APIClient.get_request_token()

authorization_url = APIClient.base_url + APIClient.authorize_path
url = "%s?oauth_token=%s" % (authorization_url, request_token['oauth_token'])
print url
access_token = APIClient.get_access_token(request_token, oauth_verifier)

Yu Pengfei's picture
Joined: 2011-11-08
Mar 20, 2012

There is error when get access token.
TypeError: list indices must be integers, not str

Yu Pengfei's picture
Joined: 2011-11-08
Mar 20, 2012

token = oauth.Token(request_token['oauth_token'],

Dimitrios Kouzis-Loukas's picture
Joined: 2012-04-12
Apr 22, 2012

The way I do it:

#!/usr/bin/python

from pprint import pprint
from liclient import LinkedInAPI

API_KEY = '***'
SECRET_KEY = '***'
ACCESS_TOKEN = {} # POINT A

api = LinkedInAPI(API_KEY, SECRET_KEY)

login = True

if login:
request_token = api.get_request_token()
authorization_url = api.base_url + api.authorize_path
url = "%s?oauth_token=%s" % (authorization_url, request_token['oauth_token'])
print "Go to %s to grab your oauth Verifier." % url
#open your browser and allow access, then come back here and paste your oath Verifier:

oauth_verifier = raw_input('What is your oauth Verifier? ')

access_token = api.get_access_token(request_token, oauth_verifier)
pprint(access_token)
#COPY PASTE the output string to POINT A above and set login = False
else:
api = LinkedInAPI(API_KEY, SECRET_KEY)

x = api.get_user_profile(ACCESS_TOKEN, [])
pprint(x[0].first_name + " " + x[0].last_name)

Hugo Koopmans's picture
Joined: 2012-09-25
Sep 28, 2012

thanx for the script,

I tried it but after getting the access_token and putting logic = false

I get:

Traceback (most recent call last):
File "/home/hugo/Tools/eclipse/workspace/autoUpdater/autoUpdater/autoUp.py", line 33, in <module>
x = api.get_user_profile(ACCESS_TOKEN,[])
File "/usr/local/lib/python2.7/dist-packages/liclient/__init__.py", line 75, in get_user_profile
user_token, url = self.prepare_request(access_token, self.api_profile_url, kwargs)
File "/usr/local/lib/python2.7/dist-packages/liclient/__init__.py", line 218, in prepare_request
user_token = oauth.Token(access_token['oauth_token'],
TypeError: string indices must be integers, not str

Any suggestion ?

Özgür Vatansever's picture
Joined: 2010-06-07
Mar 24, 2013

Hi,

I reimplemented the entire Python library from scratch. It is full OAuth 2.0 compliant. It is in my GitHub repo. You can check it out:

https://github.com/ozgur/python-linkedin/

Cheers

Sunita Koppar's picture
Joined: 2013-05-09
May 31, 2013

Hi Ozgur,
Thanks for your library. Its very handy and useful. I am trying to use it for my test application.
Can you help me with these issues I'm struggling with:
1. How to fetch next results (for instance, I am using the search_job api. I see num_results = 1811 but count = 20, just the first page I'm sure. How to pull the next set of pages)
2. I intend to upload the response into a HIVE table. I'm reading a lot about json structure and how to flatten it in order to load it into HIVE, but do not have enough clarity. Any recommendations / references

Mayank Gupta's picture
Joined: 2013-06-12
Jun 25, 2013

Can someone please help me also? I have the same problem as above.

Grace Tang's picture
Joined: 2012-06-15
Aug 6, 2013

Same problem, I'm trying to get a higher number of posts from the group API using the count param,

r=application.get_posts(12345, params={'count': 20, 'start': 5})

but neither the count not start params works, it seems. Still getting only the first ten values:

{u'_total': 200, u'_count': 10, u'_start': 0, u'values': ...

Grace Tang's picture
Joined: 2012-06-15
Aug 8, 2013

There is a bug in the make_request code that will cause params like 'count' to be ignored. See this pull request:

https://github.com/ozgur/python-linkedin/pull/27/files