Have you ever felt like you've missed an album from your favorite artist? If yes then this article is just for you.
Here we will fetch your followed artists and their albums from Deezer API to see whether you missed any releases or not. We will use Python to do all the work.
Getting started
First, you'll need to know your ID. You can get it by opening Deezer in a browser and visiting your profile.
Now, if you check the URL address you should see something like this
https://www.deezer.com/en/profile/700513741
A number at the end of the URL is your ID (mine is 700513741
). Let's store it in a variable.
deezer_id = 700513741
If you want to get IDs of users of your project you'll need to create a Deezer application and connect that application to your project. For more information on how to do that you can check out this guide.
Fetching information about you
To begin our fetching journey let's fetch ourselves first. To fetch a user we can use Deezer's User endpoint. We just need to send a request to a URL specified in the documentation and information about a user should be in the response.
But before doing any requests with Python we can try doing some requests in Deezer's API explorer.
The docs say that the URL for getting info about a user is https://api.deezer.com/user/me
. but if we try to perform a request to the endpoint we receive an error
An active access token must be used to query information about the current user
This means that we have to get a token that is related to our user for Deezer to know who is "me". But we all like doing things in an easy way and getting that access token is just too hard. This is exactly why I asked you to get your ID by yourself. Now we can just replace /me
with your ID and everything should be working. Here's what I got in the API explorer
Making real requests
Making requests in Python is very easy with requests
library. If you don't have the library installed you can use an official installation guide. Once you have requests
installed we can proceed to coding.
To send a regular GET
request with requests
the library provides us a get
method which just needs a URL
import requests
url = f"https://api.deezer.com/user/{deezer_id}"
user_response = requests.get(url)
The user_response
variable should now contain lots of data that happened during the request. What interests us is what the body of the response. We can get it with response.content
method
user_response.content
# => b'{"id":700513741, "name":"hmlON", ...}'
As we can the response contains a JSON string. We could parse it with a json
library but requests
have worked everything out for is — we can just use a json()
method
user_response.json()
# => {'id': 700513741, 'name': 'hmlON', ...}
Now we have a normal dictionary with which we can work. Let's finish our "hello world" program (Deezer API edition) before we continue making other requests
name = user_response.json()['name']
print(f"Hello, {name}!")
Fetching your favorite artists
Your favorite artists can be found on a User / Artists endpoint. As usual, it suggests to use /me
in the URL but we're smarter then that and will use the ID. So let's test the endpoint.
artists_url = f"https://api.deezer.com/user/{deezer_id}/artists"
artists_response = requests.get(artists_url)
artists_response.json()
# => {
# "data": [
# {
# "id": "296861",
# "name": "The Neighbourhood",
# ...
# },
# ...
# ]
# ...
# "total": 30,
# "next": "https://api.deezer.com/user/700513741/artists?index=25"
# }
The endpoint seems to be working. As we can see from the response, we have a couple of interesting fields here:
- data — your favorite artists that we wanted
- total — how many artists we are following
- next — a link to the next page of results
The next
parameter is empty if a response returned the last page of data. This means that if we want to just take a glance at artists we can send requests as is. But if we want to fetch all data (like we do now) we would have to use this parameter.
The algorithm for fetching all records is pretty simple — we go to the next page while it is present. Let's go ahead and implement it
artists = [] # we'll store artists here as we go through the pages
all_artists_loaded = False # in the beginning nothing is loaded
url = f"https://api.deezer.com/user/{deezer_id}/artists"
while not all_artists_loaded:
response = requests.get(url).json()
artists += response['data'] # data attribute contains artists from the request
if response.get('next'): # there are more artists on the next page
url = response['next'] # we will continue to fetch from the next page
else: # there are no more followed artists
all_artists_loaded = True # we will end the loop
The algorithm is pretty straightforward but there is one thing I would like to note. When I'm checking whether there is a next page I use response.get('next')
instead of response['next']
. The difference here is that when the next key is not present in the response the response.get('next')
method will return nothing while the regular response['next']
will raise an error.
response = {'data': ['...']} # response without the 'next' attribute
response['next']
# raises KeyError: 'next'
response.get('next')
# => None
Fetching your favorite artists' releases
Now that we have all followed artists we can fetch their albums. The Artist / Albums endpoint is quite suitable for this task.
This time we would need to loop over each artist and save all albums in an array. To fetch all releases for each artist we would use the same algorithm as we've used to fetch artists.
releases = [] # we'll store all releases here
for artist in artists:
# the old algorithm is still working here
all_releases_loaded = False
artist_id = artist['id']
url = f"https://api.deezer.com/artist/{artist_id}/albums"
while not all_releases_loaded:
response = requests.get(url).json()
releases += response['data']
if response.get('next'):
url = response['next']
else:
all_releases_loaded = True
Pretty much the same as before. But there is one problem which we will notice if we look at any release
releases[-1]
# {
# 'cover': 'https://api.deezer.com/album/40571541/image',
# 'explicit_lyrics': True,
# 'fans': 52,
# 'genre_id': 116,
# 'id': 40571541,
# 'link': 'https://www.deezer.com/album/40571541',
# 'record_type': 'single',
# 'release_date': '2017-04-18',
# 'title': 'DEADMAN WUNDERLAND',
# 'tracklist': 'https://api.deezer.com/album/40571541/tracks',
# 'type': 'album'
# }
The problem is that we don't know who the artist is. We can solve it in two ways:
- by storing artists in a dictionary with their ID as a key and adding
artist_id
to all releases - by storing full title (with artist's name) in the release
I will go with the second one since it would be easier to do but if you would like to implement the first solution or any other please share it in the comments.
To save the full title in a release we would need to store artist's songs in a temporary array. And when all albums are fetched we would need to add the full title to them.
releases = [] # we'll store all releases here
for artist in artists:
# this time we'll store releases in a temporary array
current_artist_releases = []
# nothing changed here
all_releases_loaded = False
artist_id = artist['id']
url = f"https://api.deezer.com/artist/{artist_id}/albums"
while not all_releases_loaded:
response = requests.get(url).json()
# now we're saving each page's response to current_artists_releases
# instead of straight to releases
current_artist_releases += response['data']
# this stays the same too
if response.get('next'):
url = response['next']
else:
all_releases_loaded = True
# and after we've fetched all releases
# we can add full title to all of them
for release in current_artist_releases:
full_title = f"{artist['name']} — {release['title']}"
release['full_title'] = full_title
# and only after we every release from current artist
# has a full title we can add them to the main releases
releases += current_artist_releases
So now all releases should have a full title
releases[-1]['full_title']
# => 'Aries — DEADMAN WUNDERLAND'
So what have you missed?
Let's check what was released during the last year. If you haven't checked it, you might be surprised by some interesting albums.
To begin, we need to filter releases so that only that were created during the last year are left. To do this we will use a standard datetime library to get a date of the last year
import datetime
today = datetime.date.today()
print(today)
# => 2018-12-13
year_ago = today - datetime.timedelta(days=365)
print(year_ago)
# => 2017-12-13
Then, to filter we need to compare the release date with our year_ago
variable. The only problem here is that release date is a string
releases[-1]['release_date']
# => '2017-04-18'
And we can't compare string with a date in Python. So a way out of this is to convert a string into a date. The datetime library has a function just for our case called datetime.strptime
. It needs a string (the release date) and it's format.
As we can see, release_date
format is 'year-month-day'
. With a little help of documentation, this converts into '%Y-%m-%d'
datetime.datetime.strptime(releases[-1]['release_date'], '%Y-%m-%d').date()
# => datetime.date(2017, 4, 18)
Let's store the release_date
as a date instead of a string for all releases
.
for release in releases:
previous_date = release['release_date']
new_date = datetime.datetime.strptime(previous_date, '%Y-%m-%d').date()
release['release_date'] = new_date
Now we can finally filter our releases
to get only the ones from last year
latest_releases = [
release for release in releases
if release['release_date'] > year_ago
]
After that, all of the last year's releases are stored in the latest_releases
variable. Now we need to sort those releases by date to have them listed chronologically
latest_releases = sorted(latest_releases, key=lambda release: release['release_date'])
And finally, we can print those releases
for release in latest_releases:
date = release['release_date']
title = release['full_title']
print(f"{date}: {title}")
# ...
# 2018-10-25: Aries — BLOSSOM
# 2018-11-02: Panic! At the Disco — The Greatest Show
# 2018-11-02: The Neighbourhood — Hard To Imagine The Neighbourhood Ever Changing
# 2018-11-09: Muse — Simulation Theory (Super Deluxe)
# 2018-11-09: Imagine Dragons — Origins
# 2018-11-09: Imagine Dragons — Origins (Deluxe)
# 2018-11-09: Goody Grace — Nostalgia Is A Lie
# 2018-11-30: Arctic Monkeys — Tranquility Base Hotel & Casino
If you've followed along this far please share your latest releases for the last month in the comments.
Conclusion
In this article I've covered:
- how to work with Deezer API
- how to make requests with Python
- how to convert strings into dates
Congratulations, now you know how to check for new releases from artists that you follow. If you're like me and hate missing out on new releases from your favorite artists, I've built a website just for this purpose.
If you would like to run the code by yourself and don't want to scramble it from the article pieces by pieces, I've uploaded it into a gist on GitHub.
Also, this is the third part of a series of articles about the MuN. Stay tuned for part 4. You can find the code of this project, as well as my other projects, on my GitHub page. Leave your comments down below and follow me if you liked this article.
Top comments (0)