I read the book Introduction to Tornado. It introduces the asynchronous feature of tornado in an application using twitter search API.
The code is as follows:
class IndexHandler(tornado.web.RequestHandler):
#tornado.web.asynchronous
#tornado.gen.engine
def get(self):
query = self.get_argument('q')
client = tornado.httpclient.AsyncHTTPClient()
response = yield tornado.gen.Task(client.fetch,
"http://search.twitter.com/search.json?" + \
urllib.urlencode({"q": query, "result_type": "recent", "rpp": 100}))
...
self.finish()
It uses the v1 twitter API to search a keywork. However, the new v1.1 twitter API forbids the use of non oauth request. As a result, I have to use the oauth library with my consumer key and access key to request the twitter search API.
def request_twitter(url, http_method = 'GET', post_body = '', http_headers = ''):
consumer = oauth.Consumer(key = consumer_key, secret = consumer_secret)
token = oauth.Token(key = access_token, secret = access_secret)
client = oauth.Client(consumer, token)
request = client.request(url, method = http_method, body = post_body, headers = http_headers)
return request
But the oauth client doesn't provide the asynchronous way to request. So I want to know how can I make the asynchronous request using oauth client to twitter API in python? Thanks.
Take a look at the TwitterMixin that is supplied with Tornado and study its code a bit.
Related
I'm trying to retrieve mails from my organization's mailbox, and I can do that via Graph Explorer. However, when I use the same information that I used in Graph Explorer, the generated token returns an error stating '/me request is only valid with delegated authentication flow.' in me/messages endpoint.
So, how can I generate the acceptable token for the /me endpoint?
An example python code or example Postman request would be amazing.
It sounds like the endpoint you're using in Graph Explorer is something like this
https://graph.microsoft.com/v1.0/me/messages
/me is referring to the user signed into Graph Explorer. If you want to read another user's messages you would use
https://graph.microsoft.com/v1.0/users/user#domain.com/messages
When connecting to Graph API as an application with no user interaction, you can never use /me endpoints, as there's no user logged in.
Reference
https://learn.microsoft.com/en-us/graph/api/user-list-messages?view=graph-rest-1.0
Python example to list messages
import requests
def get_messages(access_token, user):
request_url = f"https://graph.microsoft.com/v1.0/users/{user}/messages"
request_headers = {
"Authorization": "Bearer " + access_token
}
result = requests.get(url = request_url, headers = request_headers)
return(result)
msgs = get_messages(access_token = token['access_token'], user = "userPrincipalName#domain.com")
print(msgs.content)
Additional example of obtaining a token, using an app registration and client secret
import msal
def get_token_with_client_secret(client_id, client_secret, tenant_id):
# This function is to obtain a bearer token using the client credentials flow, with a client secret instead of a certificate
# https://docs.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=CS#client-credentials-provider
app = msal.ConfidentialClientApplication(
client_id = client_id,
client_credential = client_secret,
authority = f"https://login.microsoftonline.com/{tenant_id}")
scopes = ["https://graph.microsoft.com/.default"]
token = app.acquire_token_for_client(scopes = scopes)
return(token)
I'm trying access some resources behind Amazon API gateway. One must be authenticated with Cognito to access the resources. I am very confused however how I should request the data. I have been successful in using warrant to authenticate but I am very confused how construct the call (using requests) for the data.
I just need to get data for a simple ETL pipeline which will run in Jenkins or similar.
from warrant.aws_srp import AWSSRP
import requests
USERNAME='foo'
PASSWORD='barfoo'
POOL_ID='eu-west-1_XXXXXXX'
CLIENT_ID = 'foobar'
aws = AWSSRP(username=USERNAME, password=PASSWORD, pool_id=POOL_ID,
client_id=CLIENT_ID)
tokens = aws.authenticate_user()
id_token = tokens['AuthenticationResult']['IdToken']
refresh_token = tokens['AuthenticationResult']['RefreshToken']
access_token = tokens['AuthenticationResult']['AccessToken']
token_type = tokens['AuthenticationResult']['TokenType']
print(tokens)
headers={
"x-amz-security-token": ???,
"authorization": ???,
???: ??? }
url="https://foo.execute-api.eu-west-1.amazonaws.com/foo/bar"
r = requests.get(url, headers=headers)
print(r.text)
I'm trying to register a Twitter webhook on an API I create on AWS API Gateway. I was able to set up the CRC portion which provides the appropriate response through a browser however I'm unable to make post requests to the same endpoint. I've been following multiple guides on this including this and this
The code is below that is giving a 403 response:
from urllib.parse import quote_plus
from requests_oauthlib import OAuth1Session
import json
import tweepy
import urllib
CONSUMER_KEY = 'xxxxxxxxxxxxx'
CONSUMER_SECRET = 'xxxxxxxxxxxxx'
ACCESS_TOKEN = 'xxxxxxxxxxxxx'
ACCESS_SECRET = 'xxxxxxxxxxxxx'
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://#######.execute-api.us-east-2.amazonaws.com/dev/webhook")
url = 'https://api.twitter.com/1.1/account_activity/all/:env_name/'
def register_webhook(url,twitter,webhook_endpoint):
url+=f'webhooks.json?url={webhook_endpoint}'
response = twitter.post(url)
print(response)
def subscribe_to_user_activity(url,twitter):
url+=f'subscriptions.json'
response = twitter.post(url)
print(response)
if __name__ == '__main__':
register_webhook(url,twitter,webhook_endpoint)
subscribe_to_user_activity(url,twitter)```
A couple of things I checked:
I can verify that the account is approved for account activity API, I created and counter checked the dev environment label, Keys were regenerated twice, Testing on Postman as advised here is giving a 200 forbidden response and doesn't work
In postman, I selected Oauth1.0 as the auth type and fill in Consumer Key, Consumer Secret, Access Token, Token Secret values, and provided the URL endpoint in the body. Is the POST request being sent to https://api.twitter.com/1.1/account_activity/all/:my_env_name/webhooks.json?
On the AWS side, the POST method was created on the resource with all default values
Any idea where I could be going wrong? Or a foolproof method of registering a Twitter webhook with AWS API gateway as the listener?
So, there is a code that uses xAuth authentication to call tumblr API methods:
import urllib
import urlparse
import oauth2 as oauth
consumer_key = "..."
consumer_secret = "..."
consumer = oauth.Consumer(consumer_key, consumer_secret)
client = oauth.Client(consumer)
resp, content = client.request('https://www.tumblr.com/oauth/access_token', "POST", urllib.urlencode({
'x_auth_mode': 'client_auth',
'x_auth_username': '...#yandex.ru',
'x_auth_password': '...'
}))
token = dict(urlparse.parse_qsl(content))
print token
token = oauth.Token(token['oauth_token'], token['oauth_token_secret'])
client = oauth.Client(consumer, token)
response, data = client.request('http://api.tumblr.com/v2/blog/good.tumblr.com/followers', method='GET')
print data
It works perfect with User methods from tumblr API that require OAuth authentication.
But it fails when i try to call any Blog method with OAuth authentication (/followers for example):
{"meta":{"status":401,"msg":"Not Authorized"},"response":[]}
Except one thing. If i use my blog name as {base-hostname} parameter it works without any errors.
Weird. How is that possible? Is something wrong with the code?
Well that is because your OAuth access token grants you access to your blogs. OAuth can't give you permission to access Blog methods that you do not own because then you could post to them.
When you make POST request the enctype must be "multipart/form-data".
I had the same problem with Zend_Oauth (php), but is resolved now.
RequestError: Unable to upgrade OAuth request token to access token: 400, signature_invalid
base_string:POST&https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthGetAccessToken&oauth_consumer_key%3Dcalendar-auth.appspot.com%26oauth_nonce%3D646112512717164%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1306760936%26oauth_token%3D4%252F-cP-Ai1NzxDtLehvtzRbGd4SHZ1-%26oauth_verifier%3DPYGMYX8riH9AfpJvTEh_Ztzm%26oauth_version%3D1.0
I am new to google apps development.was trying to implement OAuth in a web application.When i call GetAccessToken() method then it shows the above error.Please help me out frokm this....
I am using the following code... :
class MainHandler(webapp.RequestHandler):
def get(self):
CONSUMER_KEY = 'xyz'
CONSUMER_SECRET = 'xyz'
SCOPES = ['https://docs.google.com/feeds/', 'https://www.google.com/calendar/feeds/'] # example of a multi-scoped token
client = gdata.docs.client.DocsClient(source='xyz')
oauth_callback_url = 'http://%s/get_access_token' % self.request.host
request_token = client.GetOAuthToken(
SCOPES, oauth_callback_url, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET)
memcache.add("rtoken",request_token,3600)
domain = 'default' # If on a Google Apps domain, use your domain (e.g. 'example.com').
url = str(request_token.generate_authorization_url(google_apps_domain=domain))
self.redirect(url)
class AuthToken(webapp.RequestHandler):
def get(self):
client = gdata.docs.client.DocsClient(source='xyz')
saved_request_token = memcache.get("rtoken")
request_token = gdata.gauth.AuthorizeRequestToken(saved_request_token, self.request.uri)
self.response.out.write("Got the token")
access_token = client.GetAccessToken(request_token)
https://www.google.com/accounts/OAuthGetAccessToken
{
oauth_consumer_key=calendar-auth.appspot.com
oauth_nonce=646112512717164
oauth_signature_method=HMAC-SHA1
oauth_timestamp=1306760936
oauth_token=4/-cP-Ai1NzxDtLehvtzRbGd4SHZ1-
oauth_verifier=PYGMYX8riH9AfpJvTEh_Ztzm
oauth_version=1.0
}
I would recommend against posting oauth tokens to the public.
According to http://wiki.oauth.net/w/page/12238555/Signed-Callback-URLs, you should be posting oauth_signature, but I don't see it in the list