]> jfr.im git - z_archive/twitter.git/blob - twitter/api.py
Documentation for searching was incorrect, fixed
[z_archive/twitter.git] / twitter / api.py
1
2 from base64 import b64encode
3 from urllib import urlencode
4
5 import httplib
6
7 from exceptions import Exception
8
9 def _py26OrGreater():
10 import sys
11 return sys.hexversion > 0x20600f0
12
13 if _py26OrGreater():
14 import json
15 else:
16 import simplejson as json
17
18 class TwitterError(Exception):
19 """
20 Exception thrown by the Twitter object when there is an
21 error interacting with twitter.com.
22 """
23 pass
24
25 class TwitterCall(object):
26 def __init__(self, username, password, format, domain, uri=""):
27 self.username = username
28 self.password = password
29 self.format = format
30 self.uri = uri
31 self.domain = domain
32 def __getattr__(self, k):
33 try:
34 return object.__getattr__(self, k)
35 except AttributeError:
36 return TwitterCall(
37 self.username, self.password, self.format, self.domain,
38 self.uri + "/" + k)
39 def __call__(self, **kwargs):
40 method = "GET"
41 if (self.uri.endswith('new')
42 or self.uri.endswith('update')
43 or self.uri.endswith('create')
44 or self.uri.endswith('destroy')):
45 method = "POST"
46
47 encoded_kwargs = urlencode(kwargs.items())
48 argStr = ""
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
60 c = httplib.HTTPConnection(self.domain)
61 try:
62 c.putrequest(method, "%s.%s%s" %(
63 self.uri, self.format, argStr))
64 for item in headers.iteritems():
65 c.putheader(*item)
66 c.endheaders()
67 if method == "POST":
68 c.send(encoded_kwargs)
69 r = c.getresponse()
70
71 if (r.status == 304):
72 return []
73 elif (r.status != 200):
74 raise TwitterError("Twitter sent status %i: %s" %(
75 r.status, r.read()))
76 if "json" == self.format:
77 return json.loads(r.read())
78 else:
79 return r.read()
80 finally:
81 c.close()
82
83 class 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:
91
92 http://apiwiki.twitter.com/
93 http://groups.google.com/group/twitter-development-talk/web/api-documentation
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
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.search(q="#gaza")
122
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']
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")
142
143 The output will not be parsed in any way. It will be a raw string
144 of XML.
145 """
146 def __init__(self, email=None, password=None, format="json", domain="twitter.com"):
147 """
148 Create a new twitter API connector using the specified
149 credentials (email and password). Format specifies the output
150 format ("json" (default) or "xml").
151 """
152 if (format not in ("json", "xml")):
153 raise TwitterError("Unknown data format '%s'" %(format))
154 TwitterCall.__init__(self, email, password, format, domain)
155
156 __all__ = ["Twitter", "TwitterError"]