Error when trying to authenticate Spotify: Bad Request Error - python

I was trying to run the following code on my jupyter notebook:
import spotipy
sp = spotipy.Spotify()
from spotipy.oauth2 import SpotifyClientCredentials
import spotipy.util as util
# setting up authorization
cid ="my client id"
secret = "my client secret"
# saving the info you're going to need
username = 'your_account_number'
scope = 'user-library-read' #check the documentation
authorization_url = 'https://accounts.spotify.com/authorize'
token_url = 'https://accounts.spotify.com/api/token'
redirect_uri ='https://localhost.com/callback/'
token = util.prompt_for_user_token(username,scope,client_id='client_id_number',client_secret='client_secret',redirect_uri='https://localhost.com/callback/')
client_credentials_manager = SpotifyClientCredentials(client_id=cid, client_secret=secret)
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
Which would redirect me to a site. However the site just contains a text saying "INVALID_CLIENT: Invalid client" and nothing else. When I paste this URL in the prompt, I keep getting a Bad Request error. I would be grateful for any help or guidance you can provide. Thanks!

this was the code that worked for me:
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import spotipy.util as util
import os
from Spotify_isplaying import isplay
os.environ["SPOTIPY_CLIENT_ID"] = '' # client id
os.environ["SPOTIPY_CLIENT_SECRET"] = '' # Secret ID
os.environ["SPOTIPY_REDIRECT_URI"] = '' # Redirect URI
username = "" # username
client_credentials_manager = SpotifyClientCredentials(client_id="SPOTIPY_CLIENT_ID",client_secret="SPOTIPY_CLIENT_SECRET")
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
scope = '' # scope needed for your programme
token = util.prompt_for_user_token(username, scope)
if token:
sp = spotipy.Spotify(auth=token)
else:
print("Can't get token for", username)
# where you put your code

Related

Spotipy same data for two users

