]>
jfr.im git - z_archive/twitter.git/blob - twitter/api.py
3 from twitter
.twitter_globals
import POST_ACTIONS
4 from twitter
.auth
import NoAuth
8 return sys
.hexversion
> 0x20600f0
13 import simplejson
as json
15 class TwitterError(Exception):
17 Base Exception thrown by the Twitter object when there is a
18 general error interacting with the API.
22 class TwitterHTTPError(TwitterError
):
24 Exception thrown by the Twitter object when there is an
25 HTTP error interacting with twitter.com.
27 def __init__(self
, e
, uri
, format
, uriparts
):
31 self
.uriparts
= uriparts
35 "Twitter sent status %i for URL: %s.%s using parameters: "
36 "(%s)\ndetails: %s" %(
37 self
.e
.code
, self
.uri
, self
.format
, self
.uriparts
,
40 class TwitterResponse(object):
42 Response from a twitter request. Behaves like a list or a string
43 (depending on requested format) but it has a few other interesting
46 `headers` gives you access to the response headers as an
47 httplib.HTTPHeaders instance. You can do
48 `response.headers.getheader('h')` to retrieve a header.
50 def __init__(self
, headers
):
51 self
.headers
= headers
54 def rate_limit_remaining(self
):
56 Remaining requests in the current rate-limit.
58 return int(self
.headers
.getheader('X-RateLimit-Remaining'))
61 def rate_limit_reset(self
):
63 Time in UTC epoch seconds when the rate limit will reset.
65 return int(self
.headers
.getheader('X-RateLimit-Reset'))
68 def wrap_response(response
, headers
):
69 response_typ
= type(response
)
70 if response_typ
is bool:
71 # HURF DURF MY NAME IS PYTHON AND I CAN'T SUBCLASS bool.
74 class WrappedTwitterResponse(response_typ
, TwitterResponse
):
75 __doc__
= TwitterResponse
.__doc
__
77 def __init__(self
, response
):
78 if response_typ
is not int:
79 response_typ
.__init
__(self
, response
)
80 TwitterResponse
.__init
__(self
, headers
)
82 return WrappedTwitterResponse(response
)
86 class TwitterCall(object):
88 self
, auth
, format
, domain
, uri
="", agent
=None,
89 uriparts
=None, secure
=True):
95 self
.uriparts
= uriparts
98 def __getattr__(self
, k
):
100 return object.__getattr
__(self
, k
)
101 except AttributeError:
103 auth
=self
.auth
, format
=self
.format
, domain
=self
.domain
,
104 agent
=self
.agent
, uriparts
=self
.uriparts
+ (k
,),
107 def __call__(self
, **kwargs
):
110 for uripart
in self
.uriparts
:
111 # If this part matches a keyword argument, use the
112 # supplied value otherwise, just use the part.
113 uriparts
.append(unicode(kwargs
.pop(uripart
, uripart
)))
114 uri
= u
'/'.join(uriparts
)
117 for action
in POST_ACTIONS
:
118 if uri
.endswith(action
):
122 # If an id kwarg is present and there is no id to fill in in
123 # the list of uriparts, assume the id goes at the end.
124 id = kwargs
.pop('id', None)
134 uriBase
= "http%s://%s/%s%s%s" %(
135 secure_str
, self
.domain
, uri
, dot
, self
.format
)
139 headers
.update(self
.auth
.generate_headers())
140 arg_data
= self
.auth
.encode_params(uriBase
, method
, kwargs
)
142 uriBase
+= '?' + arg_data
147 req
= urllib2
.Request(uriBase
, body
, headers
)
150 handle
= urllib2
.urlopen(req
)
151 if "json" == self
.format
:
152 res
= json
.loads(handle
.read())
153 return wrap_response(res
, handle
.headers
)
155 return wrap_response(str(handle
.read()), handle
.headers
)
156 except urllib2
.HTTPError
, e
:
160 raise TwitterHTTPError(e
, uri
, self
.format
, arg_data
)
162 class Twitter(TwitterCall
):
164 The minimalist yet fully featured Twitter API class.
166 Get RESTful data by accessing members of this class. The result
167 is decoded python objects (lists and dicts).
169 The Twitter API is documented here:
171 http://dev.twitter.com/doc
177 auth=OAuth(token, token_key, con_secret, con_secret_key)))
179 # Get the public timeline
180 twitter.statuses.public_timeline()
182 # Get a particular friend's timeline
183 twitter.statuses.friends_timeline(id="billybob")
185 # Also supported (but totally weird)
186 twitter.statuses.friends_timeline.billybob()
188 # Send a direct message
189 twitter.direct_messages.new(
191 text="I think yer swell!")
193 # Get the members of a particular list of a particular friend
194 twitter.user.listname.members(user="billybob", listname="billysbuds")
199 twitter_search = Twitter(domain="search.twitter.com")
201 # Find the latest search trends
202 twitter_search.trends()
204 # Search for the latest News on #gaza
205 twitter_search.search(q="#gaza")
208 Using the data returned
209 -----------------------
211 Twitter API calls return decoded JSON. This is converted into
212 a bunch of Python lists, dicts, ints, and strings. For example::
214 x = twitter.statuses.public_timeline()
216 # The first 'tweet' in the timeline
219 # The screen name of the user who wrote the first 'tweet'
220 x[0]['user']['screen_name']
226 If you prefer to get your Twitter data in XML format, pass
227 format="xml" to the Twitter object when you instantiate it::
229 twitter = Twitter(format="xml")
231 The output will not be parsed in any way. It will be a raw string
237 domain
="twitter.com", secure
=True, auth
=None,
240 Create a new twitter API connector.
242 Pass an `auth` parameter to use the credentials of a specific
243 user. Generally you'll want to pass an `OAuth`
246 twitter = Twitter(auth=OAuth(
247 token, token_secret, consumer_key, consumer_secret))
250 `domain` lets you change the domain you are connecting. By
251 default it's twitter.com but `search.twitter.com` may be
254 If `secure` is False you will connect with HTTP instead of
257 The value of `agent` is sent in the `X-Twitter-Client`
258 header. This is deprecated. Instead Twitter determines the
259 application using the OAuth Client Key and Client Key Secret
262 `api_version` is used to set the base uri. By default it's
263 nothing, but if you set it to '1' your URI will start with
269 if (format
not in ("json", "xml", "")):
270 raise ValueError("Unknown data format '%s'" %(format))
274 uriparts
+= (str(api_version
),)
276 TwitterCall
.__init
__(
277 self
, auth
=auth
, format
=format
, domain
=domain
,
278 secure
=secure
, uriparts
=uriparts
)
281 __all__
= ["Twitter", "TwitterError", "TwitterHTTPError", "TwitterResponse"]