Spotify web api call gives wrong code (python) - python

To get an authorization code from the Spotify web api I use this code:
AUTH_URL = 'https://accounts.spotify.com/authorize'
TOKEN_URL = 'https://accounts.spotify.com/api/token'
BASE_URL = 'https://api.spotify.com/v1/'
CLIENT_ID = '******'
CLIENT_SECRET = '*****'
auth_code = requests.get(AUTH_URL, {
'client_id': CLIENT_ID,
'response_type': 'code',
'redirect_uri': 'uri',
'scope': 'playlist-modify-private',
})
auth_header = base64.urlsafe_b64encode((CLIENT_ID + ':' + CLIENT_SECRET).encode())
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic %s' % auth_header.decode('ascii')
}
payload = {
'grant_type': 'authorization_code',
'code': auth_code,
'redirect_uri': 'uri',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
}
access_token_request = requests.post(url=TOKEN_URL, data=payload, headers=headers)
access_token_response_data = access_token_request.json()
access_token = access_token_response_data['access_token']
Only the auth_code for getting the code from Spotify gives <Response 200> instead the code. What could be wrong?
I tried to print the auto code but it gives <Response 200> back. This is ultimately used in the call to Spotify for the token.

Authorization Code Flow in spotify needs a server feature at application side.
It can get code value from spotify server, then request token with code.
In code flow diagram, explain detail here
I will demo with Flask
File save as spotify-client.py
from flask import Flask, request, redirect
from requests_oauthlib import OAuth2Session
from requests.auth import HTTPBasicAuth
import requests
import json
app = Flask(__name__)
AUTH_URL = 'https://accounts.spotify.com/authorize'
TOKEN_URL = 'https://accounts.spotify.com/api/token'
REDIRECT_URI = '<your callback URI>' # my case is 'http://localhost:3000/callback'
CLIENT_ID = "<your client id>"
CLIENT_SECRET = "<your client secret>"
SCOPE = [
"user-read-email",
"playlist-read-collaborative"
]
#app.route("/login")
def login():
spotify = OAuth2Session(CLIENT_ID, scope=SCOPE, redirect_uri=REDIRECT_URI)
authorization_url, state = spotify.authorization_url(AUTH_URL)
return redirect(authorization_url)
#app.route("/callback", methods=['GET'])
def callback():
code = request.args.get('code')
res = requests.post(TOKEN_URL,
auth=HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET),
data={
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI
})
return json.dumps(res.json())
if __name__ == '__main__':
app.run(port=3000,debug=True)
Steps
#1 Run Application
python spotify-client.py
#2 Open Browser and access this URL
http://localhost:3000/login
#3 Login with your Spotify credential
This login screen automatically shows to you.
#4 The access-token will shows on your browser if success login.

Related

400 error on POST request for Spotify token (Python)

Using the documentation for authorisation, There are 2 steps in getting a Spotify OAuth Token
App requests authorization and receives a authorization code.
App posts a request to receive a OAuth Token.
https://developer.spotify.com/documentation/general/guides/authorization-guide/
When I try to POST a request to receive an Oath Token I get a 400 error. The code is a a bit dirty, sorry about that.
import json
import requests
from urllib.parse import urlencode
#credentials
USER_ID = '31......fbq'
CLIENT_ID = '553b......9dd'
CLIENT_SECRET = '16c40......24067b'
# encodes and prints URL
auth_url = 'https://accounts.spotify.com/authorize'
scopes_params = urlencode({
'client_id': CLIENT_ID,
'scope': 'playlist-modify-private',
'redirect_uri': 'http://localhost:8000',
'response_type': 'code'
})
scope_url = auth_url + '?' + scopes_params
print(scope_url)
response = requests.get(scope_url)
# Authorization code is copy pasted here
authorization_code = input('Enter Authorization_Code: ')
request_body_token = json.dumps({
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': authorization_code,
'redirect_uri': 'http://localhost:8000'
})
access_token_request = requests.post(url='https://accounts.spotify.com/api/token',
data=request_body_token)
print(access_token_request.status_code)
This is the section of the authorization code I copy paste in from the redirect URI
Let me know if any additional information is needed.
I found out the issue. The request_body_token doesn't need to be converted from JSON to Python using json.dumps method, the dictionary can already be parsed in the data/body. Solution Below:
import json
import requests
from urllib.parse import urlencode
#credentials
USER_ID = '31ldam........w3wwfbq'
CLIENT_ID = '553bc4.........c0b3f09dd'
CLIENT_SECRET = '16c400........a24067b'
ENPOINT = f'https://api.spotify.com/v1/users/{USER_ID}/playlists'
# encodes and prints URL
auth_url = 'https://accounts.spotify.com/authorize'
scopes_params = urlencode({
'client_id': CLIENT_ID,
'scope': 'playlist-modify-private',
'redirect_uri': 'http://localhost:8000',
'response_type': 'code'
})
scope_url = auth_url + '?' + scopes_params
print(scope_url)
# Authorization code is copy pasted here
response = requests.get(scope_url)
authorization_code = input('Enter Authorization_Code: ')
# Here is where the error was, json.dump removed
request_body_token = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': authorization_code,
'redirect_uri': 'http://localhost:8000'
}
access_token_request = requests.post(url='https://accounts.spotify.com/api/token', data=request_body_token)
print(access_token_request.status_code)
access_token = access_token_request.json()['access_token']

