Automate Spotify with Python (Spotify API)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I've had a bit of a problem for the past few weeks I've started listening to my Spotify discover weekly and totally forgotten about it and then it's disappeared potentially missing out on some lovely bloody bangers so I decided to fix this using code we're gonna be doing this in Python and obviously we're just going to be using the Spotify Web API the problem with this is this can be quite confused and if you have never done much work with api's before but I assure you this is not difficult the documentation for the API is actually very well written and I will talk you through it now what I would suggest is creating two Python files one called secrets py and another called main dot py main is obviously where we're gonna have the main code secrets is where we will put our authentication details which we will get now so the first thing we need to do is get authorized this link will be the first link in the description and it walks you through getting authorized can either read through this whole thing yourself or I will just walk you through it here basically there are three different ways that we can be authorized the way that I would recommend getting authorization is by following the authorization code flow however this is a fairly complicated process which I will explain however if you just want temporary access and you want to rush through this as quickly as possible when you can just do this go to this link in the description which is the create a playlist request page and this actually gives you an OAuth token for doing exactly lat or you'll want to do is press get token it shows you the required scopes for the send point that means the required permissions that this key will have to give you you so you just check these two and click request token you press ctrl a ctrl + C to copy and then we can just put this in our secrets dot py file make a new variable called Spotify underscore token equals and then put in this token it is very long okay so that is the easy way to do it and this token will expire very quickly and you will need to do that every time that it expires you can't really automate the process so if you want to follow these slightly more complicated but I would say better approach of getting an authorization code then follow this right now so here is the authorization code flow a lot of reading blah blah blah blah blah a big we have a diagram explaining the flow but I'm sorry who has got time for that so basically the first thing we want to do is actually create an app so to obtain authorization register your application click on that and then it says to register your app go to your dashboard and click create a client ID lovely now it might ask you to log into your account your Spotify account so just do so and then you will probably have no apps here and it will say create app um now I don't know why it says that because in the description here it says click create client ID so that's what we will do don't click create app click create a client ID and then we follow this form here so Apple hardware name anything you want to do I'm just gonna call it Spotify tutorial ok app description now this app is going to save the discover weekly every week okay so I'll just take that saved discover weekly every week what are we building we're building a desktop app and click Next are we developing a commercial integration no we are not selling this or monetizing it or now we're just making this far our own purposes we're gonna click non-commercial and we understand it's not for commercial use we understand we can't migrate it we understand and agree with the developer Terms of Service oh of course we do lovely so that's created the app and we now have a client ID and a client secret what I'm going to do now is click Edit settings here redirect URIs you can really put in any URI of your choice ok what will happen is we will prompt the user to authorize our app with their account and I'm pretty sure that the only user is just gonna be us where you making this app for ourselves we're not put out there so we will just do this once and then once they've clicked yes it redirects into a URI and it puts an authorization code in actual URI itself as a parameter that sounds complicated don't worry just all you got to do is put any URI of your choice in here it can really be anyone so just click Add by the way this doesn't even have to be a valid URI you can just put in you know a made-up one that doesn't exist now this thumb might seem really confusing but you'll see why once we get there okay now we're done here our app has been created and we have our client ID in our client secret okay so I'm just gonna copy and paste those straight into the secret store py file for now just so we know where everything is okay so now we move on so we scroll down here and for the authorization code flow step one is have your application request authorization the user logs in and authorizes access again we're the only user so we're not going to actually put this in the application we're just gonna do this manually in the browser so we're gonna send the get request to this URL and we are going to pass in the following query parameters client ID well we've registered our application so we can just pass in this client ID yeah okay so the second query parameter is response underscore type and this is required and set to code that is exactly what it sounds like we have second parameter using the ampersand called a response underscore type equals code lovely okay redirect URI we already talked about this as you can see it says it must match exactly one of the values you entered when you registered your application well I can just go to my actual application and simply copy URL I entered however it isn't that easy because if we scroll down here and take a look at the example you can see it's actually URL encoded if we just search for URL encoder and we will just go to this link here enter the URL click in code and there we go it is now URL encoded and we can paste this in so redirect and this you are I there we go equals lovely finally we will specify scope so if you remember in the basic o'the walkthrough at the beginning of the video we need two scopes so what we do is type and scope playlist - modify - public now this is a space separated list but what we will do instead of just a space is do percentage design 20 okay so playlist - modify - public percentage 20 playlist - modify - private and there we go that is the formatted get request so when we enter in this get request it should ask us for permissions and then once we click accept they will redirect us to the redirect URI we've specified and in the URL will have a code parameter but I'm not gonna do that quite yet because that code I believe is only valid for a certain period of time so we'll just get this ready first step - and basically in step 2 we take the access token we've generated now the access token basically says my Spotify account and this application are allowed to work together so that isn't an API token or which we need to put in the code so we have to use that access token which we will get from this get request and we will use that to exchange it with an access token by making a post request to this endpoint okay now if that sounds complicated again don't worry cuz it's actually very very simple and you can see all the parameters and such that we need and they actually provide a curl command so we will just copy that and put it over here okay now you might be wondering what the bloody hell is Curl Curl is a command-line tool for transferring data using various network protocols lovely ok so that basically means that we can make it such as this and get a response back now to check whether you have curl you will just open up the command prompt you can do that by pressing Windows key on our CMD and just type the curl now if you type curl and you get a response like this that means curl is already installed if not then you will have to install it I won't go through that here because it is actually possible that you already have kill'd installed if you're on Windows and you have get four windows installed I believe it you will already have it installed or if you have Windows 10 version I believe 1803 and above it actually already comes with curl pre-installed if you don't already have it installed then go and look up how to install it and then come back and we'll be fine so we have this sample curl command now what does this entail so let me walk you through this curl commands with so we're invoking curl obviously - H this means head at what are we sending in the request header well we send authorization as a basic authorization and then we have this what is this this is just the sample that Spotify is provided so just ignore that but what that actually should be is base64 encoded string that contains the client ID and secret ID it must have the following format okay what the hell does this mean well we have the client ID and C client secret right here so what you need to do is take your client ID put a colon and then take your client secret and put it right after the code on no spaces or anything so we have client ID colon client secret then copy all that again being careful not to add any extra whitespace at the beginning or the end and we need to base64 encode it so just search base64 encode ur and first site that comes up right here the first time I did this I was accidentally on the decode option you make sure that you're on in code paste in your client ID and secret in the format that we just went through and click encode and there we go we get this in response lovely so that is going to replace this sample thing Spotify has given us and press paste lovely okay next - D grant type equals authorization underscore code well as you can see here that is exactly how we need it so we're not going to change that - D code well this is what we're going to get by running this get request up here which we will do in a second and finally - the redirect URI equals but our redirect URI and if you remember correctly the redirect URI is right here and we're gonna copy it exactly as it is okay just like so and then it has a space and then the endpoint so the only thing we're missing is this code and we get that by running this get request we formatted earlier so how are we gonna do that we're not actually going to do it programmatically we're just gonna paste this in the browser and just press ENTER and it will take us to this following page it may or may not ask you to login but it will walk you through it's got our app title and it tells us the things that we have requested to do so take actions on Spotify on your behalf we have said that we can create edit follow private playlists and create edit and follow public playlists click agree and there we go it is redirected us so whatever URL you put to redirect to is going to pass it so as you can see here we have a parameter called code which gives us this long access code so we have to be quick because this is a time-based access code but as I said this URL doesn't actually have to be valid because we're not actually doing anything with this parameter on the website so we now have our access code and we can go back to our curl and we can fill in the final parameter so let me just walk you through one more time what we have we invoke curl and we pass it the header authorization basic then our client ID client secret comma separated as base64 okay then we we start the body parameters the first one is grant authorization code just default as it was then we have another one called code and that is that long authorization code which we just generated via that get request then we have our redirect URI which is the same as the one we used in the get request then we pass all this to the endpoint okay so now we can just copy this entire command and paste it into the command line assuming you've already installed curl now as you can see I actually receive an error here initialization security contacts failed bla bla bla bla bla bla bla so I found the answer to this as always on Stack Overflow somebody says curl needs a parameter to tell it not to check certificate revocation we can be confident with doing that because this is the exact command that Spotify gave us we don't really need to worry so we just add in this - SSL - no revoke argument and run it and there we go we get this response so what the hell is this response so we need to take note of this access code parameter also as you can see this expires in 3 600 which means in one hour you will also want to take note of this refresh token here because that is what we'll use later when we are trying to regain access I'll walk you through setting up automatic refreshing of this token at the end but for now let's just get the rest of the at work and we now have our access token and we can access the API so we will copy that and now clear all this from our secrets py and now what I'm going to do is create a variable in here and just call it Spotify and it's got token equals and paste this you'll also need a variable called spot fight and the score user and score ID so you can get that just by opening the Spotify app and you can actually just copy it right here you can also see this if you click account it is right here your just your regular Spotify username paste that in as your Spotify user ID variable and we are now done in the secrets file until we want to automate it but as I say we'll worry about that later so now let's go to main top py now let's let's think about what do we actually want it to do well the first thing we want to do is actually find the songs and we want to find the songs by finding our discover weekly playlist we want to get a playlists tracks or items and actually here we are there is a page in Spotify API which tells us exactly how to do that how do we do it well we send a get request to this endpoint so the packages we will need for now are Jason and requests we will also import from secrets our Spotify user ID and Spotify token ok and I'm gonna do this in a class I'm just going to call it save songs we're going to define our init function like so and I know how annoying it is when you're watching the tutorial and they just walk through it really fast but this is all just sort of setup stuff so just caught you can copy this exactly and you can really see what it's doing so we're important the packages we need we're important our ID and our token so we are then going to set these as variables so self that user ID equals Spotify user ID self dot Spotify token equals Spotify and let's go token so we're going to define our first function and we said the first thing we want to do is actually find the songs so define a function called find songs right so what we want to do well we want to loop through playlist tracks and add them to a list that seems like a reasonable thing to do so if we take a look at the API send a request to this query is going to look like this for now now we can delete where it says playlist ID in these curly brackets and then use dot format to pass in the playlist ID and we can grab that by just going on Spotify clicking made for you and we want to grab the discover weekly players because that is the one we are going to save so what we're gonna do is not copy the link copy the Spotfire you are i and then if we just paste this here you see that we get Spotify : playlist : and then this identifier so what we can do is just copy that and you know it's probably good practice if we put this in the secrets file so what I just gonna go playlists and it's got ID so this is the ID of our discover weekly playlist so then we will need to import that from secrets and to avoid confusion we should probably call it this gather weekly ID because we are also going to have a place of idea of a playlist that we create self dot discover weekly ID equals discover weekly ID there we go okay so now we have our user ID our token and the idea about discover weekly playlist so I'm just gonna format this like so okay so that is the end point of the query that we want to make all right so let's actually formulate this query so we're gonna set this to a variable called response and that is gonna be equal to a request from the requests library which we've imported and it's a get request and obviously we want to the URL is going to be this query variable which we've already assigned the parameters well let's take a look at the API as you can see all these are actually optional parameters but what is required is a header field required a valid access token from the Spotfire account service here is the format that you will want to put this in let's do that right now headers equals curly brackets first thing we're gonna do is define the content type as JSON so we're gonna do content that type : application slash JSON now we're going to type authorization and be careful this is the American spelling of authorization with the said authorization : bearer curly brackets and then we're also gonna use dot format on this string and pass in a Spotify token there we go okay that is the request so we've made a request to the Spotify API and we have said we want the tracks of this playlist and we should get a response in JSON so we can check if that's working what we'll do is go response underscore Jason equals response dot Jason lovely then we can print the response and we'll just run this now to see if this is actually working so to run it we will just say a equals safe songs and then we will call a dark find underscore songs let's just click run response 200 now a response 200 means okay that is completed successfully and that is because I have printed out the actual response code not the response and it's got JSON which we just created so if we change that and run it again there we go now you can see we get a lot of stuff in response and let's break down what this actually is because this is where people get worried they're like what the hell is this but this is actually very very simple and the Spotify API explains this as well so what we get back is a JSON list okay and this starts off with the URL of the playlist and then we have an items list okay as you can see the key items corresponds to the following list okay and this list is another list of JSON values so each track will have its will be its own JSON item and you can sort of think of this almost like a dictionary of key value pairs and for each track we have an added add value and added by URL ID type and so on to just verify this I can actually see here track one Elton John ah here's the title captain fantastic and the brown cowboy well just to verify I'm gonna go into my discover weekly and you as you can see yeah that is the first track so great that's what we've achieved we've now printed out every single track of this playlist however that is not what we want because we want to actually create a list of all the individual IDs well how we gonna do that the first thing I'm gonna do is just add some print statements to say what we do in wine so I was gonna say print finding songs in discover weekly okay I'm actually just gonna print the response because if the response is 200 we know it's okay okay lovely so now how do we extract all these IDs well you can probably guess we're gonna use a for loop so we want to loop through this entire thing so what exactly we're gonna look through well we can start by saying we're gonna use for I in response underscore JSON but now what though because the response on this code Jason looks like this and it has the following keys it has the href and then it has items that's what we want we want to loop through everything in this items key so everything here okay so that is all the songs so if we say for I in response to some items alright and just to verify this I'm just going to print I but if we do this okay we still get this and yeah now that looks less confusing as you can see it is actually printing out each individual song but again it's printed out so much stuff we can't actually see what's going on so we need to break it down even further so what we've got now is we have this whole structure right so for each we're looping through each one of these so for every single song has all these different things and we want to we don't want the externally or us will ignore that what we want is here the track key corresponds to the following values okay and in the track key we want to isolate the URI because that is actually what is required to add it to the Spotify playlist we're already in response items and we're looping through every single song so now all we've got to do is add to print this just to make sure that it works so print I and in the song obviously we want the Trac key within the track key we want the you are I now let's run this and see what we get there we go we get a list of you are ice lovely okay but the problem is we don't want to print it we want to add all these to a list let's just make a list here I'm just gonna call it self duck Trax equals I'm actually set this is a string because in the request that we send is actually easier to just send it as a string of comma separated values rather than the list representation of that for every song self tracks plus equals this and I'm also going to add a comma because there needs to be a comma separated list so now what we will do is we'll create a string full of comma separated values of track you are is the only issue here is the final value will also have a comma but nothing following it and we can just fix this very easily just by saying self dot tracks equals self dot tracks and we will slice nothing minus one okay so it's just colon minus one and what that means is basically just remove the last character to remove the last comma and there we go so that will now create a list of URLs and if you really want to verify it just do self dot tracks print and there we go so this is the list of your eyes that we will pass to the API now we need a second function so we've we've gone through the songs and we've found the one we've added them to a playlist great what step two well step two will be to create a new playlist let's make a function call create underscore playlist and this well but create the new playlist obviously and if you take a look at the API documentation for this we can see that we're actually sending a post request to this URL we're passing in the user ID and we're also setting the following parameters name is it public or not and so on so let's do that right now the query will be sent to this URL which is given to us query equals this and once again we're gonna delete this in the curly brackets and we'll add that in using dot format and we want to pass in a Spotify user ID we now need to specify the body of the query so I'm gonna go request underscore body and it's gonna be called JSON doc dumps in parentheses we are going to specify a JSON list again and first one is going to be name so this is just the name of the playlist so you can name this anything you want any string can go here and that will just be the name but what I want to do is get today's date the date that we're saving it on and then discover weekly because I want this to run every Monday when the discover weekly gets refreshed so to do that I am just going to import another package from date/time import date I'm just gonna do this in the create playlist function we're just gonna make a variable call today and set that equal to date dot today okay and then to format it correctly and it's gonna create a new variable call today formatted and set that to today dot STR F time I want this to be in the format day month year because that's how we do it in the UK and it's it's the right way come on and so just Center sang D slash percentage sign em slash percentage sign capital y o and I'm getting an error because I am put equals okay great I'll just get today's date as I say so we will use that in the name field this equals today formatted so today's date plus discover weekly the rest of these body parameters are all optional but I will add a description anyway the description would be anything you want so just put anything in there and I'm also going to set this to public if you want it to be private just do public foss but I'm just gonna do public true okay so that's our request body done now we can send the query so I'm going to do response equals requests dot post this time not get and this is going to take the query as the URL we're then going to do data equals quest body and finally headers is going to be equal to exactly what we did up here really we should put that in a variable if we're gonna use it twice but who cares I'm just gonna copy it okay so that is the response so let's just turn this to Jason just like we did before equals monster Jason and I will then print this and see if it actually works and I've Spotify open and on the left just you can see if this actually works the playlist should just appear here automatically once it's done instead of calling find underscore songs I'm just going to call create playlist now let's click run and there we go so it's appeared over here the place actually been created it has the description which we gave it and also um it's given us this response back so this response is just a JSON list describing the playlist there we go so we have we can now find all the songs and copy the IDs and we can also create a playlist lovely so we'll really get it in there now so now the only thing left to do is to actually add all the songs which we have saved to this tracks list to this new playlist so we will of course create a new function called add to playlist okay and obviously this function will just add all songs to new playlists so if we take a look at the Spotify API documentation for this you can see that we send another post request to this end point with our playlist ID and we pass a list of Spotify you our eyes there's one more thing that we should do in the create a playlist thing you should actually return the ID of the playlist we just created so we can use it in this next function so I'm just gonna return response underscore JSON ID and if we take a look in this response here that will just return this ID which is being created for this playlist and I will also just print out so it tells us what it's doing and trying to create playlist and black print out here as well print adding songs let's make a new class level variable just call it new playlist underscore ID okay and we will set this equal to in this function the return value of the create playlist so that is how we're gonna invoke the create a playlist method now in this function we actually create the playlist assign it to this and then add the songs alright so now what should the query be well we are given the URL here in the API so we want to send a post request to this and we will obviously get rid of this will do doc format self dot new underscore playlist ID so that's the ID of the place we want to add to and will also pass an optional field which is a comma-separated list of Spotify you our eyes we've actually already got that because we extracted it from the playlist earlier and we've saved that in the Trax variable finally we will actually make the request and they'll be requests dot post query and also the headers will be the same as it's been before and I really should have added this to a variable that should work so now let's print the response Jason so if we run the correct function here at the playlist obviously this will call the create playlist function within itself what I will need to do is first actually find all the songs so we need to once we found the songs we should call the add to playlist function the self dot add to playlist ok so we will call this as a user that will find all the songs it will call the add to playlist function which creates the new playlist by calling this function and then adds all the songs that we got from this function into the playlist alright so that means that we will then call find songs so that should actually work and what I'll do is just put Spotify and trying to create playlist math response of 400 so it's created the playlist but we've received the sponsz a response of 400 when it's trying to add songs to the playlist of course I forgot to add in the final query here so we just do a question mark with the key you are eyes equals and an empty list because we added in this in the format but we didn't put it in here ok so now if we run this there we go we get a response of 200 which wants a 201 which means it's completed is created another player so we have two now and this one actually contains all the songs the only thing that's left to do now is actually have this run on a weekly basis and also to refresh the authentication code so how do we request refreshed access well hopefully you saved your refresh token from the kill command we entered in initially so that was the command which actually got us the initial spotify token in the first place it also came with a refresh token so we need that and we have to send another post request so we're actually going to do this one programmatically we didn't do the first one programmatically just because they wanted to get the app up and running quickly this one we actually want to run automatically every single time the app runs because the code will expire by the next time you use it because our use case is running once a week so for that reason I am actually going to delete this Spotify token here okay I'm gonna make a new file called refresh dot py in the init function the only thing I need is south dot refresh and score token which I'm gonna import from secrets also in secret I'm going to put if you remember in the curl command we specified a client secret and our client ID separated by a colon in base64 I'm actually gonna put that here so I'm gonna do base64 I just call it that paste that in okay so after refresh token equals refresh token and cell top base 64 equals base 64 and I'll just import that here as well okay so this needs to have a function called death refresh and that is just going to make a post request where I'm gonna import requests yeah and import JSON okay that's just gonna make a request and it's going to use following styles so this is the curl command okay so instead of typing that in as a kill command like we did before I'm just gonna convert this to a request dot post request in Python so how do we do that well gonna sign it to a variable and we'll call it response and that's gonna be eat that's gonna equal request stop post obviously the URI I'm going to put that as an available called query as we've been doing that is going to be this endpoint we can put that into here so the URL is going to be query okay the data is going to be the following grunt underscore type in the API it gives us this is just going to be refresh token so : refresh and the score token then fairly confusing me because we have refresh token here the next key is actually refresh underscore token but this obviously refers to the token itself which we import from secrets so that's a refresh token which was given only run the first kill command okay the only thing we need now is the headers okay and this is just going to be authorization but the Z basic and then our base64 encoded string which of course is our client ID from the app and the clients seek from the app separated by a comma in base64 okay so that it creates a response and hopefully it should respond with a brand new key so we can just print out response Jason print that obviously we will just run I just run this here for now so a equals refresh a dot refresh run and there we go it's responded with a brand new key okay what we should do here then is actually return response and we want to return the access token so a slice access and the score token so now that should just respond with this so in the main application what I will do is actually create its own function here and just call it def call underscore refresh okay and that will just call the refresh function from here I decided to put this in his main file because it is not a part of the main set of instructions I just like to have things in their own file but we will call it from within here so just call refresh and make a variable called refresh caller equals refresh and we will want to import that so from refresh import refresh also in secrets we no longer import the token because we're gonna generate it here okay I'll just set that equal to it so we'll set the token equal to an empty string and then set it down here so refresh caller equals refresh I'm just going to say self dot Spotify token equals refresh refresh caller dot refresh because the refresh function returns the access token so that should set the brand new one as this variable here and then we can continue to access it as normal so let's see if that will now work so I just print refreshing token and then once it's been refreshed we can then call the next function which is find underscore songs so this function calls finds songs and which of course you know well instead of calling here we call in this function so we want to call this to begin with so we now actually need to replace this Spotify token with self dot Spotify token because previously we were just using the bit that we imported but we can't do that anymore so we'll just change that to self dot Spotify tokens after Spotify token then you would save hopefully the red line goes away and that is fine so hopefully now when we run this this should work oh and we get in there a response object is not subscript Abul because we didn't convert it to json so we actually need to do response underscore json equals response dot JSON and then we can slice it like that okay so response underscore Jason and hit run there we go so it's refreshing token finding songs and discover weekly adding songs creating playlists boom there we go also we've now programmatically refreshed our code so the app will work pretty much forever we don't have to worry about manually to reset them the code every week okay one thing is remaining how do we get this to run automatically so the schedule the task we're just gonna use the windows task scheduler if you're on Mac or Linux then you will be able to find similar programs to allow you to do this but this part this tutorial is really window only to do this on Windows which is gonna click create task him and we can give it a name I'm just gonna call it Spotify API tutorial okay you can give it a description but you don't have to okay so now click triggers and for the purposes of this tutorial I just want it to happen one time I'm just gonna set it to happen in a few minutes time however if I was actually using this program I'd want it to run every Monday so we could do that by clicking weekly okay so once you have the trigger you can then add an action and the action is going to be to start a program and the program we want to start is actually Python in order to do that we want to get the directory of Python you can do that quite easily by just opening up idle and type in import sis and then to type sis dot executable presenter and that will print out your - directory so you can copy that and paste that in the script and this is python w exe it won't just open up a command line window and potentially distract you if you're working on something else it will run in the background and you won't even notice it so the arguments we want to add to this is just a Python program and if you remember this was called main DUP UI that we want to run the main file which will also which will call the refreshness secrets so we're gonna type in main UI and we want to start in this is the directory that this program was starting and obviously we just want that to be the directory where our main file is stored and that is all we need to do for this so now click OK and there's also a lot of different settings so you might want to look at for example if it misses your scheduled tasks then you can have it so it runs again automatically and you're all sorts of different settings you might want to look at you but that is the gist of it right so I'm just gonna set this to run in the next minute just so I can show you that it works I'm gonna click OK and the task is now ready so the program should begin running in 5 seconds and we should hopefully see a new playlist pop up just here and there we go it popped up straight away really quickly and it was completely in the background nothing popped up and that's what we want so you can schedule out every single week and it will keep working and once again it is a long process to automate something that you can do just like this you could just go select all copy new playlist create but what's the point in that if we can spend hours do neal encode am i right
Info
Channel: Euan Morgan
Views: 11,583
Rating: 4.9376945 out of 5
Keywords: spotify, api, python, programming, tutoriall, automate, python spotify, automation, discover weekly
Id: -FsFT6OwE1A
Channel Id: undefined
Length: 46min 2sec (2762 seconds)
Published: Tue May 26 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.