]>
jfr.im git - z_archive/twitter.git/blob - twitter/oauth.py
2 Visit the Twitter developer page and create a new application:
4 https://dev.twitter.com/apps/new
6 This will get you a CONSUMER_KEY and CONSUMER_SECRET.
8 When users run your application they have to authenticate your app
9 with their Twitter account. A few HTTP calls to twitter are required
10 to do this. Please see the twitter.oauth_dance module to see how this
11 is done. If you are making a command-line app, you can use the
12 oauth_dance() function directly.
14 Performing the "oauth dance" gets you an ouath token and oauth secret
15 that authenticate the user with Twitter. You should save these for
16 later so that the user doesn't have to do the oauth dance again.
18 read_token_file and write_token_file are utility methods to read and
19 write OAuth token and secret key values. The values are stored as
20 strings in the file. Not terribly exciting.
22 Finally, you can use the OAuth authenticator to connect to Twitter. In
23 code it all goes like this::
27 MY_TWITTER_CREDS = os.path.expanduser('~/.my_app_credentials')
28 if not os.path.exists(MY_TWITTER_CREDS):
29 oauth_dance("My App Name", CONSUMER_KEY, CONSUMER_SECRET,
32 oauth_token, oauth_secret = read_token_file(MY_TWITTER_CREDS)
34 twitter = Twitter(auth=OAuth(
35 oauth_token, oauth_token_secret, CONSUMER_KEY, CONSUMER_SECRET))
37 # Now work with Twitter
38 twitter.statuses.update(status='Hello, world!')
42 from __future__
import print_function
44 from random
import getrandbits
47 from .util
import PY_3_OR_HIGHER
50 import urllib
.parse
as urllib_parse
51 from urllib
.parse
import urlencode
53 import urllib2
as urllib_parse
54 from urllib
import urlencode
60 from .auth
import Auth
, MissingCredentialsError
63 def write_token_file(filename
, oauth_token
, oauth_token_secret
):
65 Write a token file to hold the oauth token and oauth token secret.
67 oauth_file
= open(filename
, 'w')
68 print(oauth_token
, file=oauth_file
)
69 print(oauth_token_secret
, file=oauth_file
)
72 def read_token_file(filename
):
74 Read a token file and return the oauth token and oauth token secret.
77 return f
.readline().strip(), f
.readline().strip()
82 An OAuth authenticator.
84 def __init__(self
, token
, token_secret
, consumer_key
, consumer_secret
):
86 Create the authenticator. If you are in the initial stages of
87 the OAuth dance and don't yet have a token or token_secret,
88 pass empty strings for these params.
91 self
.token_secret
= token_secret
92 self
.consumer_key
= consumer_key
93 self
.consumer_secret
= consumer_secret
95 if token_secret
is None or consumer_secret
is None:
96 raise MissingCredentialsError(
97 'You must supply strings for token_secret and consumer_secret, not None.')
99 def encode_params(self
, base_url
, method
, params
):
100 params
= params
.copy()
103 params
['oauth_token'] = self
.token
105 params
['oauth_consumer_key'] = self
.consumer_key
106 params
['oauth_signature_method'] = 'HMAC-SHA1'
107 params
['oauth_version'] = '1.0'
108 params
['oauth_timestamp'] = str(int(time()))
109 params
['oauth_nonce'] = str(getrandbits(64))
111 enc_params
= urlencode_noplus(sorted(params
.items()))
113 key
= self
.consumer_secret
+ "&" + urllib_parse
.quote(self
.token_secret
, safe
='~')
116 urllib_parse
.quote(i
, safe
='~') for i
in [method
.upper(), base_url
, enc_params
])
118 signature
= (base64
.b64encode(hmac
.new(
119 key
.encode('ascii'), message
.encode('ascii'), hashlib
.sha1
)
121 return enc_params
+ "&" + "oauth_signature=" + urllib_parse
.quote(signature
, safe
='~')
123 def generate_headers(self
):
126 # apparently contrary to the HTTP RFCs, spaces in arguments must be encoded as
127 # %20 rather than '+' when constructing an OAuth signature (and therefore
128 # also in the request itself.)
129 # So here is a specialized version which does exactly that.
130 # In Python2, since there is no safe option for urlencode, we force it by hand
131 def urlencode_noplus(query
):
132 if not PY_3_OR_HIGHER
:
134 TILDE
= '____TILDE-PYTHON-TWITTER____'
136 if type(k
) is unicode: k
= k
.encode('utf-8')
137 k
= str(k
).replace("~", TILDE
)
138 if type(v
) is unicode: v
= v
.encode('utf-8')
139 v
= str(v
).replace("~", TILDE
)
140 new_query
.append((k
, v
))
142 return urlencode(query
).replace(TILDE
, "~").replace("+", "%20")
144 return urlencode(query
, safe
='~').replace("+", "%20")