Why I am receiving 405 error for request?

I am trying to send a post request using python3.6 to oauth2 server to get my access token, it is showing response 405. Can someone tell me what I am doing wrong here
import requests
client_id = 'client_id'
client_secret = 'my client secret'
r = request.post('serverurl/oauth2/token&Content-Type="application/x-www-form-urlencoded"',data = {'grant_type':'authorization_code',
'code':'91a8a5e4-c5b3-4e2a-91ca-d59fe139526c',
'client_id':client_id,
'client_secret':client_secret,
'redirect_uri':'actualredirecturl'
}
I solved it using the following code
here is the code
import requests,base64
client_id = "myclientid"
client_secret = "myclientsecret"
redirect_uri = 'my redirect url'
code = 'code return by server on login'
requestHeaders = {
'Authorization': 'Basic ' + base64.b64encode(client_id + ':' + client_secret),
'Content-Type': 'application/x-www-form-urlencoded'
}
requestBody = {
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': redirect_uri
}
response = requests.post('token_url', data=requestBody, headers=requestHeaders)
token = response.json()['access_token']
Hope that helps

How to add http headers along with data to send a POST request to an API endpoint using Oauth2Session (requests_oauthlib)?

I have a python code like this to interact with an API
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
import json
from pprint import pprint
key = "[SOME_KEY]" # FROM API PROVIDER
secret = "[SOME_SECRET]" # FROM API PROVIDER
api_client = BackendApplicationClient(client_id=key)
oauth = OAuth2Session(client=api_client)
url = "[SOME_URL_FOR_AN_API_ENDPOINT]"
# GETTING TOKEN AFTER PROVIDING KEY AND SECRET
token = oauth.fetch_token(token_url="[SOME_OAUTH_TOKEN_URL]", client_id=key, client_secret=secret)
# GENERATING AN OAuth2Session OBJECT; WITH THE TOKEN:
client = OAuth2Session(key, token=token)
body = {
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
response = client.post(url, data=json.dumps(body))
pprint(response.json())
When I run this py file, I get this response from the API, that I have to include the content type in the header. How do I include the header with Oauth2Session?
{'detailedMessage': 'Your request was missing the Content-Type header. Please '
'add this HTTP header and try your request again.',
'errorId': '0a8868ec-d9c0-42cb-9570-59059e5b39a9',
'simpleMessage': 'Your field could not be created at this time.',
'statusCode': 400,
'statusName': 'Bad Request'}
Have you tried to you send a header paramter with this requests?
headers = {"Content-Type": "application/json"}
response = client.post(url, data=json.dumps(body), headers=headers)
This is how I was able to configure the POST request for exchanging the code for a token.
from requests_oauthlib import OAuth2Session
from oauthlib.oauth2 import WebApplicationClient, BackendApplicationClient
from requests.auth import HTTPBasicAuth
client_id = CLIENT_ID
client_secret = CLIENT_SECRET
authorization_base_url = AUTHORIZE_URI
token_url = TOKEN_URI
redirect_uri = REDIRECT_URI
auth = HTTPBasicAuth(client_id, client_secret)
scope = SCOPE
header = {
'User-Agent': 'myapplication/0.0.1',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
}
# Create the Authorization URI
# Not included here but store the state in a safe place for later
the_first_session = OAuth2Session(client_id=client_id, redirect_uri=redirect_uri, scope=scope)
authorization_url, state = the_first_session.authorization_url(authorization_base_url)
# Browse to the Authorization URI
# Login and Auth with the OAuth provider
# Now to respond to the callback
the_second_session = OAuth2Session(client_id, state=state)
body = 'grant_type=authorization_code&code=%s&redirect_uri=%s&scope=%s' % (request.GET.get('code'), redirect_uri, scope)
token = the_second_session.fetch_token(token_url, code=request.GET.get('code'), auth=auth, header=header, body=body)

Facebook API: generate user access_token with permissions

Question in short: how to get Facebook API access_token with permission
I want to read the reach for specific ad settings from the Facebook API using Python. In order to do so, I need a facebook access token with extended permissions. I use the following function to get a new access token, but the token I get does not have the proper permission levels. So: how to get an access_token with custom permissions, like you can do manually here?
Python example below (problem is actually language independent):
import requests
import json
from facebookads.adobjects.adaccount import AdAccount
from facebookads.api import FacebookAdsApi
from facebookads.adobjects.adset import AdSet
app_id = 'xxxx'
app_secret = 'xxxx'
account_id = 'xxxx'
def get_fb_token(app_id, app_secret):
payload = {'grant_type': 'client_credentials',
'client_id': app_id,
'client_secret': app_secret,
}
file = requests.post('https://graph.facebook.com/oauth/access_token?', params = payload)
string = file.content.decode('utf-8')
json_obj = json.loads(string)
return json_obj['access_token']
access_token = get_fb_token(app_id, app_secret)
account = AdAccount(account_id)
# initiate API
FacebookAdsApi.init(app_id, app_secret, access_token)
# Request reach
targeting_spec = {
'geo_locations': {
'countries': ['nl']
},
}
fb_params = {
'currency': 'EUR',
'optimize_for': AdSet.OptimizationGoal.offsite_conversions,
'targeting_spec': targeting_spec,
}
reach_estimate = account.get_reach_estimate(params=fb_params)
And the error message I get:
(#278) Reading advertisements requires an access token with the extended permission ads_read
Help is highly appreciated!
Try this:
payload = {
'grant_type': 'client_credentials',
'client_id': app_id,
'client_secret': app_secret,
'scope': 'ads_read'
}
file = requests.post('https://graph.facebook.com/oauth/access_token?', params = payload)
Also, you need to redirect to the correct endpoint (https://www.facebook.com/v2.xy/dialog/oauth), not POST to it. You cannot get a User token without user interaction.

LinkedIn API in Python: How to get code while running it on command line

I am writing a command line script accessing LinkedIN API via Library but having issues with it. Here is my code:
from linkedin import linkedin
import requests
RETURN_URL = "http://localhost"
authentication = linkedin.LinkedInAuthentication(CLIENT_ID, CLIENT_SECRET, RETURN_URL,
linkedin.PERMISSIONS.enums.values())
print(authentication.authorization_url)
get_code = authentication.authorization_url
application = linkedin.LinkedInApplication(authentication)
authentication.authorization_code = 'AQQfHou58eyVEJmbabHk1njdl-AY0bqfDjkZeosAn6DR-DiTnH7raJoDcign2U3w5w1YieYU4cjfTz3Ab-wa7cm3KwwctjzU-SoAWchjj_odArFM7q1W1CCU_15Q7gLDRrZoMCo5ivXnkisR5gYfGS0V2E_jsQ&state=74abc361c20313f5bc87d43f42f88b53#!'
# authentication.get_access_token()
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'redirect_uri': RETURN_URL,
'code': 'AQTqmP0g4PWGJpNnSysqvH4TCXTusoWsjbx1f3R7TPazYP4pCB81a4FrRJRUNjeJzH5yoN2XTrIT4YO-mu2VBQkhL12kwJZ09Xm_WHh97nyok0tqKHh8k54c3dCc075hrsJ8KYw02X-2XSMD-TkxQWKrUXPsMw&state=82d8d2bbbc80ba485812d2fe500cf3e9#!'
}
url = 'https://www.linkedin.com/uas/oauth2/accessToken'
r = requests.post(url, data=data)
print(r.text)
The error I get:
https://www.linkedin.com/uas/oauth2/authorization?client_id=862ztaa9740mst&redirect_uri=http%3A//localhost&scope=rw_company_admin%20r_emailaddress%20r_basicprofile%20w_share&response_type=code&state=d8e7aaefdbd32211fb7d342b238a84dc
{"error_description":"missing required parameters, includes an invalid parameter value, parameter more than once. : Unable to retrieve access token : appId or redirect uri does not match authorization code or authorization code expired","error":"invalid_request"}
Also, how to get code part dynamically?

Categories

Resources