Tweepy streaming returns 401 Authorization Required - python

I am trying to connect to the twitter stream api to fetch tweets in realtime. This piece of code was working till 5-6 ago. Suddenly I've started receiving 401 all the time. Strangely this is both happening in my local machine and on our production server which is located in cloud, so I think this is not a network related issue.
Here is the code:
l = StdOutListener()
auth = OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
auth.callback = 'https://localhost' #no effect commented/uncommented
stream = Stream(auth, l)
stream.filter(track=['twitter'], languages=["es"])
So far I've tried the following:
Generating new consumer key, consumer secret, access token and access token secret. I've used 4 different set of keys which was working previously.
Created a fresh new app from apps.twitter.com. Filled the callback url as some users reported that 401 "Authorization Required" is related with the callback URL field missing in the application page of twitter.
Synced my clock with an ntp server, both on my local and on production server. My clock is not off.
My application have the correct privileges and I received access token and secret after the configuration.
Here is the request:
'Content-Length': '22'
'Content-Type': 'application/x-www-form-urlencoded'
'Authorization': 'OAuth oauth_nonce="161484371946745487981492681844"
oauth_timestamp="1492681844"
oauth_version="1.0"
oauth_signature_method="HMAC-SHA1"
oauth_consumer_key="<oauth_consumer_key>"
oauth_token="<oauth_token>"
oauth_signature="tphQqFWaBvEo2byjZ%2BRqNAM30I0%3D"'
Method: 'POST'
URL: 'https://stream.twitter.com/1.1/statuses/filter.json?delimited=length'
Any help would be appreciated on why I am getting a 401 Unauthorized "Need Authorization" response.
Edit: I've also tried using Twython and I got the same response back from twitter.
Thanks

Maybe you can try using Twython OAuth2 to connect if you don't need to tweet back
Twython Auth
Or try using this code.
# Put the consumer keys
auth = tweepy.OAuthHandler("consumer_key", "consumer_secret")
# Redirect user to Twitter to authorize
redirect_user(auth.get_authorization_url())
# Get access token
auth.get_access_token("verifier_value")
# Construct the API instance
api = tweepy.API(auth)
#Create the stream
streamClass= StdOutListener()
stream= tweepy.Stream(auth = api.auth, listener=streamClass)
This should work.
Maybe your bot is not authorised on the account and this may be the error. But I don't think it's the case.
Check out my BOT's auth if you want an example :
ED_Postcards BOT
(New version incoming with pretty code)

I was able to solve the issue after 2 weeks of troubleshooting. For tweepy you need to manually set the callback url of the auth object you use to authenticate with the twitter.
After this correction head to apps.twitter.com and uncheck the box "Allow this application to to be used to Sign in with Twitter". Twitter API is not concise at all with the error messages.

Related

Tweepy + api v1 + keys

I have python code that posts tweets to twitter using oauth2 and that works fine but I need to attach some images to tweets and it seems that has to be done with api v1.1
On the twitter dev portal under project settings, user authentication it says "oAuth 1.0a and OAuth 2.0 turned on" and the Oauth 1.0a settings app permissions are read and write. I'm confused about which keys I should be using for Oauth 1.0a as when I use the consumer keys like this
my_api_key="xxx"
my_api_secret="xxx"
auth = tw.OAuthHandler(my_api_key, my_api_secret)
api = tw.API(auth, wait_on_rate_limit=True)
tweet = api.update_status("Testing tweepy API v1")
I get the error 220 - Your credentials do not allow access to this resource.
If I copy the access keys from the OAuth2 code that works then I get this error
32 - Could not authenticate you.
The OAuth2 code that works looks like this:
api = tweepy.Client(bearer_token=keys.twitter_bearer,
access_token=keys.access_key,
access_token_secret=keys.access_secret,
consumer_key=keys.consumer_key,
consumer_secret=keys.consumer_secret_key)
api.create_tweet(text=str)
I'm not sure what I'm doing wrong.
edit - am elevated
Went back to basics and investigated the code as everything else sounds right.
Turns out I was just doing it wrong.
This works:
auth = tweepy.OAuth1UserHandler(
consumer_key, consumer_secret, access_token, access_token_secret
)
api = tweepy.API(auth)
image=".\dataframe.png"
media=api.media_upload(image)
try:
api.update_status("Test",media_ids=[media.media_id])
except Exception as e:
print(e.class)
print(f"Exception occured - {e}")
else:
print("Success")

Learning to use Tweepy and Twitter API