I'm trying to get two users' top tracks. Why does this program produce the same results for both users? (user_2 is getting user_1's results). I've allowed access for both of the Spotify accounts in question.
import spotipy
from spotipy import util
from spotipy.oauth2 import SpotifyOAuth
import pandas as pd
CLIENT_ID = CLIENT_ID
CLIENT_SECRET = CLIENT_SECRET
REDIRECT_URI = REDIRECT_URI
# list of Spotify usernames to get top tracks for
usernames = ["user_1", "user_2"]
# Spotify API scope
scope = 'user-top-read'
tokens = []
for username in usernames:
token = util.prompt_for_user_token(username, scope, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri)
if token:
tokens.append(token)
else:
print(f"Can't get token for {username}")
sp = spotipy.Spotify(auth=tokens[0]) # initialize the Spotify object using the first token
user_ids = []
for token, username in zip(tokens, usernames):
sp = spotipy.Spotify(auth=token)
user_id = sp.current_user()['id'] # get the user ID
user_ids.append(user_id) # add the user ID to the list
# now make API requests for each user's top tracks
for user_id, username in zip(user_ids, usernames):
print(f"Top tracks for {username}:")
top_tracks = sp.current_user_top_tracks(limit=10, time_range='short_term') # make API request
for i, track in enumerate(top_tracks['items']):
print(f"{i+1}. {track['name']} by {track['artists'][0]['name']}")
print()

Youtube Data API v3 - Skip "Please visit this URL" & enter authorization code?

I'm trying to get the video list of my youtube channel and update it as i please, i've done it with .net & it's quite easy, But in python it's kind of disturbing each time i run the script i got the message of "Please visit this URL to authorize this application" Althought i use the same credentials.json file i use it on .net.
NB: No need to mark down this question for duplicate or anything because i already check many Many of the same question here on stackover like this , this & this other forums too but none seems to provide a clear concrete solution every solution so far i've tried has the same result.
Here's the sample code i'm using :
Any help will be much appreciated.
import os
import sys
file_path = os.path.dirname(__file__)
module_path = os.path.join(file_path, "lib")
sys.path.append(module_path)
import pickle
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
scopes = [
"https://www.googleapis.com/auth/youtube",
"https://www.googleapis.com/auth/youtube.upload",
"https://www.googleapis.com/auth/youtubepartner",
"https://www.googleapis.com/auth/youtube.force-ssl",
]
client_secrets_file = "credentials.json"
api_service_name = "youtube"
api_version = "v3"
def main():
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
client_secrets_file, scopes)
youtube = get_authenticated_service()
request = youtube.channels().list(
part="contentDetails",
mine=True
)
response = request.execute()
print(response)
def get_authenticated_service():
if os.path.exists("CREDENTIALS_PICKLE_FILE"):
with open("CREDENTIALS_PICKLE_FILE", 'rb') as f:
credentials = pickle.load(f)
else:
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(client_secrets_file, scopes)
credentials = flow.run_console()
with open("CREDENTIALS_PICKLE_FILE", 'wb') as f:
pickle.dump(credentials, f)
return googleapiclient.discovery.build(
api_service_name, api_version, credentials=credentials)
if __name__ == "__main__":
main()
I luckily found the solution to this problem, and here a sample working script that will list all the video you have in ur YouTube channel and will ask for authorization Code just one time.
i know it's a bit messy but it's ok
import os
import sys
file_path = os.path.dirname(__file__)
module_path = os.path.join(file_path, "lib")
sys.path.append(module_path)
import httplib2
import json
import argparse
import re
import random
from pytz import timezone
from dateutil import parser
from datetime import datetime
from googleapiclient.discovery import build
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import argparser, run_flow
random.seed()
CLIENT_SECRETS_FILE = "credentials.json"
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0
To make this sample run you will need to populate the client_secrets.json file
found at: %swith information from the Developers Console
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),CLIENT_SECRETS_FILE))
scopes = [
"https://www.googleapis.com/auth/youtube",
"https://www.googleapis.com/auth/youtube.upload",
"https://www.googleapis.com/auth/youtubepartner",
"https://www.googleapis.com/auth/youtube.force-ssl",
]
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE,message=MISSING_CLIENT_SECRETS_MESSAGE, scope=scopes)
storage = Storage("%s-oauth2.json" % sys.argv[0])
credentials = storage.get()
if credentials is None or credentials.invalid:
flags = argparser.parse_args()
credentials = run_flow(flow, storage, flags)
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
http=credentials.authorize(httplib2.Http()))
channels_response = youtube.channels().list(
mine=True,
part="contentDetails"
).execute()
for channel in channels_response["items"]:
uploads_list_id = channel["contentDetails"]["relatedPlaylists"]["uploads"]
print("Videos in list {0:s}".format(uploads_list_id),file=sys.stderr)
playlistitems_list_request = youtube.playlistItems().list(
playlistId=uploads_list_id,
part="snippet",
maxResults=50
)
playlistitems_list_response = playlistitems_list_request.execute()
for playlist_item in playlistitems_list_response["items"]:
title = playlist_item["snippet"]["title"]
video_id = playlist_item["snippet"]["resourceId"]["videoId"]
video_list_request = youtube.videos().list(
id=video_id,
part="snippet,fileDetails,statistics,status",
maxResults=50
)
video_list_response = video_list_request.execute()
for video_list_item in video_list_response["items"]:
print(title)
print (video_id)
print (video_list_item["fileDetails"]["fileName"])
print (video_list_item["statistics"]["viewCount"])
print (video_list_item["statistics"]["likeCount"])
print (video_list_item["snippet"]["description"])
print (video_list_item["snippet"]["publishedAt"])
print (video_list_item["status"]["privacyStatus"])

Can anyone tell me why I'm still getting an INVALID_CLIENT message? Spotipy on mac

