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