]>
jfr.im git - z_archive/twitter.git/blob - twitter/api.py
2 Attempting to patch to accommodate API like the list interface.
3 Note: Make sure not to use keyword substitutions that have the same name
4 as an argument that will get encoded.
9 from exceptions
import Exception
11 from twitter
.twitter_globals
import POST_ACTIONS
12 from twitter
.auth
import UserPassAuth
, NoAuth
16 return sys
.hexversion
> 0x20600f0
21 import simplejson
as json
23 class TwitterError(Exception):
25 Base Exception thrown by the Twitter object when there is a
26 general error interacting with the API.
30 class TwitterHTTPError(TwitterError
):
32 Exception thrown by the Twitter object when there is an
33 HTTP error interacting with twitter.com.
35 def __init__(self
, e
, uri
, format
, encoded_args
):
39 self
.encoded_args
= encoded_args
43 "Twitter sent status %i for URL: %s.%s using parameters: "
44 "(%s)\ndetails: %s" %(
45 self
.e
.code
, self
.uri
, self
.format
, self
.encoded_args
,
48 class TwitterCall(object):
50 self
, auth
, format
, domain
, uri
="", agent
=None,
51 uriparts
=None, secure
=True):
57 self
.uriparts
= uriparts
60 def __getattr__(self
, k
):
62 return object.__getattr
__(self
, k
)
63 except AttributeError:
64 """Instead of incrementally building the uri string, now we
65 just append to uriparts. We'll build the uri later."""
67 self
.auth
, self
.format
, self
.domain
,
68 self
.uri
, self
.agent
, self
.uriparts
+ (k
,))
70 def __call__(self
, **kwargs
):
73 for uripart
in self
.uriparts
:
74 #if this part matches a keyword argument, use the supplied value
75 #otherwise, just use the part
76 uri
= uri
+ "/" + kwargs
.pop(uripart
,uripart
)
78 for action
in POST_ACTIONS
:
79 if uri
.endswith(action
):
82 kwargs
["source"] = self
.agent
85 """This handles a special case. It isn't really needed anymore because now
86 we can insert an id value (or any other value) at the end of the
87 uri (or anywhere else).
88 However we can leave it for backward compatibility."""
89 id = kwargs
.pop('id', None)
99 uriBase
= "http%s://%s/%s%s%s" %(
100 secure_str
, self
.domain
, uri
, dot
, self
.format
)
104 if (method
== "GET"):
105 if self
.encoded_args
:
106 argStr
= "?%s" %(self
.encoded_args
)
108 argData
= self
.encoded_args
112 headers
["X-Twitter-Client"] = self
.agent
113 if self
.auth
is not None:
114 headers
.update(self
.auth
.generate_headers())
116 req
= urllib2
.Request(uriBase
+argStr
, argData
, headers
)
119 handle
= urllib2
.urlopen(req
)
120 if "json" == self
.format
:
121 return json
.loads(handle
.read())
124 except urllib2
.HTTPError
, e
:
128 raise TwitterHTTPError(e
, uri
, self
.format
, self
.encoded_args
)
130 class Twitter(TwitterCall
):
132 The minimalist yet fully featured Twitter API class.
134 Get RESTful data by accessing members of this class. The result
135 is decoded python objects (lists and dicts).
137 The Twitter API is documented here:
139 http://apiwiki.twitter.com/
140 http://groups.google.com/group/twitter-development-talk/web/api-documentation
145 auth=OAuth(token, token_key, con_secret, con_secret_key)))
147 # Get the public timeline
148 twitter.statuses.public_timeline()
150 # Get a particular friend's timeline
151 twitter.statuses.friends_timeline(id="billybob")
153 # Also supported (but totally weird)
154 twitter.statuses.friends_timeline.billybob()
156 # Send a direct message
157 twitter.direct_messages.new(
159 text="I think yer swell!")
161 # Get the members of a particular list of a particular friend
162 twitter.user.listname.members(user="billybob", listname="billysbuds")
167 twitter_search = Twitter(domain="search.twitter.com")
169 # Find the latest search trends
170 twitter_search.trends()
172 # Search for the latest News on #gaza
173 twitter_search.search(q="#gaza")
176 Using the data returned
177 -----------------------
179 Twitter API calls return decoded JSON. This is converted into
180 a bunch of Python lists, dicts, ints, and strings. For example::
182 x = twitter.statuses.public_timeline()
184 # The first 'tweet' in the timeline
187 # The screen name of the user who wrote the first 'tweet'
188 x[0]['user']['screen_name']
194 If you prefer to get your Twitter data in XML format, pass
195 format="xml" to the Twitter object when you instantiate it::
197 twitter = Twitter(format="xml")
199 The output will not be parsed in any way. It will be a raw string
204 self
, email
=None, password
=None, format
="json",
205 domain
="twitter.com", agent
=None, secure
=True, auth
=None,
208 Create a new twitter API connector.
210 Pass an `auth` parameter to use the credentials of a specific
211 user. Generally you'll want to pass an `OAuth`
214 twitter = Twitter(auth=OAuth(
215 token, token_secret, consumer_key, consumer_secret))
218 Alternately you can pass `email` and `password` parameters but
219 this authentication mode will be deactive by Twitter very soon
220 and is not recommended::
222 twitter = Twitter(email="blah@blah.com", password="foobar")
225 `domain` lets you change the domain you are connecting. By
226 default it's twitter.com but `search.twitter.com` may be
229 If `secure` is False you will connect with HTTP instead of
232 The value of `agent` is sent in the `X-Twitter-Client`
233 header. This is deprecated. Instead Twitter determines the
234 application using the OAuth Client Key and Client Key Secret
237 `api_version` is used to set the base uri. By default it's
238 nothing, but if you set it to '1' your URI will start with
241 if email
is not None or password
is not None:
244 "Can't specify 'email'/'password' and 'auth' params"
246 auth
= UserPassAuth(email
, password
)
251 if (format
not in ("json", "xml", "")):
252 raise ValueError("Unknown data format '%s'" %(format))
256 uri
= str(api_version
)
258 TwitterCall
.__init
__(
259 self
, auth
, format
, domain
, uri
, agent
,
263 __all__
= ["Twitter", "TwitterError", "TwitterHTTPError"]