One of the main reasons to adopt REST is the simplicity of the API, compared to the juggling of formats required to send and receive SOAP messages.  We’ve had a long history of creating toolkits and libraries to ease the burden of using SOAP as a transport – so much so that when I first started looking at Python again as a language (not an accident that it was around the same time Heroku added it to their polyglot platform) … I really wanted to take a step back and see how simple I could make a script functional with  Not make something intended as fully functional application, or a web based interface, or handling multiple tasks or anything – just how simple could I make a script which logs in, performs a query, and then displays the results.  Make it as small as possible with as few dependencies as possible.

Here’s the result, a command line app which opens a browser to handle OAuth, grabs the tokens, does a SOQL query in REST and displays the results:

import os
import urlparse
import urllib
from restful_lib import Connection

consumer_key = 'CONSUMERKEY'
callback = ''
login_url = ''+consumer_key+'&redirect_uri='+callback

os.system("open '"+login_url+"'");
url_result = raw_input('If the page says "Remote Access Application Authorization", what is the URL?')

result = dict(urlparse.parse_qsl(url_result.split("success#")[1]));
token = urllib.unquote(result["access_token"])
instance_url = urllib.unquote(result["instance_url"])

conn = Connection(instance_url+'/services/data/v20.0')
result = conn.request_get('query',args={'q':'SELECT ID FROM CONTACT'},headers={'Authorization': 'OAuth '+token});
print result

Twenty lines of code.  You do need to cut and paste the post login URL from the browser back into the Python script in this flow.  The only dependency is a REST library from Google. I also had to make sure my httplib was up to date (the version that comes with Snow Leopard is apparently slightly dated). The line:

os.system("open '"+login_url+"'");

Is OS X specific (opens the default web browser to the URL), but you could easily modify the script to handle a Windows based browser.  Now since writing this, I’ve gone on updated it to handle queries based on user input, and some utility functions to do things like enter and remember the token (so that you don’t have like a dozen browser tabs open…) – but even with that level of functionality the script is still more like sixty lines of code.  Next step will probably be to handle the login with “password” grant type of OAuth to remove the browser requirement completely (but I do like the browser usage as an example of how OAuth works with most use cases).

This script is among my gists on GitHub, and I’ll probably add the more functional script as a proper repository down the road.  But you can see how integration with the platform doesn’t need to be a heavy-handed affair, thanks to REST and OAuth being in your toolbox.

tagged , , , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • Pat Patterson

    Hey Josh – I rewrote your script to use OAuth username/password (handy for headless server apps) and urllib2 rather than restful_lib – . I have an ‘evil plan‘ in the works :-)

    • Josh Birk

      Double plus cool! Evil plans for the win.

    • Tyler Harrington

      Pat, I don’t quite understand lines 8-12… Where does this go to get this information? Is the app running on the user’s local machine? Is this their salesforce login credentials?


      • Pat Patterson

        The app is pulling credentials from environment variables – best practice is to avoid putting passwords and such in the source code. This approach works well in most situations. See for more.

        • Tyler Harrington

          Right, but how are these variables set in the first place? How did you get the consumer_key, consumer_secret, and login_server? Pardon my inexperience…

          • Pat Patterson

            No worries, and apologies for the delay in replying – I missed the comment notification. You create a Connected App in Salesforce to represent your app. This gives your app an identity, and creates the consumer key and secret – see for details. The login server will be for standard developer edition/production environments or for sandboxes. You can also use a ‘My Domain’ URL as the login server if you have configured SAML SSO in your environment,