]> jfr.im git - z_archive/twitter.git/blame - twitter/api.py
Automatically generating _POST_ACTIONS list.
[z_archive/twitter.git] / twitter / api.py
CommitLineData
7364ea65 1
2from base64 import b64encode
5251ea48 3from urllib import urlencode
7364ea65 4
de072195 5import urllib2
7364ea65 6
5251ea48 7from exceptions import Exception
8
4e9d6343
HN
9from twitter.twitter_globals import _POST_ACTIONS
10
f1a8ed67 11def _py26OrGreater():
12 import sys
13 return sys.hexversion > 0x20600f0
14
15if _py26OrGreater():
16 import json
17else:
18 import simplejson as json
19
5251ea48 20class TwitterError(Exception):
21e3bd23 21 """
22 Exception thrown by the Twitter object when there is an
23 error interacting with twitter.com.
24 """
5251ea48 25 pass
26
7364ea65 27class TwitterCall(object):
c8d451e8 28 def __init__(
45688301 29 self, username, password, format, domain, uri="", agent=None):
7364ea65 30 self.username = username
31 self.password = password
a55e6a11 32 self.format = format
153dee29 33 self.domain = domain
7364ea65 34 self.uri = uri
4a6070c8 35 self.agent = agent
7364ea65 36 def __getattr__(self, k):
37 try:
38 return object.__getattr__(self, k)
39 except AttributeError:
40 return TwitterCall(
153dee29 41 self.username, self.password, self.format, self.domain,
45688301 42 self.uri + "/" + k, self.agent)
7364ea65 43 def __call__(self, **kwargs):
da45d039 44 uri = self.uri
7364ea65 45 method = "GET"
2dab41b1
MV
46 for action in _POST_ACTIONS:
47 if self.uri.endswith(action):
48 method = "POST"
4ad03f81
MV
49 if (self.agent):
50 kwargs["source"] = self.agent
2dab41b1 51 break
da45d039
MV
52
53 id = kwargs.pop('id', None)
54 if id:
55 uri += "/%s" %(id)
4e9d6343 56
5b8b1ead 57 encoded_kwargs = urlencode(kwargs.items())
7364ea65 58 argStr = ""
de072195
HN
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
5b8b1ead 66
67 headers = {}
4a6070c8
HN
68 if (self.agent):
69 headers["X-Twitter-Client"] = self.agent
5b8b1ead 70 if (self.username):
71 headers["Authorization"] = "Basic " + b64encode("%s:%s" %(
72 self.username, self.password))
5b8b1ead 73
de072195
HN
74 req = urllib2.Request(
75 "http://%s/%s.%s%s" %(self.domain, self.uri, self.format, argStr),
76 argData, headers
77 )
7364ea65 78 try:
de072195
HN
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):
7364ea65 86 return []
de072195 87 else:
1c11e6d7 88 raise TwitterError(
da45d039 89 "Twitter sent status %i for URL: %s.%s using parameters: (%s)\ndetails: %s" %(
25de7f81 90 e.code, uri, self.format, encoded_kwargs, e.fp.read()))
de072195 91
7364ea65 92class Twitter(TwitterCall):
93 """
94 The minimalist yet fully featured Twitter API class.
4e9d6343 95
7364ea65 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 100
0b486eda
HN
101 http://apiwiki.twitter.com/
102 http://groups.google.com/group/twitter-development-talk/web/api-documentation
4e9d6343 103
7364ea65 104 Examples::
4e9d6343 105
7364ea65 106 twitter = Twitter("hello@foo.com", "password123")
4e9d6343 107
7364ea65 108 # Get the public timeline
109 twitter.statuses.public_timeline()
4e9d6343 110
7364ea65 111 # Get a particular friend's timeline
112 twitter.statuses.friends_timeline(id="billybob")
4e9d6343 113
7364ea65 114 # Also supported (but totally weird)
115 twitter.statuses.friends_timeline.billybob()
4e9d6343 116
7364ea65 117 # Send a direct message
118 twitter.direct_messages.new(
119 user="billybob",
120 text="I think yer swell!")
121
153dee29 122 Searching Twitter::
4e9d6343 123
0b486eda 124 twitter_search = Twitter(domain="search.twitter.com")
153dee29 125
0b486eda
HN
126 # Find the latest search trends
127 twitter_search.trends()
153dee29 128
0b486eda
HN
129 # Search for the latest News on #gaza
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']
4e9d6343 144
a55e6a11 145 Getting raw XML data::
4e9d6343 146
a55e6a11 147 If you prefer to get your Twitter data in XML format, pass
148 format="xml" to the Twitter object when you instantiate it:
4e9d6343 149
a55e6a11 150 twitter = Twitter(format="xml")
4e9d6343 151
a55e6a11 152 The output will not be parsed in any way. It will be a raw string
153 of XML.
7364ea65 154 """
45688301
MV
155 def __init__(
156 self, email=None, password=None, format="json", domain="twitter.com",
157 agent=None):
7364ea65 158 """
159 Create a new twitter API connector using the specified
a55e6a11 160 credentials (email and password). Format specifies the output
161 format ("json" (default) or "xml").
7364ea65 162 """
a55e6a11 163 if (format not in ("json", "xml")):
164 raise TwitterError("Unknown data format '%s'" %(format))
4ad03f81 165 TwitterCall.__init__(self, email, password, format, domain, "", agent)
7364ea65 166
5b8b1ead 167__all__ = ["Twitter", "TwitterError"]