public
Description: Python Twitter API
Homepage: http://mike.verdone.ca/twitter/
Clone URL: git://github.com/sixohsix/twitter.git
twitter / twitter / api.py
100644 167 lines (130 sloc) 4.878 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
from base64 import b64encode
from urllib import urlencode
 
import urllib2
 
from exceptions import Exception
 
from twitter.twitter_globals import POST_ACTIONS
 
def _py26OrGreater():
    import sys
    return sys.hexversion > 0x20600f0
 
if _py26OrGreater():
    import json
else:
    import simplejson as json
 
class TwitterError(Exception):
    """
Exception thrown by the Twitter object when there is an
error interacting with twitter.com.
"""
    pass
 
class TwitterCall(object):
    def __init__(
        self, username, password, format, domain, uri="", agent=None):
        self.username = username
        self.password = password
        self.format = format
        self.domain = domain
        self.uri = uri
        self.agent = agent
    def __getattr__(self, k):
        try:
            return object.__getattr__(self, k)
        except AttributeError:
            return TwitterCall(
                self.username, self.password, self.format, self.domain,
                self.uri + "/" + k, self.agent)
    def __call__(self, **kwargs):
        uri = self.uri
        method = "GET"
        for action in POST_ACTIONS:
            if self.uri.endswith(action):
                method = "POST"
                if (self.agent):
                    kwargs["source"] = self.agent
                break
 
        id = kwargs.pop('id', None)
        if id:
            uri += "/%s" %(id)
 
        argStr = ""
        argData = None
        encoded_kwargs = urlencode(kwargs.items())
        if (method == "GET"):
            if kwargs:
                argStr = "?%s" %(encoded_kwargs)
        else:
            argData = encoded_kwargs
 
        headers = {}
        if (self.agent):
            headers["X-Twitter-Client"] = self.agent
        if (self.username):
            headers["Authorization"] = "Basic " + b64encode("%s:%s" %(
                self.username, self.password))
 
        req = urllib2.Request(
                "http://%s/%s.%s%s" %(self.domain, uri, self.format, argStr),
                argData, headers
            )
        try:
            handle = urllib2.urlopen(req)
            if "json" == self.format:
                return json.loads(handle.read())
            else:
                return handle.read()
        except urllib2.HTTPError, e:
            if (e.code == 304):
                return []
            else:
                raise TwitterError(
                    "Twitter sent status %i for URL: %s.%s using parameters: (%s)\ndetails: %s" %(
                        e.code, uri, self.format, encoded_kwargs, e.fp.read()))
 
class Twitter(TwitterCall):
    """
The minimalist yet fully featured Twitter API class.
 
Get RESTful data by accessing members of this class. The result
is decoded python objects (lists and dicts).
 
The Twitter API is documented here:
 
http://apiwiki.twitter.com/
http://groups.google.com/group/twitter-development-talk/web/api-documentation
 
Examples::
 
twitter = Twitter("hello@foo.com", "password123")
 
# Get the public timeline
twitter.statuses.public_timeline()
 
# Get a particular friend's timeline
twitter.statuses.friends_timeline(id="billybob")
 
# Also supported (but totally weird)
twitter.statuses.friends_timeline.billybob()
 
# Send a direct message
twitter.direct_messages.new(
user="billybob",
text="I think yer swell!")
 
Searching Twitter::
 
twitter_search = Twitter(domain="search.twitter.com")
 
# Find the latest search trends
twitter_search.trends()
 
# Search for the latest News on #gaza
twitter_search.search(q="#gaza")
 
Using the data returned::
 
Twitter API calls return decoded JSON. This is converted into
a bunch of Python lists, dicts, ints, and strings. For example,
 
x = twitter.statuses.public_timeline()
 
# The first 'tweet' in the timeline
x[0]
 
# The screen name of the user who wrote the first 'tweet'
x[0]['user']['screen_name']
 
Getting raw XML data::
 
If you prefer to get your Twitter data in XML format, pass
format="xml" to the Twitter object when you instantiate it:
 
twitter = Twitter(format="xml")
 
The output will not be parsed in any way. It will be a raw string
of XML.
"""
    def __init__(
        self, email=None, password=None, format="json", domain="twitter.com",
        agent=None):
        """
Create a new twitter API connector using the specified
credentials (email and password). Format specifies the output
format ("json" (default) or "xml").
"""
        if (format not in ("json", "xml")):
            raise TwitterError("Unknown data format '%s'" %(format))
        TwitterCall.__init__(self, email, password, format, domain, "", agent)
 
__all__ = ["Twitter", "TwitterError"]