Tweepy + App Engine Example OAuth Help
Hi I am trying to follow the Tweepy App Engine OAuth Example app in my app but am running into trouble.
Here is a link to the tweepy example code: http://github.com/joshthecoder/tweepy-examples Specifically look at: http://github.com/joshthecoder/tweepy-examples/blob/master/appengine/oauth_example/handlers.py
Here is the relevant snippet of my code [Ignore the spacing problems]:
try:
authurl = auth.get_authorization_url()
request_token = auth.request_token
db_user.token_key = request_token.key
db_user.token_secret = request_token.secret
db_user.put()
except tweepy.TweepError, e:
# Failed to get a request token
self.generate('error.html', {
'error': e,
})
return
self.generate('signup.html', {
'authurl': authurl,
'request_token': request_token,
'request_token.key': request_token.key,
'request_token.secret': request_token.secret,
})
As you can see my code is very similar to the example. However, when I compare the version of the request_token.key and request_token.secret that are rendered on my signup page
I.e. the variables I output to the browser:
request_token.key
request_token.secret
Are not the same as the data stored in the datastore:
db_user.token_key = request_token.key
db_user.token_secret = request_token.secret
db_user.put()
As an example here is what I am seeing when testing:
Printed to the screen:
request_token.key: MocXJxcqzDJu6E0yBeaC5sAMSkEoH9NxrwZDDvlVU
request_token.secret: C7EdohrWVor9Yjmr58jbObFmWj0GdBHMMMrIkU8Fds
Valu开发者_Go百科es in the datastore:
token_key: 4mZQc90GXCqcS6u1LuEe60wQN53A0fj7wdXHQrpDo
token_secret: dEgr8cvBg9jmPNhPV55gaCwYw5wcCdDZU4PUrMPVqk
Any guidance on what I am doing wrong here?
Thanks!
Reference Links:
Here is a sample code to get Twitter followers-count for a single user using Tweepy (version 2.0) on Google App Engine (GAE) in Python (version 2.7).
# ----GAE MODULES-----------
import webapp2
from webapp2_extras import jinja2
from google.appengine.api import users
import tweepy
import urlparse
import logging
# ----JINJA2 TEMPLATE----------
class TemplateHandler(webapp2.RequestHandler):
@webapp2.cached_property
def jinja2(self):
return jinja2.get_jinja2(app=self.app)
def render_template(self, filename, **template_args):
logging.info('calling jinja2 render function %s %s', self, filename)
self.response.write(self.jinja2.render_template(filename, **template_args))
# ----CODE--------------------
class TwitterTweepyImplementation(TemplateHandler):
'''
All Tweepy related methods are handled in this class
'''
#All methods that expect HTTP GET
twitter_tweepy_impl_get_methods = {
'/tweepyimpl/oauthRedirect': 'redirect_to_twitter_for_user_to_enter_uname_and_pwd',
'/tweepyimpl/oauthCallback': 'handle_callback_from_twitter_after_user_authentication',
}
def get(self):
'''
All twitter specific get actions are handled here
'''
#identify page to display from the path in the URL
rcvd_url = self.request.path
#to keep the code a little easier to understand, there are no security checks or exception handling coded added in
#this code example, so please add those on your own.
#get destination method using key-value pair
dest_method = self.__class__.twitter_tweepy_impl_get_methods.get(rcvd_url, None)
if dest_method:
func = getattr(self, dest_method, None)
if func:
func()
return
def redirect_to_twitter_for_user_to_enter_uname_and_pwd(self):
"""
Twitter OAuth Redirection: redirects user to Twitter for entering user name and password
"""
logging.info('redirect_to_twitter_for_user_to_enter_uname_and_pwd')
auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, YOUR_OWN_REDIRECT_URL_AFTER_TWITTER_AUTHENTICATION)
'''YOUR_OWN_REDIRECT_URL_AFTER_TWITTER_AUTHENTICATION: you can set this everytime above or once at twitter.com from where
you get your Consumer Key and Consumer Secret. E.g., http://www.yourwebsite.com/tweepyimpl/oauthCallback'''
#get Twitter redirect url where user enters credentials (uname and pwd)
auth_url = auth.get_authorization_url(); #logging.info("auth_url = %s", auth_url);
#store temp credentials as browser cookies (these need to be stored in the browser so that after user completes authentication
#at Twitter.com, when user is redirected to the return URL above by Twitter (= YOUR_OWN_REDIRECT_URL_AFTER_TWITTER_AUTHENTICATION)
#your application server knows for which user this redirect is for).
self.response.set_cookie('token_key', auth.request_token.key)
self.response.set_cookie('token_secret', auth.request_token.secret)
#redirect user's browser to twitter auth URL where user can enter username and pwd
self.redirect(auth_url)
return
def handle_callback_from_twitter_after_user_authentication(self):
"""
Callback from Twitter after user enters user name and pwd at twitter.com URL
"""
logging.info('handle_callback_from_twitter_after_user_authentication')
#Twitter redirected browser here. Now read verifier and determine if user twitter authentication succeeded, failed, or was
#canceled by the user
auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET)
verifier = self.request.get('oauth_verifier', None); #logging.info('verifier = %s', verifier)
#user canceled twitter oauth
if not verifier:
self.redirect('your_app_url') #add your own url here.
return
#fetch temp credentials from browser cookies (as set during redirect_to_twitter_for_user_to_enter_uname_and_pwd method).
token_key = self.request.cookies['token_key'];
token_secret = self.request.cookies['token_secret'];
#now exchange temp credentials for user specific access token
auth.set_request_token(token_key, token_secret)
#parse access token string to extract the key and the secret
access_token = auth.get_access_token(verifier=verifier); logging.info('access_token = %s', access_token)
params = urlparse.parse_qs(str(access_token), keep_blank_values=False)
access_key = params['oauth_token'][0]; logging.info('access_key = %s', access_key)
access_secret = params['oauth_token_secret'][0]; logging.info('access_secret = %s', access_secret)
#add access token information to the datastore for periodic fetch of Twitter information later on for this user, e.g., via a cron job.
user_obj = UserTwitterAccessTokenStorageDatabase.get_by_key_name(users.get_current_user().email())
user_obj.access_key = access_key
user_obj.access_secret = access_secret
user_obj.put()
auth.set_access_token(access_key, access_secret) #this statement you can use later on to fetch twitter data for any user whose
#access-key/secret you have stored in your database. For example, via a cron job.
#User does NOT need to be visiting your website for you to fetch twitter data for the user.
#use tweepy api now to get user data from Twitter
api = tweepy.API(auth)
me = api.me()
#display debug information
logging.info("me = %s", me)
logging.info('me.id_str = %s, name = %s, screen_name = %s', me.id_str, me.name, me.screen_name)
#get followers count for this user
user = api.get_user(me.id_str)
logging.info('num_followers = %s', user.followers_count)
#you have the required information - in this code example followers-count. now redirect user to your app determined URL
self.redirect('your_app_url') #add your own url here.
app = webapp2.WSGIApplication([
('/tweepyimpl/.*', TwitterTweepyImplementation)
], debug=const.DEBUG)
It seems you use twice request_token
, request_token.key
and request_token.secret
. The second time ( in self.generate
) you should read their values from your database and not request them again.
精彩评论