I am trying to build a Spotify player with python and spotipy. I keep getting a message that says INVALID_CLIENT. The client id is entered properly along with the secret and the username
import spotipy
import spotipy.util as util
from spotipy.oauth2 import SpotifyClientCredentials
cid ="xx"
secret = "xx"
username = "xx"
client_credentials_manager = SpotifyClientCredentials(client_id=cid, client_secret=secret)
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
scope = 'user-library-read playlist-read-private'
token = util.prompt_for_user_token(username,scope,client_id='http://localhost:8888/callback/',client_secret='http://localhost:8888/callback/',redirect_uri='http://localhost:8888/callback/')
if token:
sp = spotipy.Spotify(auth=token)
else:
print("Can't get token for", username)
cache_token = token.get_access_token()
sp = spotipy.Spotify(cache_token)
currentfaves = sp.current_user_top_tracks(limit=20, offset=0, time_range='medium_term')
print(currentfaves)
You're using both the Client Credentials and Authorization Code Flow. To get user's top tracks, you need to use Authorization Code Flow.
You should remove the client credentials lines, then make sure the util.prompt_for_user_token call is configured properly. In your code, you have all parameters set to your redirect URI, which is giving you the Invalid Client error. Seems like you're following the Spotipy documentation, which is incorrect for this call. I'll try to make a PR.
Your code should look like this:
import spotipy
import spotipy.util as util
cid ="xx"
secret = "xx"
username = "xx"
scope = 'user-library-read playlist-read-private'
token = util.prompt_for_user_token(username,scope,client_id=cid,client_secret=secret,redirect_uri='http://localhost:8888/callback/')
if token:
sp = spotipy.Spotify(auth=token)
else:
print("Can't get token for", username)
cache_token = token.get_access_token()
sp = spotipy.Spotify(cache_token)
currentfaves = sp.current_user_top_tracks(limit=20, offset=0, time_range='medium_term')
print(currentfaves)

Twitter API OAuth cannot find 'authorization_url'

I'm writing a code that uses Twitter API to get users' statuses, number of followers etc. I need to write a script that opens browser and asks users to sign in and let me get the authentication from them.
from requests_oauthlib import OAuth1Session
import requests
from requests_oauthlib import OAuth1
from urlparse import parse_qs
client_key = "keykeykeykey"
client_secret = "keykeykeykeykey"
request_token_url = 'https://api.twitter.com/oauth/request_token'
oauth = OAuth1Session(client_key, client_secret=client_secret)
fetch_response = oauth.fetch_request_token(request_token_url)
#print(fetch_response)
resource_owner_key = fetch_response.get('oauth_token')
resource_owner_secret = fetch_response.get('oauth_token_secret')
oauth = OAuth1(client_key, client_secret=client_secret)
r = requests.post(url=request_token_url, auth=oauth)
#print(r.content)
credentials = parse_qs(r.content)
resource_owner_key = credentials.get('oauth_token')[0]
resource_owner_secret = credentials.get('oauth_token_secret')[0]
base_authorization_url = 'https://api.twitter.com/oauth/authorize'
authorization_url = oauth.authorization_url(base_authorization_url)
print 'Please go here and authorize,', authorization_url
redirect_response = raw_input('Paste the full redirect URL here: ')
oauth_response = oauth.parse_authorization_response(redirect_response)
#print(oauth_response)
verifier = oauth_response.get('oauth_verifier')
authorize_url = base_authorization_url + '?oauth_token='
authorize_url = authorize_url + resource_owner_key
print 'Please go here and authorize,', authorize_url
verifier = raw_input('Please input the verifier')
I have found this kind of example from internet but it gives an error like :
AttributeError: 'OAuth1' object has no attribute 'authorization_url'
I have checked the session info and actually there is authorization_url here:
https://github.com/requests/requests-oauthlib/blob/master/requests_oauthlib/oauth1_session.py
It looks like you use the oauth variable as an OauthSession object and a Oauth1 object.
oauth = OAuth1Session(client_key, client_secret=client_secret)
oauth = OAuth1(client_key, client_secret=client_secret)
It should work if you use it as a session object

Creating a DfpClient with a Service Account in Python

