Few days ago, I knew Basic Auth will be removed by June 30, 2010, Twitter even made a nice countdown timer1.

At the moment, I said “I’ll be damned!” to myself, because I simply didn’t want to switch to OAuth for the scripts I am using. Alright, I admit that the real reason is I don’t want to learn OAuth, yes, I still didn’t know how OAuth works in behind.

Anyway, it turned out I spent an hour to make one of my code to use OAuth with help from python-oauth2 library. Yes, I only took an hour to modify and believe or not, for 50 minutes, I was using wrong consumer key or secret. I somehow copy-and-paste them with some dust.

Using python-oauth2 is pretty simple if you used to access Twitter API, then json.loads(content) on your own, read on. If you are using python-twitter, you will need to find a library with Twitter OAuth support, or just objectify the parsed json content to have similar Status, User, etc. from python-twitter.

As for Streaming API, I would simply say it’s an alternative way to search but more efficient because we keep-alive the connection. The Twitter Search API, we request every a while. Streaming API requires us staying where we can see each other all the time.

1   Twitter OAuth

By using OAuth, we must register application on Twitter Developers in order to get consumer key and consumer secret. We are no longer require user’s username and password, in fact, they are useless now.

I am not going through OAuth because I didn’t try to know it. I just followed the sample code of python-oauth2. I wrote this twitter-oauth.py, I don’t post the complete code here, please follow the link. Note that you also need httplib2 for python-oauth2.

First-time user has to authorize the application. After that, application will get a access token which allows the application to really do something with user’s account. get_access_token() (it is the sample code of python-oauth2) is for getting the access token, it guides user to follow steps. Note that here we are talking a client type client not browser type client.

def get_access_token(consumer):

  client = oauth.Client(consumer)
  # [snip]

As you can see we need consumer to create a client instance. Which is

consumer = oauth.Consumer(config.consumer_key, config.consumer_secret)

The get_access_token() will give user a link, so they can get a PIN number. After user inputs PIN to the application, the application use this PIN number to get the access token. Once application has the access token, it should store it somewhere safe for later use and create a new client:

token = oauth.Token(
    config.access_token['oauth_token'],
    config.access_token['oauth_token_secret'])
client = oauth.Client(consumer, token)

After first time, application can directly supply with (access) token. Then it can request as we do with Twitter Basic Auth, e.g. friends timeline:

request_uri = 'https://api.twitter.com/1/statuses/friends_timeline.json'
resp, content = client.request(request_uri, 'GET')

and this is how it post new status:

request_uri = 'https://api.twitter.com/1/statuses/update.json'
data = {'status': raw_input("What's happening? ")}
resp, content = client.request(request_uri, 'POST', urllib.urlencode(data))

Simple, ain’t they?

Try to run that script, just remember to delete config.py which it generates. I believe you can start from here for your application.

2   Being Lazier?

I just knew of a new library, oauth-python-twitter2, which packages python-oauth2 to be a Python Twitter library and provides you methods like GetUserTimeline(). It will json.loads() for you, from there, you take over. Check out this sample code:

from oauth import oauth
from oauthtwitter import OAuthApi
import pprint

consumer_key = ""
consumer_secret = ""

twitter = OAuthApi(consumer_key, consumer_secret)

# Get the temporary credentials for our next few calls
temp_credentials = twitter.getRequestToken()

# User pastes this into their browser to bring back a pin number
print(twitter.getAuthorizationURL(temp_credentials))

# Get the pin # from the user and get our permanent credentials
oauth_verifier = raw_input('What is the PIN? ')
access_token = twitter.getAccessToken(temp_credentials, oauth_verifier)

print("oauth_token: " + access_token['oauth_token'])
print("oauth_token_secret: " + access_token['oauth_token_secret'])

# Do a test API call using our new credentials
twitter = OAuthApi(consumer_key, consumer_secret, access_token['oauth_token'], access_token['oauth_token_secret'])
user_timeline = twitter.GetUserTimeline()

pp = pprint.PrettyPrinter(indent=4)
pp.pprint(user_timeline)

I don’t think I am this lazy, so this is not my candy. :)

3   Streaming API

When I first heard of Streaming API, I was completely reluctant to learn anything about it because the documentation was really *masked* hard to read. Now the documentation with better style, however it still reads strange, especially the headings. But I managed to read it this time. And I came out with this simple tracking script in 10 or 20 minutes, here is part of twitter-streaming.py:

def fetch(uri, username='', password='', data=None):

  headers = {}
  if username and password:
        headers['Authorization'] = 'Basic ' + base64.b64encode('%s:%s' % (username,
                password))
        headers['User-Agent'] = 'TwitterStreamingSample'

  req = urllib2.Request(uri, headers=headers)
  if data:
        req.add_data(urllib.urlencode(data))
  f = urllib2.urlopen(req)
  return f


def main():

  username = raw_input('Twitter Username: ')
  password = getpass.getpass('Twitter Password: ')
  track = raw_input('Tracking keyword? ')
  print

  try:
        f = fetch('http://stream.twitter.com/1/statuses/filter.json', username,
                password, {'track': track})
        print 'Tracking... [Control + C to stop]'
        print
        while True:
          line = f.readline()
          if line:
                status = json.loads(line)
                try:
                  print '%s: %s' % (status['user']['screen_name'], status['text'])
                except KeyError, e:
                  # Something we don't handle yet.
                  print '* FIXME *', line
          else:
                time.sleep(0.1)
  except urllib2.HTTPError, e:
        # Deal with unexpected disconnection
        raise e
  except KeyboardInterrupt:
        # End
        f.close()
        print 'Bye!'

Streaming API requires Basic Auth, so you must have an account. In this code, I show you how to keep the connection alive, just don’t close it. :) It keeps asking for data every 0.1seconds, some people may not like this way but this one using PyCurl, but I am fine with it.

Basically, one line per one status return, but if you have seen raw tweet, you would know '\n' is allowed. So I have multiline in code to detect if that is more than one line for a status.

This code doesn’t do much or handle any unexpected surprises from Twitter, you might want to check the last part of the documentation, Pre-Launch Checklist, it has pointed out some situation we may encounter.


[1]http://www.countdowntooauth.com/ is gone.