Use Ansible to automate Spotify - Part I
To find new music with Spotify I thought about to go a new way … so why not using Ansible to automate Spotify ?
- The modules
- Step 1 - Prerequisites
- Step 2 - Authentication
- Step 3 - Let’s do something
The modules
To use Ansible to automate Spotify I developed 9 different Ansible modules which contacts the Spotifi API using the Python library Spotipy.
The modules including examples, roles and configuration can be found on Github (Link).
Following Ansible modules are at the moment available:
Module name | Description | Documentation |
---|---|---|
spotify_auth | Module for the authentication process | Link |
spotify_auth_create_user_token | Module for the user authentication process | Link |
spotify_album | Get information about one or multiple albums. | Link |
spotify_artists_top_tracks | Get the top tracks of an artist | Link |
spotify_player | Spotify Player to play a song and more. | Link |
spotify_related_artists | Get related artists | Link |
spotify_search | Search in Spotify | Link |
spotify_track_data | Get Audio features from a track or analyse tracks | Link |
spotify_user_info | Get user information | Link |
spotify_user_playlists | Search and create a user playlist | Link |
spotify_update_playlists | Add or remove songs from a playlist | Link |
Step 1 - Prerequisites
-
Download or clone the github project
-
Spotify Client ID & Secret
All modules are doing API Calls and to do API calls we need a CLIENT ID and CLIENT SECRET. You can go to Spotify Developer(Link) and create your own or use the one from my github example. If you create your own one don’t forget to permit a redirect url. I recommend to use the default redirect url http://mbloch.s3-website-ap-southeast-2.amazonaws.com
.
Once you have created your own keys you may want to update the inventory files ansible/inventory/group_vars/public.yaml
& ansible/inventory/group_vars/user.yaml
.
- Spotipy
All modules are using the python library Spotipy version 2.4.4 to connect to the Spotify API. Since the Github version contains several improvements and bug fixes which are not released on pip yet we need to install Spotipy from github:
Step 2 - Authentication
After finishing the Prerequisites. Let’s see how authentication is done as this is very important and quite complex.
Depending on the authentication process the modules require different parameters.
Public authentication:
- client_id
- client_secret
User authentication:
- client_id
- client_secret
- username
- redirect_uri
- scope
All Ansible modules require an authentication_token. To create an authentication token we need to use the modules spotify_auth
& spotify_auth_create_user_token
.
The redirect_uri
is the URL where Spotify will redirect you once you allow the application access, more information can be found further down at user authentication process. The scope
tells Spotify what your application is allows to access. More information and which scopes are available can be found here (Link).
Depending on the use case we may want to use the public authentication or user authentication process.
Public authentication process
- Connect to Spotify API and passing the parameters client_id & client_secret.
- Receive authentication token
The public authentication process only requires the module spotify_auth
. The client_id & client_secret can be set via configuration file i.e. ansible/inventory/group_vars/public.yaml
:
1
2
client_id: a430d21d72594499a3aaee8dc9636a3f
client_secret: 7660b5c77ed34df48bac67beed2e100c
Playbook use:
1
2
3
- name: Spotify public authentication via configuration file
spotify_auth:
config_file: "{{ inventory_dir }}/group_vars/public.yaml"
or we can set the parameters in a playbook:
1
2
3
4
- name: Spotify public authentication
spotify_auth:
client_id: a430d21d72594499a3aaee8dc9636a3f
client_secret: 7660b5c77ed34df48bac67beed2e100c
User authentication process:
-
Search for local cached credentials in
/tmp/.cache-USERNAME
and use if exist -
if no cached credentials exists connect to Spotify API and pass parameters
-
Allow application access for your Spotiy Account & receive API Code
-
Pass API Code to Spotify API with module
spotify_auth_create_user_token
-
Receive authentication token
As you can see the user authentication process is a bit more complex and requires the modules spotify_auth
& spotify_auth_create_user_token
. The required parameters can be set via configuration file i.e. ansible/inventory/group_vars/user.yaml:
1
2
3
4
client_id: a430d21d72594499a3aaee8dc9636a3f
client_secret: 7660b5c77ed34df48bac67beed2e100c
redirect_uri: http://mbloch.s3-website-ap-southeast-2.amazonaws.com
scope: playlist-modify-private,playlist-modify-public,user-read-currently-playing
Playbook use:
1
2
3
4
- name: Spotify user authentication via configuration file
spotify_auth:
username: bloch-m
config_file: "{{ inventory_dir }}/group_vars/user.yaml"
or we can set the parameters in a playbook:
1
2
3
4
5
6
7
- name: Spotify user authentication
spotify_auth:
username: bloch-m
client_id: a430d21d72594499a3aaee8dc9636a3f
client_secret: 7660b5c77ed34df48bac67beed2e100c
redirect_uri: http://mbloch.s3-website-ap-southeast-2.amazonaws.com
scope: playlist-modify-private,playlist-modify-public,user-read-currently-playing
The module spotify_auth
checks if a cached authentication token exists and will return it. If there is no cached authentication token the module connects to the Spotify API and Ansible will open up your default OS browser
and redirect you to the Spotify authentication page. Now you have to login to Spotify and allow the application Access to your Spotify. Once you have done this you will be redirected to the specified redirect_uri. If you are using the default redirect_uri copy the API Code as shown. If not you may need to copy the API Code from the address bar in your browser i.e. you need to copy the part after ?code=
e.g. https://example.com/?code=ABCDEFG
copy ABCDEFG
.
Once copied you need to pass it to the module spotify_auth_create_user_token
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- name: Create user token from Spotify API user code
spotify_auth_create_user_token:
api_user_code: "ABCDEFG"
username: bloch-m
config_file: "{{inventory_dir}}/group_vars/user.yaml"
or
- name: Create user token from Spotify API user code
spotify_auth_create_user_token:
api_user_code: "ABCDEFG"
username: bloch-m
client_id: a430d21d72594499a3aaee8dc9636a3f
client_secret: 7660b5c77ed34df48bac67beed2e100c
redirect_uri: http://mbloch.s3-website-ap-southeast-2.amazonaws.com
scope: playlist-modify-private,playlist-modify-public,user-read-currently-playing
Authentication role
To automate the authentication process as far as possible I created the role authentication
which will set the authentication token as fact auth_token
.
Role use in playbook:
1
2
3
4
5
6
7
8
9
---
- hosts: localhost
connection: local
gather_facts: false
vars:
config_file: "{{ inventory_dir }}/group_vars/user.yaml"
username: bloch-m
roles:
- authentication
The tricky part is passing the API Code, for creating the user authentication token, from the Ansible module spotify_auth
to the module spotify_auth_create_user_token
. To realise this, the role will tell Ansible to wait for Input while the Browser opens up the URL define in the redirect_uri
option. Once the application is allowed copy the API code and go back to your terminal where Ansible is waiting for you and enter the API Code. After entering the API Code you will get an authentication token to use with the other Ansible modules like spotify_update_playlists
.
Initial user authentication:
Cached User authentication:
Public authentication:
Step 3 - Let’s do something
Now that we know how to authenticate we can finally do something. Let’s start with something easy…
Search with Ansible
To search in Spotify with Ansible we can use the role search
which is using the module spotify_search
. The module allows us to search for artists, albums, playlists, tracks, artists & album, artists & track
.
Role use in playbook:
1
2
3
4
5
6
7
8
9
10
11
12
13
---
- hosts: localhost
connection: local
gather_facts: false
vars:
config_file: "{{ inventory_dir }}/group_vars/public.yaml"
search_for: artists
search_for_artists_name: Young the Giant
search_result_output: short
search_result_limit: 20
roles:
- authentication
- search
As you can see we first execute the role authentication
and than executing the role search
. The authentication role takes care of getting an authentication token from the Spotify API and due setting the authentication token as fact auth_token
it can be used by all other roles included in the playbook.
Search artist Young the Giant:
Access some User data
We can use the role user_info
which use the module spotify_user_info
. This module allows us to access user data like current playback, recently played, users top artist, users top tracks and general user info
.
Role use in playbook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
- hosts: localhost
connection: local
gather_facts: false
vars:
config_file: "{{inventory_dir}}/group_vars/user.yaml"
username: bloch-m
user_info_output: short
user_info_limit: 50
user_info_dest_file: "{{ playbook_dir }}/../files/{{ username }}_top_tracks.json"
user_info_state: top_tracks
user_info_time_range: medium_term
roles:
- authentication
- user_info
This playbook will save informations in short format about my most 50 played tracks within the time range medium_term
to {{ playbook_dir }}/../files/{{ username }}_top_tracks.json
. The saved file can than be consumed i.e. from the module spotify_update_playlists
for adding those tracks to a own playlist.
Get users top tracks:
Conclusions
Since the authentication process is a little bit complex I would recommend to always run the authentication
role first.
Furthermore, I tried to build the modules as much as possible compatible to each other. Which means every module which has the capability to load information from a file can use the save results from other modules e.g. the saved output from the module spotify_related_artists
can be consumed from the module spotify_artists_top_tracks
to get all top tracks from related artists. This gives us the possibility to create more complex Ansible playbooks like add all top tracks from all found related artists to a new created playlist.
To get more information about the project, the Ansible modules and more examples visit the Github project (Link).
More about constructing more complex playbooks is coming up in Part II.
Have fun trying and testing.
Cheers!