I use the google DFP api to collect some statistics on ads clicked on our website. The
code is written in Python. Currently, I am trying to upgrade the code to use oAuth 2.
Since, the code runs automatically everyday without any user involvement, I created a
service account under my google project and added the account to the DoubleClick for
Publishers network of our company. Based on the sample codes on the web, I wrote this:
import httplib2
from oauth2client.client import SignedJwtAssertionCredentials
from apiclient.discovery import build
from googleads.dfp import DfpClient
GOOGLE_DFP_SCOPE="https://www.googleapis.com/auth/dfp"
API_VERSION="v201411"
KEY_FILE="*******.p12"
ACCT_EMAIL="************************#developer.gserviceaccount.com"
NETWORK_CODE="**********"
with open(KEY_FILE) as config_file:
my_private_key = config_file.read()
credentials = SignedJwtAssertionCredentials(service_account_name=ACCT_EMAIL, private_key=my_private_key,scope=GOOGLE_DFP_SCOPE)
http = httplib2.Http()
http_auth = credentials.authorize(http)
dfp_client = build(serviceName='dfp',version=API_VERSION,http=http_auth)
This code does not seem to be correct, because the network_code has not been passed
anywhere in the code. In addition, it fails with the following message:
apiclient.errors.UnknownApiNameOrVersion: name: dfp version: v201411.
Also, the line below:
dfp_client = DfpClient.LoadFromStorage()
does not work for my case, because, this is based on googleads.yaml which seems
to be formatted only for web-app accounts with client secret, not P12 private key.
Any advice? Thanks.
Apiclient.discovery uses a default route to check the services.
But I did not find a service for DoubleClick for publishers.
I use this code to use API with Oauth2. Using Flask
import json
import requests
import flask
from googleads import dfp
from googleads import oauth2
app = flask.Flask(__name__)
CLIENT_ID = ''
CLIENT_SECRET = '' # Read from a file or environmental variable in a real app
SCOPE = 'https://www.googleapis.com/auth/dfp'
REDIRECT_URI = ''
APPLICATION_NAME = 'DFP API SERVICE'
NETWORK_CODE = ''
#app.route('/')
def index():
if 'credentials' not in flask.session:
return flask.redirect(flask.url_for('oauth2callback'))
credentials = json.loads(flask.session['credentials'])
if credentials['expires_in'] <= 0:
return flask.redirect(flask.url_for('oauth2callback'))
else:
try:
refresh_token = credentials['refresh_token']
oauth2_client = oauth2.GoogleRefreshTokenClient(CLIENT_ID, CLIENT_SECRET, refresh_token)
dfp_client = dfp.DfpClient(oauth2_client, APPLICATION_NAME, NETWORK_CODE)
user_service = dfp_client.GetService('UserService', version='v201508')
user = user_service.getCurrentUser()
return flask.render_template('index.html', name=user['name'])
except:
flask.session.pop('credentials', None)
return flask.redirect(flask.url_for('oauth2callback'))
#app.route('/oauth2callback')
def oauth2callback():
if 'code' not in flask.request.args:
auth_uri = ('https://accounts.google.com/o/oauth2/auth?response_type=code'
'&access_type=offline&client_id={}&redirect_uri={}&scope={}&').format(CLIENT_ID, REDIRECT_URI, SCOPE)
return flask.redirect(auth_uri)
else:
auth_code = flask.request.args.get('code')
data = {'code': auth_code,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'redirect_uri': REDIRECT_URI,
'grant_type': 'authorization_code'}
r = requests.post('https://www.googleapis.com/oauth2/v3/token', data=data)
flask.session['credentials'] = r.text
return flask.redirect(flask.url_for('index'))
if __name__ == '__main__':
import uuid
app.secret_key = str(uuid.uuid4())
app.debug = False
app.run()
I hope this help you
You are correct. You have to pass the network code when you create a dfp client. And version is not necessary. Try the following code to create the client in python.
import os
from googleads import oauth2
from googleads import dfp
def get_dfp_client():
application_name = "Your application name" # from google developer console. eg: Web Client
network_code = ********
private_key_password = 'notasecret'
key_file = os.path.join('path/to/p12file')
service_account_email = '****#***.iam.gserviceaccount.com'
# create oath2 client(google login)
oauth2_client = oauth2.GoogleServiceAccountClient(
oauth2.GetAPIScope('dfp'), service_account_email, key_file)
dfp_client = dfp.DfpClient(oauth2_client, application_name, network_code)
return dfp_client
client = get_dfp_client()
Reference
Please comment if you need more clarification.
Update
googleads renamed module dfp to ad_manager, docs here – Gocht

Categories

Resources