I'm currently trying to learn the Twitter API within Python. My code is this:
import tweepy
consumer_key = "Consumer Key"
consumer_secret = "Consumer Secret"
access_token = "Access Token"
access_token_secret = "Access Token Secret"
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_acess_token(access_token, access_token_secret)
auth.secure = True
api = tweepy.API(auth)
tweet = "This tweet was made from a program"
api.update_status(status=tweet)
However this is the error that the code is giving me:
Forbidden: 403 Forbidden
453 - You currently have Essential access which includes access to Twitter API v2 endpoints only. If you need access to this endpoint, you’ll need to apply for Elevated access via the Developer Portal. You can learn more here: https://developer.twitter.com/en/docs/twitter-api/getting-started/about-twitter-api#v2-access-leve
Process finished with exit code 1
Do I really need to apply for further access just to tweet one thing? Thanks
Twitter has a newer (v2) API. You should use tweepy.Client to be able to use the new endpoints without signing up.

Tweepy API v2 "NoneType"

import tweepy
client = tweepy.Client(consumer_key='REPLACE_ME',
consumer_secret='REPLACE_ME',
access_token='REPLACE_ME',
access_token_secret='REPLACE_ME')
# Replace the text with whatever you want to Tweet about
response = client.create_tweet(text='hello world')
print(response)
I am currently trying to work with this template code, but this is the error that I am currently getting:
TypeError: Consumer key must be string or bytes, not NoneType
I'm not sure how this counts as a NoneType error, the Consumer Key, Consumer Secret, Access Token, and Access Token Secret are all in quotations so they should be a string.
Thank you!
You can try something like this if you want to post a tweet.
import tweepy
consumerKey = 'REPLACE_ME'
consumerSecret = 'REPLACE_ME'
accessToken = 'REPLACE_ME'
accessTokenSecret = 'REPLACE_ME'
auth = tweepy.OAuthHandler(consumerKey, consumerSecret)
auth.set_access_token(accessToken, accessTokenSecret)
api = tweepy.API(auth)
status = api.update_status(status="Hello world!")
I replicated your code on my machine (I am using Twitter API v2). I get an Unauthorized 401 error. The first argument to tweepy.Client() should be the bearer token, in addition to the 4 other keys of course.
After that, you may face Forbidden: 403 issues with Client.create_tweet() if you have not given your app write permissions. See how you can address this issue in the answer to this post.

Can't register webhook for Twitter Account Activity API [python3]

I'm trying to set up a Twitter app using the Account Activity API, to replace my old set up which used the user streaming endpoint. I want to be able to get DM messages to one user sent to a particular URL in real time.
Following these migration instructions, I've set up a webhook endpoint on my site, as described here. I've checked that process is working, by making sure that when I open https://example.com/webhook_endpoint?crc_token=foo in my browser, I get a token in response.
Now I'm trying and failing to register my webhook. I'm using the following code, and getting a 403 response.
from requests_oauthlib import OAuth1Session
import urllib
CONSUMER_KEY = 'my consumer key'
CONSUMER_SECRET = 'my consumer secret'
ACCESS_TOKEN = 'my access token'
ACCESS_SECRET = 'my access secret'
twitter = OAuth1Session(CONSUMER_KEY,
client_secret=CONSUMER_SECRET,
resource_owner_key=ACCESS_TOKEN,
resource_owner_secret=ACCESS_SECRET)
webhook_endpoint = urllib.parse.quote_plus('https://example.com/webhook/')
url = 'https://api.twitter.com/1.1/account_activity/all/env-beta/'
'webhooks.json?url={}'.format(webhook_endpoint)
r = twitter.post(url)
403 response content: {"errors":[{"code":200,"message":"Forbidden."}]}
I can successfully post a status using the same session object and
r = twitter.post('https://api.twitter.com/1.1/statuses/update.json?status=Test')
What am I doing wrong here?
This turned out to be due to a combination of:
Not having created an environment here: https://developer.twitter.com/en/account/environments as described here: https://developer.twitter.com/en/docs/accounts-and-users/subscribe-account-activity/guides/getting-started-with-webhooks
using the wrong consumer secret in the function that created the token returned at the /webhook endpoint

Oauth client initialization in python for tumblr API using Python-oauth2

