https://github.com/soundcloud/soundcloud-python
I'm using the Python wrapper above, and I am struggling to get the access token.
import soundcloud
client = soundcloud.Client(
client_id=YOUR_CLIENT_ID,
client_secret=YOUR_CLIENT_SECRET,
redirect_uri='http://yourapp.com/callback'
)
redirect(client.authorize_url())
I am able to reach this point and it successfully allows the user to authorize. However I am lost as to how I am supposed to get the access token.
The documentation says the following:
access_token, expires, scope, refresh_token = client.exchange_token(
code=request.args.get('code'))
render_text("Hi There, %s" % client.get('/me').username)
When I use this, it gives me a 500 error.
On redirect client.authorize_url(), the user will be redirected to a SoundCloud connect screen in their browser and asked to authorize their account with your application.
If the user approves the authorization request, they will be sent to the redirect_uri specified in redirect_uri='http://yourapp.com/callback'. From there, you can extract the code parameter from the query string and use it to obtain an access token.
import soundcloud
# create client object with app credentials
client = soundcloud.Client(client_id='YOUR_CLIENT_ID',
client_secret='YOUR_CLIENT_SECRET',
redirect_uri='http://example.com/callback')
# exchange authorization code for access token
code = params['code']
access_token = client.exchange_token(code)
This is straight from the Server-Side Authentication docs.
You could use selenium webdriver
pip install --upgrade selenium
to open a browser window, log in to the soundcloud account and get the code.
#!/usr/bin/env python
# coding=utf-8
import soundcloud
from selenium import webdriver
driver = webdriver.Firefox(
executable_path='<YOUR_PATH_TO>/geckodriver')
CLIENT_ID='<YOUR_CLIENT_ID>'
CLIENT_SECRET='<YOUR_CLIENT_SECRET>'
REDIRECT_URL='<YOUR_REDIRECT_URL>'
client = soundcloud.Client(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URL)
AUTH_URL = client.authorize_url()
driver.get(AUTH_URL) ## open Firefox to access Soundcloud
code = raw_input("WAITING FOR ACCESS... type ENTER")
code = driver.current_url.replace(REDIRECT_URL+'/?code=','')[:-1]
ACCESS_TOKEN = client.exchange_token(code).access_token
USER = client.get('/me').permalink
FILE = "SOUNDCLOUD.%s.access_token" % USER
FILE_W = open(FILE,'w')
FILE_W.write(ACCESS_TOKEN)
FILE_W.close()
driver.quit()
Maybe you'll need to get geckodriver, you can google it to find the one for your OS.
Note that this access_token is not expiring. You don't need a refresh_token.
You can print the full response object with:
from pprint import pprint
[...]
code = driver.current_url.replace(REDIRECT_URL+'/?code=','')[:-1]
TOKEN_OBJECT = client.exchange_token(code)
pprint (vars(TOKEN_OBJECT))
ACCESS_TOKEN = TOKEN_OBJECT.access_token
[...]
Related
I'm building a simple application using the Spotipy API. It has been working for myself and now I'm trying to expand it so that users can log in with their spotify account. When I try to obtain the link for them to verify their credentials and open it in browser, the localhost refuses to connect.
I'm using the SpoityOAuth method, passing in my client_id and client_secret, along with a redirect_uri (http://localhost:8888/callback), and then I'm calling the get_authorize_url() method to get the link and using webbrowser.open to open that link in browser. My credentials and redirect uri are consistent with my developer settings and my program, so I'm not sure what the issue is. Any help would be appreciated!
Here is the code:
# sp_oauth = SpotifyOAuth(client_id= cred.client_id, client_secret= cred.client_secret,redirect_uri= cred.redirect_url, scope='user-top-read') url = sp_oauth.get_authorize_url() webbrowser.open(url)
You can use the following code:
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from pprint import pprint
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=cred.client_id,client_secret=cred.client_secret,redirect_uri=cred.redirect_url,scope="user-top-read"))
data = sp.current_user_top_artists(limit=20, offset=0, time_range='medium_term')
pprint(data)
I am working to create a pipeline with the spotify API that logs my streaming history. I am planning to automate it by uploading it as a lambda function and scheduling it to run every few hours. I have everything mostly in order, except for that on the first run the API requires web authentication. Here is my code:
import spotipy
import spotipy.util as util
import urllib3
un = USERNAME
scope = 'user-read-recently-played'
cid = CLIENT_ID
csid = CLIENT_SECRET_ID
redr = r'http://localhost:8888/callback/'
token = util.prompt_for_user_token(un,scope,cid,csid,redr)
When this is run for the first time, this message pops up:
User authentication requires interaction with your
web browser. Once you enter your credentials and
give authorization, you will be redirected to
a url. Paste that url you were directed to to
complete the authorization.
Opened <LINK HERE> in your browser
Enter the URL you were redirected to:
And then I have to copy the link from my browser into that space. I can get the URL that I need to paste using urllib3:
req_adr = ADDRESS_IT_OPENS_IN_BROWSER
http = urllib3.PoolManager()
resp = http.request('GET',req_adr)
redrurl = resp.geturl()
But I don't know how to pass it into the input prompt from the util.prompt_for_user_token response
Any suggestions would be very welcome.
So it turns out there is a workaround. You can run it one time on a local machine and that generates a a file called .cache-USERNAME. If you include that file in your deployment package you don't have to copy/paste the URL and it is able to be automated with a lambda function in AWS.
So i got a refresh token in this way and can I keep it?
And if so, how do I use it next time, so that there is no need for me to open browser?
Right now I'm thinking about creating OAuth2Credentials object directly, is this the right way?
from urllib.parse import urlparse, parse_qs
from oauth2client.client import flow_from_clientsecrets, OAuth2Credentials
from oauth2client.file import Storage
from oauth2client.tools import argparser, run_flow
from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.contrib import gce
import httplib2
import webbrowser
CLIENT_SECRETS_FILE = "bot_credentials.json"
flow = client.flow_from_clientsecrets(
CLIENT_SECRETS_FILE,
scope=scope,
redirect_uri='http://127.0.0.1:65010')
flow.params['include_granted_scopes'] = 'true'
flow.params['access_type'] = 'offline'
auth_uri = flow.step1_get_authorize_url()
webbrowser.open(auth_uri)
url = input('Please enter the redirected url with code')
code = get_url_param(url, 'code')
if code is None:
print('there is an error in your redirect link with code parameter, check if it exists')
exit()
print(code)
credentials = flow.step2_exchange(code[0])
print(credentials.to_json())#refresh_token here!!!
If the user consents to authorize your application to access those resources, Google will return a token to your application. Depending on your application's type, it will either validate the token or exchange it for a different type of token. Check this documentation.
For example, a server-side web application would exchange the returned token for an access token and a refresh token. The access token would let the application authorize requests on the user's behalf, and the refresh token would let the application retrieve a new access token when the original access token expires.
Basically, if your application obtains a refresh token during the authorization process, then you will need to periodically use that token to obtain a new, valid access token. Server-side web applications, installed applications, and devices all obtain refresh tokens.
It is stated here that at any time, your application can send a POST request to Google's authorization server that specifies your client ID, your client secret, and the refresh token for the user. The request should also set the grant_type parameter value to refresh_token.
The following example demonstrates this request:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
client_id=21302922996.apps.googleusercontent.com&
client_secret=XTHhXh1SlUNgvyWGwDk1EjXB&
refresh_token=1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ&
grant_type=refresh_token
The authorization server will return a JSON object that contains a new access token:
{
"access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in":3920,
"token_type":"Bearer"
}
You can check this sample on GitHub to generate a refresh token for the YouTube API. Note that this will will also create a file called generate_token.py-oauth that contains this information.
I'm attempting to write a Python script to create a Spotify playlist via the Spotipy application. I've successfully created an application in Spotify's Dev center and input the necessary variables into Spotipy's example (see below). However, the script is not authorizing properly. I've tried with and without a server running, but to no avail. There are similar questions on Stack but they do not offer complete solutions. Any suggestions would be very helpful.
Here is the message I am receiving via command prompt:
User authentication requires interaction with your
web browser. Once you enter your credentials and
give authorization, you will be redirected to
a url. Paste that url you were directed to to
complete the authorization.
Please navigate here:
https://accounts.spotify.com/authorize?scope=user-library-read&redirect_uri=None&response_type=code&client_id=xxxxx
Enter the URL you were redirected to:
And here is the script that's running. It's nearly identical to that example provided by Spotipy, with a change made for setting os variables for my Windows machine.
import pprint
import sys
import os
import subprocess
import spotipy
import spotipy.util as util
import requests
clientId = 'client id here'
clientSecret = 'client secret here'
clientRedirect = 'http://localhost:8888/callback'
username = 'username here'
scope='user-library-read'
os.environ["SPOTIPY_CLIENT_ID"] = clientId
os.environ["SPOTIPY_CLIENT_SECRET"] = clientSecret
os.environ["POTIPY_REDIRECT_URI"] = clientRedirect
token = util.prompt_for_user_token(username, scope)
if token:
sp = spotipy.Spotify(auth=token)
results = sp.current_user_saved_tracks()
for item in results['items']:
track = item['track']
print track['name'] + ' - ' + track['artists'][0]['name']
else:
print "Can't get token for", username
The application is asking a URL that should contain a "code" which will then be used to exchange with access_token as mentioned in Step.3 in https://developer.spotify.com/web-api/authorization-guide/ and the URL should look like this https://example.com/callback?code=NApCCg..BkWtQ&state=profile%2Factivity. I hope you are entering your credentials properly otherwise you will never get the code to proceed further.
I am trying to get started with the Box.com SDK and I have a few questions.
from boxsdk import OAuth2
oauth = OAuth2(
client_id='YOUR_CLIENT_ID',
client_secret='YOUR_CLIENT_SECRET',
store_tokens=your_store_tokens_callback_method,
)
auth_url, csrf_token = oauth.get_authorization_url('http://YOUR_REDIRECT_URL')
def store_tokens(access_token, refresh_token):
# store the tokens at secure storage (e.g. Keychain)
1)What is the redirect URL and how do I use it? Do I need to have a server running to use this?
2)What sort of code to I need in the store_tokens method?
The redirect URL is only required if you're runng a Web application that needs to respond to user's requests to authenticate. If you're programtically authenticating, you can simply set this as http://localhost. In a scenario where you require the user to manually authenticate, the redirect URL should invoke some function in your web app to store and process the authentication code returned. Do you need a server running? Well, if you want to do something with the authentication code returned, the URL you specify should be under your control and invoke code to do something useful.
Here's an example of what the store_tokens function should look like. It should accept two parameters, access_token and refresh_token. In the example below, the function will commit these to a local store for use when the API needs to re-authenticate:
From here:
"""An example of Box authentication with external store"""
import keyring
from boxsdk import OAuth2
from boxsdk import Client
CLIENT_ID = 'specify your Box client_id here'
CLIENT_SECRET = 'specify your Box client_secret here'
def read_tokens():
"""Reads authorisation tokens from keyring"""
# Use keyring to read the tokens
auth_token = keyring.get_password('Box_Auth', 'mybox#box.com')
refresh_token = keyring.get_password('Box_Refresh', 'mybox#box.com')
return auth_token, refresh_token
def store_tokens(access_token, refresh_token):
"""Callback function when Box SDK refreshes tokens"""
# Use keyring to store the tokens
keyring.set_password('Box_Auth', 'mybox#box.com', access_token)
keyring.set_password('Box_Refresh', 'mybox#box.com', refresh_token)
def main():
"""Authentication against Box Example"""
# Retrieve tokens from secure store
access_token, refresh_token = read_tokens()
# Set up authorisation using the tokens we've retrieved
oauth = OAuth2(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
access_token=access_token,
refresh_token=refresh_token,
store_tokens=store_tokens,
)
# Create the SDK client
client = Client(oauth)
# Get current user details and display
current_user = client.user(user_id='me').get()
print('Box User:', current_user.name)
if __name__ == '__main__':
main()
I suggest taking a look at the OAuth 2 tutorial. It will help give a better understanding of how OAuth works and what the various parameters are used for.
The redirect URL is set in your Box application's settings:
This is the URL where Box will send an auth code that can be used to obtain an access token. For example, if your redirect URL is set to https://myhost.com, then your server will receive a request with a URL that looks something like https://myhost.com?code=123456abcdef.
Note that your redirect URI doesn't need to be a real server. For example, apps that use a WebView will sometimes enter a fake redirect URL and then extract the auth code directly from the URL in the WebView.
The store_tokens callback is optional, but it can be used to save the access and refresh tokens in case your application needs to shutdown. It will be invoked every time the access token and refresh token changes, giving you an opportunity to save them somewhere (to disk, a DB, etc.).
You can then pass in these tokens to your OAuth2 constructor at a later time so that your users don't need to login again.
If you're just testing, you can also pass in a developer token. This tutorial explains how.
This is the most basic example that worked for me:
from boxsdk import Client, OAuth2
CLIENT_ID = ''
CLIENT_SECRET = ''
ACCESS_TOKEN = '' # this is the developer token
oauth2 = OAuth2(CLIENT_ID, CLIENT_SECRET, access_token=ACCESS_TOKEN)
client = Client(oauth2)
my = client.user(user_id='me').get()
print(my.name)
print(my.login)
print(my.avatar_url)