DEV Community

Giuseppe Frau
Giuseppe Frau

Posted on

Healify - Healing songs (part2) - Interacting with spotify apis with python and flask

Hi there :)
This is the second part of my diary about healify.it the side project I'm using to collect healing songs. Before diving into the technical stuff I'd like to spend some words to thank all the people who, after reading the first post, dedicated some time to send a song and leave a message. Thank you. At the moment there are 92 songs in the playlist (by the way, I've added a simple counter to show how many entries there are in the list, I'm quite proud of it, so go check it out on healify.it)

So, this part is about setting up a basic flask app in python and interacting with the spotify apis.
For those who don't know it, flask is a "is a microframework for Python based on Werkzeug, Jinja 2 and good intentions" :) You can use it for building REST apis in python. What I love about flask is how easy is to build and expose your functions. It's very well documented with good examples, and if you look at their website you find the code for simplest app. You first install it through pip and then

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

This is saying
1- create a flask app (a flask app will come with a lot of useful methods and objects for dealing with the requests)
2- I want my app to answer "Hello world" when the "/" route is reached. You can use any name for the function following the @app.route decorator

Now, to see the result on your dev environment, you can directly run your python code and flask will setup a local server for you

FLASK_APP=hello.py flask run
 * Running on http://localhost:5000/

That launches a simple built-in server, and you should only use it for testing/dev purposes. You can of course use a different way, for example to run my application I usually have a two lines bash script using gunicorn like this (config.sh contains my port and app_name but also other variables I use in the production environment)

#!/bin/bash -
source config.sh
gunicorn -b 127.0.0.1:$port $app_name:app

You can find more details about building a minimal application here and about deploying options here

Let's move forward. Our goal was to have our code to interact with the spotify apis. In particular we want to interact with the search node and build a very simple engine for the autocomplete part (the way I've implemented on healify it's probably not the best one).
Spotify offers a rich set of api functionalities. Start to explore them here
You can login using your existing spotify account, and then you will need to create a client id for your application through their nice dashboard. This will give you a client ID and a client secret necessary for authenticating your requests from your app.

The general flow for interacting with spotify is the following
1 - authenticate yourself and get a token: you will use the token for the following requests. Depending on what you want to do next you will need different kind of authorization (reading libraries, editing playlists etc). In our case we need the lowest level as we won't access any user data
2 - send the request to the specific node and get the data

Our node is the search node, allowing you to search for tracks, albums, artists, playlist. For that we will need

  • the token
  • the query
  • the type of desired results (tracks in our case)

So first of all, I've written a simple function for the authentication that returns you the code

def spotify_authenticate(spotify_client_id, spotify_client_sectret):
    data = {'grant_type': 'client_credentials'}
    url = 'https://accounts.spotify.com/api/token'
    response = requests.post(url, data=data, auth=(spotify_client_id, spotify_client_secret))
    return response.json()['access_token']

Then I've created a backend-search branch in my flask app like this. It should be quite straight forward. It gets the token through the previous function an then after constructing headers and parameters, it uses the requests python package to send a GET to the api node

@app.route('/backend-search', methods=["GET"])
def search():
    token = spotify_authenticate()
    search_url = 'https://api.spotify.com/v1/search'
    #i know i shouldnt be doing this
    search_txt = request.headers.get('search_text','')
    if search_txt == '':
        search_txt = request.args.get('search_text','')

    headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': 'Bearer {}'.format(token),
    }
    params = (
        ('q', '{}*'.format(search_txt)),
        ('type', 'track'),
        ('limit', 10)
    )

    response = requests.get(search_url, headers=headers, params=params).json()
    return json.dumps(response)

It was fun to look inside the response object. It really contains a lot of information about the tracks and it is very easy to understand.
Give it a try and have a litte fun playing with it.
To test my code I've used my local server and the Postman utility to inspect the results.

That's all for this part. Next one will be about building the page with semantic-ui and sending our requests through some simple javascript.

Stay tuned and do not forget to add some songs in the healify playlist

thank you

Top comments (0)