I'm new to Oauth. In the past for twitter applications written in Python i used python-oauth2 library to initialize client like this:
consumer = oauth.Consumer(key = CONSUMER_KEY, secret = CONSUMER_SECRET)
token = oauth.Token(key = ACCESS_KEY, secret = ACCESS_SECRET)
client = oauth.Client(consumer, token)
That was easy because twitter provides both CONSUMER and ACCESS keys and secrets. But now i need to do the same for tumblr. The problem is that tumblr provides only CONSUMER_KEY, CONSUMER_SECRET and these urls:
Request-token URL http://www.tumblr.com/oauth/request_token
Authorize URL http://www.tumblr.com/oauth/authorize
Access-token URL http://www.tumblr.com/oauth/access_token
Using this data how can i initialize client to access tumblr API?
UPD
jterrace suggested a code i tried to use before. The problem with it is oauth_callback. If i don't specify any, api returns error "No oauth_callback specified", but if i do specify some url like "http://example.com/oauthcb/" and follow the link http://www.tumblr.com/oauth/authorize?oauth_token=9ygTF..., then press Allow button, tumblr doesn't show any PIN code page, it immediately redirects to that callback url, which is useless since it's desktop application. Why PIN code isn't shown?
UPD 2
Tumblr API doesn't support PIN code authorization. Use xAuth instead - https://groups.google.com/group/tumblr-api/browse_thread/thread/857285e6a2b4268/15060607dc306c1d?lnk=gst&q=pin#15060607dc306c1d
First, import the oauth2 module and set up the service's URL and consumer information:
import oauth2
REQUEST_TOKEN_URL = 'http://www.tumblr.com/oauth/request_token'
AUTHORIZATION_URL = 'http://www.tumblr.com/oauth/authorize'
ACCESS_TOKEN_URL = 'http://www.tumblr.com/oauth/access_token'
CONSUMER_KEY = 'your_consumer_key'
CONSUMER_SECRET = 'your_consumer_secret'
consumer = oauth2.Consumer(CONSUMER_KEY, CONSUMER_SECRET)
client = oauth2.Client(consumer)
Step 1: Get a request token. This is a temporary token that is used for
having the user authorize an access token and to sign the request to obtain
said access token.
resp, content = client.request(REQUEST_TOKEN_URL, "GET")
request_token = dict(urlparse.parse_qsl(content))
print "Request Token:"
print " - oauth_token = %s" % request_token['oauth_token']
print " - oauth_token_secret = %s" % request_token['oauth_token_secret']
Step 2: Redirect to the provider. Since this is a CLI script we do not
redirect. In a web application you would redirect the user to the URL
below.
print "Go to the following link in your browser:"
print "%s?oauth_token=%s" % (AUTHORIZATION_URL, request_token['oauth_token'])
# After the user has granted access to you, the consumer, the provider will
# redirect you to whatever URL you have told them to redirect to. You can
# usually define this in the oauth_callback argument as well.
oauth_verifier = raw_input('What is the PIN? ')
Step 3: Once the consumer has redirected the user back to the oauth_callback
URL you can request the access token the user has approved. You use the
request token to sign this request. After this is done you throw away the
request token and use the access token returned. You should store this
access token somewhere safe, like a database, for future use.
token = oauth2.Token(request_token['oauth_token'], request_token['oauth_token_secret'])
token.set_verifier(oauth_verifier)
client = oauth2.Client(consumer, token)
resp, content = client.request(ACCESS_TOKEN_URL, "POST")
access_token = dict(urlparse.parse_qsl(content))
print "Access Token:"
print " - oauth_token = %s" % access_token['oauth_token']
print " - oauth_token_secret = %s" % access_token['oauth_token_secret']
print
Now that you have an access token, you can call protected methods with it.
EDIT: Turns out that tumblr does not support the PIN authorization method. Relevant post here.
If you just want to gain an access-token/secret to sign, you could just setup your callback URL as: http://localhost/blah
Fireup the CLI-app (after modifying the callback-url, secret and token ofcourse)
Follow the link in your browser
Allow app
View addressbar of the page you've been redirected to in the browser after allowing your app. It should look something like:
http://localhost/blah?oauth_token=xxxxxxxxxxxxxxxxxxxxxxxxxx0123456789ABCDEFGHIJKLMN&oauth_verifier=XXXXXXXXXXXXXXXXXXXXXXXXX0123456789abcdefghijklmn
Use the value of the query-parameter 'oauth_verifier' as your PIN:
XXXXXXXXXXXXXXXXXXXXXXXXX0123456789abcdefghijklmn
The CLI should print out your oauth-token and oauth-token-secret.
HTH! Got this working for tumblr in this way :)
Have a look at https://github.com/ToQoz/Pyblr
It uses oauth2 and urllib to provide a nice wrapper for exactly what you're trying to do.
It seems that what you're trying to do is access an OAuth 1 API with an OAuth 2 client.
See https://github.com/simplegeo/python-oauth2 and look for “three-legged OAuth example”.
had this problem with oauth2 and facebook.
#deepvanbinnen's answer lead me into the right direction.
facebook actually redirected to a page similar to this
'http://localhost/blah?code=AQAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#_=_'
using then the ' AQAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#_=_ as the PIN actually got me the access to the requested facebook account.
#jterrance's answer is good. However, realize it is a one _time_ manual procedure to get the access token. The access token is the key that you use for all subsequent API calls. (That's why he recommends saving the access token in a database.) The string referred to as 'PIN' (aka the verification key) is not necessarily a number. It can be a printable string in any form. That verification key is displayed on the authorization page at the URL printed in step 2 then pasted into the prompt for a the 'PIN'.

Categories