]> jfr.im git - z_archive/twitter.git/blame - twitter/api.py
Add Hatem to AUTHORS file, prep for 0.4.5 release soonish
[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
7364ea65 25class TwitterCall(object):
153dee29 26 def __init__(self, username, password, format, domain, uri=""):
7364ea65 27 self.username = username
28 self.password = password
a55e6a11 29 self.format = format
7364ea65 30 self.uri = uri
153dee29 31 self.domain = domain
7364ea65 32 def __getattr__(self, k):
33 try:
34 return object.__getattr__(self, k)
35 except AttributeError:
36 return TwitterCall(
153dee29 37 self.username, self.password, self.format, self.domain,
a55e6a11 38 self.uri + "/" + k)
7364ea65 39 def __call__(self, **kwargs):
40 method = "GET"
21e3bd23 41 if (self.uri.endswith('new')
42 or self.uri.endswith('update')
25aecb69 43 or self.uri.endswith('create')
44 or self.uri.endswith('destroy')):
7364ea65 45 method = "POST"
5b8b1ead 46
47 encoded_kwargs = urlencode(kwargs.items())
7364ea65 48 argStr = ""
5b8b1ead 49 if kwargs and (method == "GET"):
50 argStr = "?" + encoded_kwargs
51
52 headers = {}
53 if (self.username):
54 headers["Authorization"] = "Basic " + b64encode("%s:%s" %(
55 self.username, self.password))
56 if method == "POST":
57 headers["Content-type"] = "application/x-www-form-urlencoded"
58 headers["Content-length"] = len(encoded_kwargs)
59
153dee29 60 c = httplib.HTTPConnection(self.domain)
7364ea65 61 try:
5b8b1ead 62 c.putrequest(method, "%s.%s%s" %(
a55e6a11 63 self.uri, self.format, argStr))
5b8b1ead 64 for item in headers.iteritems():
65 c.putheader(*item)
7364ea65 66 c.endheaders()
5b8b1ead 67 if method == "POST":
68 c.send(encoded_kwargs)
7364ea65 69 r = c.getresponse()
5b8b1ead 70
7364ea65 71 if (r.status == 304):
72 return []
73 elif (r.status != 200):
5251ea48 74 raise TwitterError("Twitter sent status %i: %s" %(
7364ea65 75 r.status, r.read()))
5b8b1ead 76 if "json" == self.format:
f1a8ed67 77 return json.loads(r.read())
a55e6a11 78 else:
79 return r.read()
7364ea65 80 finally:
81 c.close()
82
83class Twitter(TwitterCall):
84 """
85 The minimalist yet fully featured Twitter API class.
86
87 Get RESTful data by accessing members of this class. The result
88 is decoded python objects (lists and dicts).
89
90 The Twitter API is documented here:
153dee29
HN
91
92 http://apiwiki.twitter.com/
93 http://groups.google.com/group/twitter-development-talk/web/api-documentation
7364ea65 94
95 Examples::
96
97 twitter = Twitter("hello@foo.com", "password123")
98
99 # Get the public timeline
100 twitter.statuses.public_timeline()
101
102 # Get a particular friend's timeline
103 twitter.statuses.friends_timeline(id="billybob")
104
105 # Also supported (but totally weird)
106 twitter.statuses.friends_timeline.billybob()
107
108 # Send a direct message
109 twitter.direct_messages.new(
110 user="billybob",
111 text="I think yer swell!")
112
153dee29
HN
113 Searching Twitter::
114
115 twitter_search = Twitter(domain="search.twitter.com")
116
117 # Find the latest search trends
118 twitter_search.trends()
119
120 # Search for the latest News on #gaza
121 twitter_search(q="#gaza")
122
7364ea65 123 Using the data returned::
124
125 Twitter API calls return decoded JSON. This is converted into
126 a bunch of Python lists, dicts, ints, and strings. For example,
127
128 x = twitter.statuses.public_timeline()
129
130 # The first 'tweet' in the timeline
131 x[0]
132
133 # The screen name of the user who wrote the first 'tweet'
134 x[0]['user']['screen_name']
a55e6a11 135
136 Getting raw XML data::
137
138 If you prefer to get your Twitter data in XML format, pass
139 format="xml" to the Twitter object when you instantiate it:
140
141 twitter = Twitter(format="xml")
7364ea65 142
a55e6a11 143 The output will not be parsed in any way. It will be a raw string
144 of XML.
7364ea65 145 """
153dee29 146 def __init__(self, email=None, password=None, format="json", domain="twitter.com"):
7364ea65 147 """
148 Create a new twitter API connector using the specified
a55e6a11 149 credentials (email and password). Format specifies the output
150 format ("json" (default) or "xml").
7364ea65 151 """
a55e6a11 152 if (format not in ("json", "xml")):
153 raise TwitterError("Unknown data format '%s'" %(format))
153dee29 154 TwitterCall.__init__(self, email, password, format, domain)
7364ea65 155
5b8b1ead 156__all__ = ["Twitter", "TwitterError"]