]> jfr.im git - z_archive/twitter.git/blame - twitter/api.py
Bugfix release 1.2.1
[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
612ececa 52
da45d039
MV
53 id = kwargs.pop('id', None)
54 if id:
55 uri += "/%s" %(id)
4e9d6343 56
7364ea65 57 argStr = ""
de072195
HN
58 argData = None
59 encoded_kwargs = urlencode(kwargs.items())
102acdb1
HN
60 if (method == "GET"):
61 if kwargs:
de072195 62 argStr = "?%s" %(encoded_kwargs)
102acdb1
HN
63 else:
64 argData = encoded_kwargs
5b8b1ead 65
66 headers = {}
4a6070c8
HN
67 if (self.agent):
68 headers["X-Twitter-Client"] = self.agent
5b8b1ead 69 if (self.username):
70 headers["Authorization"] = "Basic " + b64encode("%s:%s" %(
71 self.username, self.password))
102acdb1 72
de072195 73 req = urllib2.Request(
84f2d6bb 74 "http://%s/%s.%s%s" %(self.domain, uri, self.format, argStr),
de072195
HN
75 argData, headers
76 )
7364ea65 77 try:
102acdb1 78 handle = urllib2.urlopen(req)
de072195
HN
79 if "json" == self.format:
80 return json.loads(handle.read())
81 else:
82 return handle.read()
83 except urllib2.HTTPError, e:
84 if (e.code == 304):
7364ea65 85 return []
de072195 86 else:
1c11e6d7 87 raise TwitterError(
da45d039 88 "Twitter sent status %i for URL: %s.%s using parameters: (%s)\ndetails: %s" %(
25de7f81 89 e.code, uri, self.format, encoded_kwargs, e.fp.read()))
102acdb1 90
7364ea65 91class Twitter(TwitterCall):
92 """
93 The minimalist yet fully featured Twitter API class.
4e9d6343 94
7364ea65 95 Get RESTful data by accessing members of this class. The result
96 is decoded python objects (lists and dicts).
97
98 The Twitter API is documented here:
153dee29 99
0b486eda
HN
100 http://apiwiki.twitter.com/
101 http://groups.google.com/group/twitter-development-talk/web/api-documentation
4e9d6343 102
7364ea65 103 Examples::
4e9d6343 104
7364ea65 105 twitter = Twitter("hello@foo.com", "password123")
4e9d6343 106
7364ea65 107 # Get the public timeline
108 twitter.statuses.public_timeline()
4e9d6343 109
7364ea65 110 # Get a particular friend's timeline
111 twitter.statuses.friends_timeline(id="billybob")
4e9d6343 112
7364ea65 113 # Also supported (but totally weird)
114 twitter.statuses.friends_timeline.billybob()
4e9d6343 115
7364ea65 116 # Send a direct message
117 twitter.direct_messages.new(
118 user="billybob",
119 text="I think yer swell!")
120
153dee29 121 Searching Twitter::
4e9d6343 122
0b486eda 123 twitter_search = Twitter(domain="search.twitter.com")
153dee29 124
0b486eda
HN
125 # Find the latest search trends
126 twitter_search.trends()
153dee29 127
0b486eda
HN
128 # Search for the latest News on #gaza
129 twitter_search.search(q="#gaza")
153dee29 130
7364ea65 131 Using the data returned::
132
133 Twitter API calls return decoded JSON. This is converted into
134 a bunch of Python lists, dicts, ints, and strings. For example,
135
136 x = twitter.statuses.public_timeline()
137
138 # The first 'tweet' in the timeline
139 x[0]
140
141 # The screen name of the user who wrote the first 'tweet'
142 x[0]['user']['screen_name']
4e9d6343 143
a55e6a11 144 Getting raw XML data::
4e9d6343 145
a55e6a11 146 If you prefer to get your Twitter data in XML format, pass
147 format="xml" to the Twitter object when you instantiate it:
4e9d6343 148
a55e6a11 149 twitter = Twitter(format="xml")
4e9d6343 150
a55e6a11 151 The output will not be parsed in any way. It will be a raw string
152 of XML.
7364ea65 153 """
45688301
MV
154 def __init__(
155 self, email=None, password=None, format="json", domain="twitter.com",
156 agent=None):
7364ea65 157 """
158 Create a new twitter API connector using the specified
a55e6a11 159 credentials (email and password). Format specifies the output
160 format ("json" (default) or "xml").
7364ea65 161 """
a55e6a11 162 if (format not in ("json", "xml")):
163 raise TwitterError("Unknown data format '%s'" %(format))
4ad03f81 164 TwitterCall.__init__(self, email, password, format, domain, "", agent)
7364ea65 165
5b8b1ead 166__all__ = ["Twitter", "TwitterError"]