]> jfr.im git - z_archive/twitter.git/blob - twitter/api.py
First stab at searching
[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 if kwargs.has_key('id'):
54 uri += "/%s" %(kwargs['id'])
55
56 encoded_kwargs = urlencode(kwargs.items())
57 argStr = ""
58 argData = None
59 if (method == "GET"):
60 if kwargs:
61 argStr = "?%s" %(encoded_kwargs)
62 else:
63 argData = encoded_kwargs
64
65 headers = {}
66 if (self.agent):
67 headers["X-Twitter-Client"] = self.agent
68 if (self.username):
69 headers["Authorization"] = "Basic " + b64encode("%s:%s" %(
70 self.username, self.password))
71
72 req = urllib2.Request(
73 "http://%s/%s.%s%s" %(self.domain, uri, self.format, argStr),
74 argData, headers
75 )
76 try:
77 handle = urllib2.urlopen(req)
78 if "json" == self.format:
79 return json.loads(handle.read())
80 else:
81 return handle.read()
82 except urllib2.HTTPError, e:
83 if (e.code == 304):
84 return []
85 else:
86 raise TwitterError(
87 "Twitter sent status %i for URL: %s.%s using parameters: (%s)\ndetails: %s" %(
88 e.code, uri, self.format, encoded_kwargs, e.fp.read()))
89
90 class Twitter(TwitterCall):
91 """
92 The minimalist yet fully featured Twitter API class.
93
94 Get RESTful data by accessing members of this class. The result
95 is decoded python objects (lists and dicts).
96
97 The Twitter API is documented here:
98
99 http://apiwiki.twitter.com/
100 http://groups.google.com/group/twitter-development-talk/web/api-documentation
101
102 Examples::
103
104 twitter = Twitter("hello@foo.com", "password123")
105
106 # Get the public timeline
107 twitter.statuses.public_timeline()
108
109 # Get a particular friend's timeline
110 twitter.statuses.friends_timeline(id="billybob")
111
112 # Also supported (but totally weird)
113 twitter.statuses.friends_timeline.billybob()
114
115 # Send a direct message
116 twitter.direct_messages.new(
117 user="billybob",
118 text="I think yer swell!")
119
120 Searching Twitter::
121
122 twitter_search = Twitter(domain="search.twitter.com")
123
124 # Find the latest search trends
125 twitter_search.trends()
126
127 # Search for the latest News on #gaza
128 twitter_search.search(q="#gaza")
129
130 Using the data returned::
131
132 Twitter API calls return decoded JSON. This is converted into
133 a bunch of Python lists, dicts, ints, and strings. For example,
134
135 x = twitter.statuses.public_timeline()
136
137 # The first 'tweet' in the timeline
138 x[0]
139
140 # The screen name of the user who wrote the first 'tweet'
141 x[0]['user']['screen_name']
142
143 Getting raw XML data::
144
145 If you prefer to get your Twitter data in XML format, pass
146 format="xml" to the Twitter object when you instantiate it:
147
148 twitter = Twitter(format="xml")
149
150 The output will not be parsed in any way. It will be a raw string
151 of XML.
152 """
153 def __init__(
154 self, email=None, password=None, format="json", domain="twitter.com",
155 agent=None):
156 """
157 Create a new twitter API connector using the specified
158 credentials (email and password). Format specifies the output
159 format ("json" (default) or "xml").
160 """
161 if (format not in ("json", "xml")):
162 raise TwitterError("Unknown data format '%s'" %(format))
163 TwitterCall.__init__(self, email, password, format, domain, "", agent)
164
165 __all__ = ["Twitter", "TwitterError"]