]> jfr.im git - z_archive/twitter.git/blame - twitter/api.py
First stab at searching
[z_archive/twitter.git] / twitter / api.py
CommitLineData
7364ea65 1
2from base64 import b64encode
5251ea48 3from urllib import urlencode
7364ea65 4
de072195 5import urllib2
7364ea65 6
5251ea48 7from exceptions import Exception
8
612ececa 9from twitter.twitter_globals import POST_ACTIONS
4e9d6343 10
f1a8ed67 11def _py26OrGreater():
12 import sys
13 return sys.hexversion > 0x20600f0
14
15if _py26OrGreater():
16 import json
17else:
18 import simplejson as json
19
5251ea48 20class TwitterError(Exception):
21e3bd23 21 """
22 Exception thrown by the Twitter object when there is an
23 error interacting with twitter.com.
24 """
5251ea48 25 pass
26
7364ea65 27class TwitterCall(object):
c8d451e8 28 def __init__(
45688301 29 self, username, password, format, domain, uri="", agent=None):
7364ea65 30 self.username = username
31 self.password = password
a55e6a11 32 self.format = format
153dee29 33 self.domain = domain
7364ea65 34 self.uri = uri
4a6070c8 35 self.agent = agent
7364ea65 36 def __getattr__(self, k):
37 try:
38 return object.__getattr__(self, k)
39 except AttributeError:
40 return TwitterCall(
153dee29 41 self.username, self.password, self.format, self.domain,
45688301 42 self.uri + "/" + k, self.agent)
7364ea65 43 def __call__(self, **kwargs):
da45d039 44 uri = self.uri
7364ea65 45 method = "GET"
612ececa 46 for action in POST_ACTIONS:
2dab41b1
MV
47 if self.uri.endswith(action):
48 method = "POST"
4ad03f81
MV
49 if (self.agent):
50 kwargs["source"] = self.agent
2dab41b1 51 break
da45d039 52
25b7bf59
WD
53 if kwargs.has_key('id'):
54 uri += "/%s" %(kwargs['id'])
2dab41b1 55
5b8b1ead 56 encoded_kwargs = urlencode(kwargs.items())
7364ea65 57 argStr = ""
de072195 58 argData = None
102acdb1
HN
59 if (method == "GET"):
60 if kwargs:
de072195 61 argStr = "?%s" %(encoded_kwargs)
102acdb1
HN
62 else:
63 argData = encoded_kwargs
5b8b1ead 64
65 headers = {}
4a6070c8
HN
66 if (self.agent):
67 headers["X-Twitter-Client"] = self.agent
5b8b1ead 68 if (self.username):
69 headers["Authorization"] = "Basic " + b64encode("%s:%s" %(
70 self.username, self.password))
102acdb1 71
de072195 72 req = urllib2.Request(
84f2d6bb 73 "http://%s/%s.%s%s" %(self.domain, uri, self.format, argStr),
de072195
HN
74 argData, headers
75 )
7364ea65 76 try:
102acdb1 77 handle = urllib2.urlopen(req)
de072195
HN
78 if "json" == self.format:
79 return json.loads(handle.read())
80 else:
81 return handle.read()
82 except urllib2.HTTPError, e:
83 if (e.code == 304):
7364ea65 84 return []
de072195 85 else:
1c11e6d7 86 raise TwitterError(
da45d039 87 "Twitter sent status %i for URL: %s.%s using parameters: (%s)\ndetails: %s" %(
25de7f81 88 e.code, uri, self.format, encoded_kwargs, e.fp.read()))
102acdb1 89
7364ea65 90class Twitter(TwitterCall):
91 """
92 The minimalist yet fully featured Twitter API class.
4e9d6343 93
7364ea65 94 Get RESTful data by accessing members of this class. The result
95 is decoded python objects (lists and dicts).
96
97 The Twitter API is documented here:
153dee29 98
0b486eda
HN
99 http://apiwiki.twitter.com/
100 http://groups.google.com/group/twitter-development-talk/web/api-documentation
4e9d6343 101
7364ea65 102 Examples::
4e9d6343 103
7364ea65 104 twitter = Twitter("hello@foo.com", "password123")
4e9d6343 105
7364ea65 106 # Get the public timeline
107 twitter.statuses.public_timeline()
4e9d6343 108
7364ea65 109 # Get a particular friend's timeline
110 twitter.statuses.friends_timeline(id="billybob")
4e9d6343 111
7364ea65 112 # Also supported (but totally weird)
113 twitter.statuses.friends_timeline.billybob()
4e9d6343 114
7364ea65 115 # Send a direct message
116 twitter.direct_messages.new(
117 user="billybob",
118 text="I think yer swell!")
119
153dee29 120 Searching Twitter::
4e9d6343 121
0b486eda 122 twitter_search = Twitter(domain="search.twitter.com")
153dee29 123
0b486eda
HN
124 # Find the latest search trends
125 twitter_search.trends()
153dee29 126
0b486eda
HN
127 # Search for the latest News on #gaza
128 twitter_search.search(q="#gaza")
153dee29 129
7364ea65 130 Using the data returned::
131
132 Twitter API calls return decoded JSON. This is converted into
133 a bunch of Python lists, dicts, ints, and strings. For example,
134
135 x = twitter.statuses.public_timeline()
136
137 # The first 'tweet' in the timeline
138 x[0]
139
140 # The screen name of the user who wrote the first 'tweet'
141 x[0]['user']['screen_name']
4e9d6343 142
a55e6a11 143 Getting raw XML data::
4e9d6343 144
a55e6a11 145 If you prefer to get your Twitter data in XML format, pass
146 format="xml" to the Twitter object when you instantiate it:
4e9d6343 147
a55e6a11 148 twitter = Twitter(format="xml")
4e9d6343 149
a55e6a11 150 The output will not be parsed in any way. It will be a raw string
151 of XML.
7364ea65 152 """
45688301
MV
153 def __init__(
154 self, email=None, password=None, format="json", domain="twitter.com",
155 agent=None):
7364ea65 156 """
157 Create a new twitter API connector using the specified
a55e6a11 158 credentials (email and password). Format specifies the output
159 format ("json" (default) or "xml").
7364ea65 160 """
a55e6a11 161 if (format not in ("json", "xml")):
162 raise TwitterError("Unknown data format '%s'" %(format))
4ad03f81 163 TwitterCall.__init__(self, email, password, format, domain, "", agent)
7364ea65 164
5b8b1ead 165__all__ = ["Twitter", "TwitterError"]