]> jfr.im git - z_archive/twitter.git/blame - twitter/api.py
No tabs!!!
[z_archive/twitter.git] / twitter / api.py
CommitLineData
7364ea65 1
2from base64 import b64encode
5251ea48 3from urllib import urlencode
7364ea65 4
5import httplib
7364ea65 6
5251ea48 7from exceptions import Exception
8
f1a8ed67 9def _py26OrGreater():
10 import sys
11 return sys.hexversion > 0x20600f0
12
13if _py26OrGreater():
14 import json
15else:
16 import simplejson as json
17
5251ea48 18class TwitterError(Exception):
21e3bd23 19 """
20 Exception thrown by the Twitter object when there is an
21 error interacting with twitter.com.
22 """
5251ea48 23 pass
24
2dab41b1
MV
25# These actions require POST http requests instead of GET
26_POST_ACTIONS = [
27 "create", "update", "destroy", "new", "follow", "leave",
28 ]
29
7364ea65 30class TwitterCall(object):
153dee29 31 def __init__(self, username, password, format, domain, uri=""):
7364ea65 32 self.username = username
33 self.password = password
a55e6a11 34 self.format = format
7364ea65 35 self.uri = uri
153dee29 36 self.domain = domain
7364ea65 37 def __getattr__(self, k):
38 try:
39 return object.__getattr__(self, k)
40 except AttributeError:
41 return TwitterCall(
153dee29 42 self.username, self.password, self.format, self.domain,
a55e6a11 43 self.uri + "/" + k)
7364ea65 44 def __call__(self, **kwargs):
45 method = "GET"
2dab41b1
MV
46 for action in _POST_ACTIONS:
47 if self.uri.endswith(action):
48 method = "POST"
49 break
50
5b8b1ead 51 encoded_kwargs = urlencode(kwargs.items())
7364ea65 52 argStr = ""
5b8b1ead 53 if kwargs and (method == "GET"):
54 argStr = "?" + encoded_kwargs
55
56 headers = {}
57 if (self.username):
58 headers["Authorization"] = "Basic " + b64encode("%s:%s" %(
59 self.username, self.password))
60 if method == "POST":
61 headers["Content-type"] = "application/x-www-form-urlencoded"
62 headers["Content-length"] = len(encoded_kwargs)
63
153dee29 64 c = httplib.HTTPConnection(self.domain)
7364ea65 65 try:
5b8b1ead 66 c.putrequest(method, "%s.%s%s" %(
a55e6a11 67 self.uri, self.format, argStr))
5b8b1ead 68 for item in headers.iteritems():
69 c.putheader(*item)
7364ea65 70 c.endheaders()
5b8b1ead 71 if method == "POST":
72 c.send(encoded_kwargs)
7364ea65 73 r = c.getresponse()
5b8b1ead 74
7364ea65 75 if (r.status == 304):
76 return []
77 elif (r.status != 200):
1c11e6d7
WD
78 raise TwitterError(
79 "Twitter sent status %i for URL: %s.%s using parameters: %s\ndetails: %s" %(
80 r.status,
81 self.uri,
82 self.format,
83 encoded_kwargs,
84 r.read()))
5b8b1ead 85 if "json" == self.format:
f1a8ed67 86 return json.loads(r.read())
a55e6a11 87 else:
88 return r.read()
7364ea65 89 finally:
90 c.close()
91
92class 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:
153dee29
HN
100
101 http://apiwiki.twitter.com/
102 http://groups.google.com/group/twitter-development-talk/web/api-documentation
7364ea65 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
153dee29
HN
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
02121d76 130 twitter_search.search(q="#gaza")
153dee29 131
7364ea65 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']
a55e6a11 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")
7364ea65 151
a55e6a11 152 The output will not be parsed in any way. It will be a raw string
153 of XML.
7364ea65 154 """
153dee29 155 def __init__(self, email=None, password=None, format="json", domain="twitter.com"):
7364ea65 156 """
157 Create a new twitter API connector using the specified
a55e6a11 158 credentials (email and password). Format specifies the output
159 format ("json" (default) or "xml").
7364ea65 160 """
a55e6a11 161 if (format not in ("json", "xml")):
162 raise TwitterError("Unknown data format '%s'" %(format))
153dee29 163 TwitterCall.__init__(self, email, password, format, domain)
7364ea65 164
5b8b1ead 165__all__ = ["Twitter", "TwitterError"]