I'm making a project which will add songs from your youtube playlist to spotify playlist. everything works fine except the add_item() method. I'm getting 404 : not found response from the requests object.
Yes, i checked if the song actually exists. It does and even printed the id of the song.So it exists.
I'm following the official documentation
here is my code -
import json
from requests_oauthlib import OAuth2Session
import requests
import base64
import urllib.parse as urlparse
from urllib.parse import parse_qs
client_id = #id
client_secret = #secret
redirect_uri = 'https://www.spotify.com'
scope = "playlist-modify-public user-read-email user-read-private playlist-modify-private"
req = f'{client_id}:{client_secret}'
encoded = base64.b64encode(req.encode())
class sp :
def __init__(self) :
self.get_token()
self.get_id()
self.uri_list = []
def get_token(self) :
url = 'https://accounts.spotify.com/authorize'
oauth = OAuth2Session(client_id, redirect_uri = redirect_uri, scope = scope)
authorization_url, state = oauth.authorization_url(url)
print(authorization_url)
authorization_response = input('paste here : ')
parsed = urlparse.urlparse(authorization_response)
authorization_code = parse_qs(parsed.query)['code'][0]
# to get auth token
headers = {
'Authorization' : f'Basic {encoded.decode()}'
}
data = {
'grant_type' : 'authorization_code',
'redirect_uri' : redirect_uri,
'code' : authorization_code
}
access = requests.post('https://accounts.spotify.com/api/token', data = data, headers = headers)
response = json.loads(access.text)
self.access_token = response['access_token']
def get_id(self) :
headers = {
'Authorization' : f'Bearer {self.access_token}'
}
user_info = requests.get('https://api.spotify.com/v1/me', headers = headers)
user_info.raise_for_status()
user_info = json.loads(user_info.text)
self.user_id = user_info['id']
def search(self) :
search_url = 'https://api.spotify.com/v1/search'
headers = {
'Authorization': f'Bearer {self.access_token}'
}
params = {
'q' : 'track:Memories artist:Maroon 5',
'type' : 'track',
'limit' : 1,
}
search_response = requests.get(search_url, headers = headers, params = params)
search_response.raise_for_status()
json_response = search_response.json()
song_uri = json_response['tracks']['items'][0]['uri']
self.uri_list.append(song_uri)
def create_playlist(self) :
create_playlist_url = f'https://api.spotify.com/v1/users/{self.user_id}/playlists'
headers = {
'Authorization' : f'Bearer {self.access_token}',
'Content-Type' : 'application/json'
}
data = json.dumps({
'name' : 'new playlist'
})
response = requests.post(create_playlist_url, headers = headers, data = data)
print(response)
self.playlist_id = response.json()['uri']
def add_items(self) :
add_items_url = f'https://api.spotify.com/v1/playlists/{self.playlist_id}/tracks'
headers = {
'Authorization' : f'Bearer {self.access_token}',
'Content-Type' : 'application/json'
}
print(self.uri_list)
data = {
'uris' : json.dumps(self.uri_list)
}
res = requests.post(add_items_url, headers = headers, data = data)
print(res)
user = sp()
user.create_playlist()
user.search()
user.add_items()
Any help is appreciated. Thanks
You have this line of code for playlist creation:
self.playlist_id = response.json()['uri']
and then in items addition logic you have:
add_items_url = f'https://api.spotify.com/v1/playlists/{self.playlist_id}/tracks'
are you sure that you want to use playlist uri as playlist id?
Could you update your question with more info:
response.json() value after playlist is created
print add_items_url after f-string was declared
UPDATE
https://developer.spotify.com/documentation/web-api/reference/playlists/create-playlist/ as I can see here - the response after creation of the playlist include id field
So you should just change this line
self.playlist_id = response.json()['uri']
to
self.playlist_id = response.json()['id']
Related
I'm writing code to access the MS365 API and the Python code example uses urllib. I want to instead use requests but I'm not sure how urllib translates into requests as my attempts of doing so have failed.
The code example can be found here:
https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/run-advanced-query-sample-python?view=o365-worldwide#get-token
import json
import urllib.request
import urllib.parse
tenantId = '00000000-0000-0000-0000-000000000000' # Paste your own tenant ID here
appId = '11111111-1111-1111-1111-111111111111' # Paste your own app ID here
appSecret = '22222222-2222-2222-2222-222222222222' # Paste your own app secret here
url = "https://login.microsoftonline.com/%s/oauth2/token" % (tenantId)
resourceAppIdUri = 'https://api.securitycenter.microsoft.com'
body = {
'resource' : resourceAppIdUri,
'client_id' : appId,
'client_secret' : appSecret,
'grant_type' : 'client_credentials'
}
data = urllib.parse.urlencode(body).encode("utf-8")
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req)
jsonResponse = json.loads(response.read())
aadToken = jsonResponse["access_token"]
IIUC, this should work the same:
import requests
tenantId = '00000000-0000-0000-0000-000000000000' # Paste your own tenant ID here
appId = '11111111-1111-1111-1111-111111111111' # Paste your own app ID here
appSecret = '22222222-2222-2222-2222-222222222222' # Paste your own app secret here
url = "https://login.microsoftonline.com/%s/oauth2/token" % (tenantId)
resourceAppIdUri = 'https://api.securitycenter.microsoft.com'
params = {
'resource' : resourceAppIdUri,
'client_id' : appId,
'client_secret' : appSecret,
'grant_type' : 'client_credentials'
}
response = requests.get(url, params)
jsonResponse = response.json()
aadToken = jsonResponse["access_token"]
Modifying #BeRT2me's answer has made this work.
import requests
tenantId = '00000000-0000-0000-0000-000000000000' # Paste your own tenant ID here
appId = '11111111-1111-1111-1111-111111111111' # Paste your own app ID here
appSecret = '22222222-2222-2222-2222-222222222222' # Paste your own app secret here
url = "https://login.microsoftonline.com/%s/oauth2/token" % (tenantId)
resourceAppIdUri = 'https://api.securitycenter.microsoft.com'
data = {
'resource' : resourceAppIdUri,
'client_id' : appId,
'client_secret' : appSecret,
'grant_type' : 'client_credentials'
}
response = requests.post(url=url, data=data)
jsonResponse = response.json()
aadToken = jsonResponse["access_token"]
I am sending the post request to the TAP PAYMENT GATEWAY in order to save the card, the url is expecting two parameters like one is the source (the recently generated token) and inside the url the {customer_id}, I am trying the string concatenation, but it is showing the error like Invalid JSON request.
views.py:
ifCustomerExits = CustomerIds.objects.filter(email=email)
totalData = ifCustomerExits.count()
if totalData > 1:
for data in ifCustomerExits:
customerId = data.customer_id
print("CUSTOMER_ID CREATED ONE:", customerId)
tokenId = request.session.get('generatedTokenId')
payload = {
"source": tokenId
}
headers = {
'authorization': "Bearer sk_test_**********************",
'content-type': "application/json"
}
# HERE DOWN IS THE url of TAP COMPANY'S API:
url = "https://api.tap.company/v2/card/%7B"+customerId+"%7D"
response = requests.request("POST", url, data=payload, headers=headers)
json_data3 = json.loads(response.text)
card_id = json_data3["id"]
return sponsorParticularPerson(request, sponsorProjectId)
Their expected url = https://api.tap.company/v2/card/{customer_id}
Their documentation link: https://tappayments.api-docs.io/2.0/cards/create-a-card
Try this..
First convert dict. into JSON and send post request with request.post:
import json
...
customerId = str(data.customer_id)
print("CUSTOMER_ID CREATED ONE:", customerId)
tokenId = request.session.get('generatedTokenId')
payload = {
'source': tokenId
}
headers = {
'authorization': "Bearer sk_test_**************************",
'content-type': "application/json"
}
pd = json.dumps(payload)
# HERE DOWN IS THE url of TAP COMPANY'S API:
url = "https://api.tap.company/v2/card/%7B"+customerId+"%7D"
response = requests.post(url, data=pd, headers=headers)
json_data3 = json.loads(response.text)
card_id = json_data3["id"]
return sponsorParticularPerson(request, card_id)
Please tell me this works or not...
In order to extract data from a private API, I need to generate access tokens using my auth key and credentials. My current code is split in two parts. The first generates the access token:
import requests
url = "https://api.abcdef.com/AuthorizationServer/Token"
payload = "{\r\n \"grant_type\" : \"password\",\r\n \"username\" : \"user#aldfh.com\",\r\n \"password\" : \"kajshdgfkuyb\",\r\n \"scope\" : \"API\"\r\n}"
headers = {
'Content-Type': 'application/json',
'Authorization': 'Basic VGFibGVhdV9DaW94QFRhYmxlYXVfQ2lveDo0Ix '
}
response = requests.request("POST", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
The response looks like this:
{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpY0JVSWQiOjQ1OTg0MjEsIm5hbWUiOiJyYW15YS5nb3RldHlAY2lveGhlYWx0aC5jb20iLCJpc3MiOiJodHRwczovL2FwaS5pbmNvbnRhY3QuY29tIiwic3ViIjoidXNlcjoxNTMyMDI2MiIsImF1ZCI6IlRhYmxlYXVfQ2lveEBUYWJsZWF1X0Npb3giLCJleHAiOjE1Nzk2Mjg1NzcsImlhdCI6MTU3OTYyNDk3OCwiaWNTY29wZSI6IjgiLCJpY0NsdXN0ZXJJZCI6IkMzMSIsImljQWdlbnRJZCI6MTUzMjAyNjIsImljU1BJZCI6MTQ5NiwibmJmIjoxNTc5NjI0OTc4fQ.rEZiMHPsE1inwuWFME1oV_oD54TqkU00-uml3NjCkClW3R-_bVC7A3PxI4zGlJms1rvsZkgO3XX8-1coeV6_jtI-l3nCHixVk2nboepqAspoxT3o9w4vhBhZzvs-TAsqyk4fCrSwwHFXwn8xOMdfrqZqknXHLlVtKlGJg_Uy3bmwEiioocMN3BRZE_269_v5Ez4b94_juUHLPDWye7kS5-8cs4Izsk7HePn-Sm_-FLEqEeb2C09NUGWU8SdyA3EtQhMAiHkU-wN8uQ8wKcWoUfO7WtrSO4zbicFZHgA9Cw",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"pDYllH2UsVIYq3Pn3Dg==",
"scope":"Api",
"resource_server_base_uri":"https://api-c31.it.com/itAPI/",
"refresh_token_server_uri":"https://api-c31.it.com/AuthorizationServer/Token",
"agent_id":162,
"team_id":24355,
"bus_no":4421}'
The access token is part of the output and I paste this into the following code to generate the response:
def getPerformance():
# api-endpoint
#Give the specified url ,accessToken
BASEURL = 'https://api-c31.ict.com/tAPI/'
accessToken = "{eyJ0eXAiOiJKV1QiLCJhbGciSUzI1NiJ9.eyJpY0JVSWQiOjQ1OTgyYW15YS5nb3RldHlAY2lveGhlYWx0aC5jb20iLCJpc3MiOiJodHRwczovL2FwaS5pbmNvbnRhY3QuY29tIiwic3ViIjoidXNlcjoxNTMyMDI2MiIsImF1ZCI6IlRhYmxlYXVfQ2lveEBUYWJsZWF1X0Npb3giLCJleHAiOjE1Nzk1NjA0MjYsImlhdCI6MTU3OTU1NjgyNywiaWNTY29wZSI6IjgiLCJpY0NsdXN0ZXJJZCI6IkMzMSIsImljQWdlbnRJZCI6MTUzMjAyNjIsImljU1BJZCI6MTQ5NiwibmJmIjoxNTc5NTU2ODI2fQ.JIzsPLK8kg8Zqq_uITeNp6b24xuglcmtjVbD9Ll-ooq943gIILvr_SQ8cTKNl50YMyiX_mu48pupf-D0b-Ntbmb7hYOTNY7tjp8skM8uBDmuSzG1GnVQh3ZotdlofhiEDU9_U4sQsovqdDtXyi5inaoJ95TeBS_YQp_3LSv3pjfXQNWdt1bcn7arHWdIdl6qD5qXm0DhXQArhTr35mViZn-ZxITW4nvEi-gwZz6DdLWuWcW5kTbbzvucroVUPM-dZvzNJvMEruJvriUGl3Y2DSlB5qTLo3JqbLwujsoZfhaxfJ1eAFKd13t6mMenQ5TOwVV3Rg_yp7DfeBbnWcmwtA}"
#Check if accessToken is empty or null
if accessToken != "":
#Give necessary parameters for http request
payload={'startDate':'1/1/2020',
'endDate':'1/6/2020',
'fields':'"teamId","calls"'}
#add all necessary headers
header_param = {'Authorization': 'bearer ' + '{accessToken}','content-Type': 'application/x-www-form-urlencoded','Accept': 'application/json, text/javascript, */*'}
# Make get http request
answer = requests.get(BASEURL + 'services/{version}/g/h' , headers = header_param, params=payload)
#print response appropriately
print (answer)
else: print('error')
My issue is that I need to be able to merge both scripts in order to be able to automate the process.
Try adding the following changes to the first part of your code, then with the access token at the bottom, pass it into the getPerformance() function:
#Added json import here
import json
import requests
url = "https://api.abcdef.com/AuthorizationServer/Token"
payload = "{\r\n \"grant_type\" : \"password\",\r\n \"username\" : \"user#aldfh.com\",\r\n \"password\" : \"kajshdgfkuyb\",\r\n \"scope\" : \"API\"\r\n}"
headers = {
'Content-Type': 'application/json',
'Authorization': 'Basic VGFibGVhdV9DaW94QFRhYmxlYXVfQ2lveDo0Ix '
}
response = requests.request("POST", url, headers=headers, data = payload)
#Note the changes here
json = response.read()
data = json.loads(json)
accessToken = data['access_token']
Then wherever you call the getPerformanceFunction(), you want to change it to getPerformance(accessToken). You'll need to change the function definition to this too.
Based on #Cutter's response above, making the following changes worked for me:
import requests
import json
url = "https://api.abcdef.com/AuthorizationServer/Token"
payload = "{\r\n \"grant_type\" : \"password\",\r\n \"username\" : \"user#aldfh.com\",\r\n \"password\" : \"kajshdgfkuyb\",\r\n \"scope\" : \"API\"\r\n}"
headers = {
'Content-Type': 'application/json',
'Authorization': 'Basic VGFibGVhdV9DaW94QFRhYmxlYXVfQ2lveDo0Ix '
}
response = requests.request("POST", url, headers=headers, data = payload)
testresp = response.text
data = json.loads(testresp)
#Change function definition to :
def getPerformance(data):
# api-endpoint
#Give the specified url ,accessToken
# =============================================================================
BASEURL = 'https://api-c31.ict.com/API/'
accessToken = (data["access_token"])
I am trying to retrieve events from the Outlook Calendar using the API. I only want to retrieve events after today. I'm using the following code (which is basically a cut and paste from Microsoft's tutorial):
def make_api_call(method, url, token, user_email, payload = None, parameters = None):
# Send these headers with all API calls
headers = { 'User-Agent' : 'python_tutorial/1.0',
'Authorization' : 'Bearer {0}'.format(token),
'Accept' : 'application/json',
'X-AnchorMailbox' : user_email }
# Use these headers to instrument calls. Makes it easier
# to correlate requests and responses in case of problems
# and is a recommended best practice.
request_id = str(uuid.uuid4())
instrumentation = { 'client-request-id' : request_id,
'return-client-request-id' : 'true' }
headers.update(instrumentation)
response = None
if (method.upper() == 'GET'):
response = requests.get(url, headers = headers, params = parameters)
print response.url
elif (method.upper() == 'DELETE'):
response = requests.delete(url, headers = headers, params = parameters)
elif (method.upper() == 'PATCH'):
headers.update({ 'Content-Type' : 'application/json' })
response = requests.patch(url, headers = headers, data = json.dumps(payload), params = parameters)
elif (method.upper() == 'POST'):
headers.update({ 'Content-Type' : 'application/json' })
response = requests.post(url, headers = headers, data = json.dumps(payload), params = parameters)
return response
This function gets called from the following:
get_events_url = outlook_api_endpoint.format('/Me/Events')
query_parameters = {'$select': 'Subject,Start,End',
'$orderby': 'Start/DateTime ASC',
'startDateTime' : datetime.datetime.now().isoformat(),}
r = make_api_call('GET', get_events_url, access_token, user_email, parameters = query_parameters)
It simply returns the first 10 entries in the calendar rather than entries from today onwards. How do I get back entries for specific dates?
I've found a solution that works for me. First I've changed events to calendarview, I've capitalised StartDateTime and added EndDateTime so it looks like this:
get_events_url = outlook_api_endpoint.format('/Me/calendarview')
query_parameters = {'$select': 'Subject,Start,End',
'$orderby': 'Start/DateTime ASC',
'StartDateTime' : datetime.datetime.now().isoformat(),
'EndDateTime' : datetime.datetime(2100,12,31),}
r = make_api_call('GET', get_events_url, access_token, user_email, parameters = query_parameters)
It works so I'm happy
I want to get refresh token from Dailymotion API by this code
def get_refresh_token(code):
platform = Platform.objects.get(name='Dailymotion')
secret_key = platform.secret_key
api_key = platform.api_key
redirect_uri = platform.callback_url
params = {
'code' : code,
'client_id' : api_key,
'client_secret' : secret_key,
'grant_type':'authorization_code',
'redirect_uri':redirect_uri
}
r = requests.post('https://api.dailymotion.com/oauth/token',data=params)
print (r.json())
print(code)
print(r.data)
refresh_token = r.json().get('refresh_token')
return refresh_token
but it's not working. the error is : {'error_description': 'Invalid authorization code.', 'error': 'invalid_grant'}
.I tried with the same code,grant_type... post from Chrome extensions and it works. What did i do wrong with python code?
def get_refresh_token(self, code):
args = {
'grant_type': 'refresh_token',
'refresh_token': code,
'client_id': DAILYMOTION_API_KEY,
'client_secret': DAILYMOTION_API_SECRET,
}
url = 'https://api.dailymotion.com/oauth/token'
data = urllib.urlencode(args)
request = urllib2.Request(url, data)
response = urllib2.urlopen(request)
html = response.read()
obj_Response = literal_eval(html)
return obj_Response
while getting AccessToken we get a parameter 'code' here we have to put that value in place of code.