]>
jfr.im git - z_archive/twitter.git/blob - twitter/api.py
3 from exceptions
import Exception
5 from twitter
.twitter_globals
import POST_ACTIONS
6 from twitter
.auth
import NoAuth
10 return sys
.hexversion
> 0x20600f0
15 import simplejson
as json
17 class TwitterError(Exception):
19 Base Exception thrown by the Twitter object when there is a
20 general error interacting with the API.
24 class TwitterHTTPError(TwitterError
):
26 Exception thrown by the Twitter object when there is an
27 HTTP error interacting with twitter.com.
29 def __init__(self
, e
, uri
, format
, uriparts
):
33 self
.uriparts
= uriparts
37 "Twitter sent status %i for URL: %s.%s using parameters: "
38 "(%s)\ndetails: %s" %(
39 self
.e
.code
, self
.uri
, self
.format
, self
.uriparts
,
42 class TwitterResponse(object):
44 Response from a twitter request. Behaves like a list or a string
45 (depending on requested format) but it has a few other interesting
48 `headers` gives you access to the response headers as an
49 httplib.HTTPHeaders instance. You can do
50 `response.headers.getheader('h')` to retrieve a header.
52 def __init__(self
, headers
):
53 self
.headers
= headers
56 def rate_limit_remaining(self
):
58 Remaining requests in the current rate-limit.
60 return int(self
.headers
.getheader('X-RateLimit-Remaining'))
63 def rate_limit_reset(self
):
65 Time in UTC epoch seconds when the rate limit will reset.
67 return int(self
.headers
.getheader('X-RateLimit-Reset'))
70 def wrap_response(response
, headers
):
71 response_typ
= type(response
)
72 if response_typ
is bool:
73 # HURF DURF MY NAME IS PYTHON AND I CAN'T SUBCLASS bool.
76 class WrappedTwitterResponse(response_typ
, TwitterResponse
):
77 __doc__
= TwitterResponse
.__doc
__
79 def __init__(self
, response
):
80 if response_typ
is not int:
81 response_typ
.__init
__(self
, response
)
82 TwitterResponse
.__init
__(self
, headers
)
84 return WrappedTwitterResponse(response
)
88 class TwitterCall(object):
90 self
, auth
, format
, domain
, uri
="", agent
=None,
91 uriparts
=None, secure
=True):
97 self
.uriparts
= uriparts
100 def __getattr__(self
, k
):
102 return object.__getattr
__(self
, k
)
103 except AttributeError:
105 auth
=self
.auth
, format
=self
.format
, domain
=self
.domain
,
106 agent
=self
.agent
, uriparts
=self
.uriparts
+ (k
,),
109 def __call__(self
, **kwargs
):
112 for uripart
in self
.uriparts
:
113 # If this part matches a keyword argument, use the
114 # supplied value otherwise, just use the part.
115 uriparts
.append(unicode(kwargs
.pop(uripart
, uripart
)))
116 uri
= u
'/'.join(uriparts
)
119 for action
in POST_ACTIONS
:
120 if uri
.endswith(action
):
124 # If an id kwarg is present and there is no id to fill in in
125 # the list of uriparts, assume the id goes at the end.
126 id = kwargs
.pop('id', None)
136 uriBase
= "http%s://%s/%s%s%s" %(
137 secure_str
, self
.domain
, uri
, dot
, self
.format
)
141 headers
.update(self
.auth
.generate_headers())
142 arg_data
= self
.auth
.encode_params(uriBase
, method
, kwargs
)
144 uriBase
+= '?' + arg_data
149 req
= urllib2
.Request(uriBase
, body
, headers
)
152 handle
= urllib2
.urlopen(req
)
153 if "json" == self
.format
:
154 res
= json
.loads(handle
.read())
155 return wrap_response(res
, handle
.headers
)
157 return wrap_response(str(handle
.read()), handle
.headers
)
158 except urllib2
.HTTPError
, e
:
162 raise TwitterHTTPError(e
, uri
, self
.format
, arg_data
)
164 class Twitter(TwitterCall
):
166 The minimalist yet fully featured Twitter API class.
168 Get RESTful data by accessing members of this class. The result
169 is decoded python objects (lists and dicts).
171 The Twitter API is documented here:
173 http://dev.twitter.com/doc
179 auth=OAuth(token, token_key, con_secret, con_secret_key)))
181 # Get the public timeline
182 twitter.statuses.public_timeline()
184 # Get a particular friend's timeline
185 twitter.statuses.friends_timeline(id="billybob")
187 # Also supported (but totally weird)
188 twitter.statuses.friends_timeline.billybob()
190 # Send a direct message
191 twitter.direct_messages.new(
193 text="I think yer swell!")
195 # Get the members of a particular list of a particular friend
196 twitter.user.listname.members(user="billybob", listname="billysbuds")
201 twitter_search = Twitter(domain="search.twitter.com")
203 # Find the latest search trends
204 twitter_search.trends()
206 # Search for the latest News on #gaza
207 twitter_search.search(q="#gaza")
210 Using the data returned
211 -----------------------
213 Twitter API calls return decoded JSON. This is converted into
214 a bunch of Python lists, dicts, ints, and strings. For example::
216 x = twitter.statuses.public_timeline()
218 # The first 'tweet' in the timeline
221 # The screen name of the user who wrote the first 'tweet'
222 x[0]['user']['screen_name']
228 If you prefer to get your Twitter data in XML format, pass
229 format="xml" to the Twitter object when you instantiate it::
231 twitter = Twitter(format="xml")
233 The output will not be parsed in any way. It will be a raw string
239 domain
="twitter.com", secure
=True, auth
=None,
242 Create a new twitter API connector.
244 Pass an `auth` parameter to use the credentials of a specific
245 user. Generally you'll want to pass an `OAuth`
248 twitter = Twitter(auth=OAuth(
249 token, token_secret, consumer_key, consumer_secret))
252 `domain` lets you change the domain you are connecting. By
253 default it's twitter.com but `search.twitter.com` may be
256 If `secure` is False you will connect with HTTP instead of
259 The value of `agent` is sent in the `X-Twitter-Client`
260 header. This is deprecated. Instead Twitter determines the
261 application using the OAuth Client Key and Client Key Secret
264 `api_version` is used to set the base uri. By default it's
265 nothing, but if you set it to '1' your URI will start with
271 if (format
not in ("json", "xml", "")):
272 raise ValueError("Unknown data format '%s'" %(format))
276 uriparts
+= (str(api_version
),)
278 TwitterCall
.__init
__(
279 self
, auth
=auth
, format
=format
, domain
=domain
,
280 secure
=secure
, uriparts
=uriparts
)
283 __all__
= ["Twitter", "TwitterError", "TwitterHTTPError", "TwitterResponse"]