Source code here.
GET /api/v1/search/tracks/
The tracks in the database that match the query. Max 10 tracks with the option to choose the number of results with the n argument. Results are ordered by relevance.
Example request:
GET /api/v1/search/tracks/?q=oasis&n=4 HTTP/1.1
Host: example.com
Accept: application/json
Example response:
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"items": [
{
"artist": "Tarja",
"id": 37237,
"lastfm_tags": [
"symphonic metal",
"female vocalists",
"Classical",
"Tarja Turunen",
"beautiful"
],
"name": "Oasis",
"preview_url": "https://p.scdn.co/mp3-preview/53a977d65842fa07f7b8081535e579852247d8de?cid=0c0bb28de56d49d3b925f9755a289113",
"spotify_id": "5hGoIsMmOwF3EsDpp4nwws"
},
{
"artist": "Oasis",
"id": 10748,
"lastfm_tags": [
"britpop",
"rock",
"oasis",
"acoustic",
"british"
],
"name": "Half The World Away",
"preview_url": "https://p.scdn.co/mp3-preview/569431423cf0900a40238fb6989995da3ed4f1f2?cid=0c0bb28de56d49d3b925f9755a289113",
"spotify_id": "6aM4E6WfuoDnPAgaKaZ5hM"
},
{
"artist": "Oasis",
"id": 16795,
"lastfm_tags": [
"britpop",
"rock",
"90s",
"british",
"oasis"
],
"name": "Don't Look Back in Anger",
"preview_url": "https://p.scdn.co/mp3-preview/8d5ecd081b86c19a0189462c2222687088a15ed1?cid=0c0bb28de56d49d3b925f9755a289113",
"spotify_id": "698mT3CTx8JEnp7twwJrGG"
},
{
"artist": "Oasis",
"id": 16992,
"lastfm_tags": [
"rock",
"britpop",
"90s",
"alternative",
"oasis"
],
"name": "Wonderwall",
"preview_url": null,
"spotify_id": "7JrUo70YjhU4S7flcJtK0k"
}
]
}
Query Parameters:
· q – track name, artist name or both
· n – Number of results. Max 10. Default 10.
Request Headers:
· Accept – application/json
Response Headers:
· Content-Type – application/json
Status Codes:
· 200 OK – no error
· 400 Bad Request – bad request (e.g. wrong request accept type)
· 429 Too Many Requests – exceeded rate limit of 5 requests per second
=======================================================================
GET /api/v1/similar/
The similar tracks in the database that match the spotify id in the url argument. Max 10 tracks with the option to choose the number of results with the n argument. Results are ordered by score of similarity.
Example request:
GET /api/v1/similar/?spotify_id=30UTvW5IQWXmvdcZ1zbF6R&n=5 HTTP/1.1
Host: example.com
Accept: application/json
Example response:
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"items": [
{
"artist": "Boogie Down Productions",
"id": 6007,
"lastfm_tags": [
"Hip-Hop",
"Old School Hip Hop",
"old school",
"hip hop",
"rap"
],
"name": "The Bridge Is Over",
"preview_url": "https://p.scdn.co/mp3-preview/04a97c7c1c8cc89293006d3f4e57aac4ccf824bd?cid=0c0bb28de56d49d3b925f9755a289113",
"score": 2.7284167729011495,
"spotify_id": "5jkjpSsMOfsxgdGScPZVq2"
},
{
"artist": "Beastie Boys",
"id": 6009,
"lastfm_tags": [
"Hip-Hop",
"rap",
"hip hop",
"80s",
"Beastie Boys"
],
"name": "Shake Your Rump",
"preview_url": null,
"score": 2.7284167729011495,
"spotify_id": "4RvprQhj7Ov1SFQ3HfO7FH"
},
{
"artist": "Ice-T",
"id": 6006,
"lastfm_tags": [
"Hip-Hop",
"rap",
"old school",
"west coast",
"80s"
],
"name": "6 'N The Mornin'",
"preview_url": "https://p.scdn.co/mp3-preview/0a4e9b835553a99d1b1a4934443fecc1d3a24dd2?cid=0c0bb28de56d49d3b925f9755a289113",
"score": 1.3642083864505747,
"spotify_id": "2cBOh97kgDenDOdtKhwU9O"
},
{
"artist": "Schoolly D",
"id": 6010,
"lastfm_tags": [
"hip hop",
"breakbeat",
"questions",
"title is a full sentence",
"cold case"
],
"name": "P.S.K. 'What Does It Mean'?",
"preview_url": "https://p.scdn.co/mp3-preview/7f2c402a4d8d53524f4b01a7db9dc41955461e92?cid=0c0bb28de56d49d3b925f9755a289113",
"score": 1.3642083864505747,
"spotify_id": "3StKzbpR9dRZB8epDx4KDW"
}
],
"playlist": {
"spotify_id": "4PDd58PluSP0lnach9fXX3",
"url": "https://open.spotify.com/user/6faqhxu4ww7isy9sr96j3o116/playlist/4PDd58PluSP0lnach9fXX3"
},
"seed_info": {
"artist": "De La Soul",
"id": 6008,
"lastfm_tags": [
"Hip-Hop",
"hip hop",
"old school",
"rap",
"80s"
],
"name": "Me, Myself And I",
"preview_url": null,
"spotify_id": "30UTvW5IQWXmvdcZ1zbF6R"
}
}
Query Parameters:
· spotify_id – Spotify id of the track
· n – Number of results. Max 10. Default 10.
· with_spotify_seed – If with_spotify_seed arg specified, the api queries the spotify seed recommendation endpoint. If it finds tracks that we have in the database:
1. Boosts score of possible common tracks from the graph suggestions
2. Returns seed_spotify_recommendations items that we have in the database with a max of 20 tracks found.
· with_k_neighbors – If with_k_neighbors arg specified, the api queries the k_neighbors model created from spotify track features:
1. Boosts score of possible common tracks from the graph suggestions
2. Returns k_neighbors_recommendations items that we have in the database with a max of 20 tracks found.
Request Headers:
· Accept – application/json
Response Headers:
· Content-Type – application/json
Status Codes:
· 200 OK – no error
· 400 Bad Request – bad request (e.g. wrong request accept type)
· 429 Too Many Requests – exceeded rate limit of 5 requests per minute
1 Basic configurations on Linux server
# Logged in as root
# Update the system
apt-get update
apt-get upgrade
# Configure locale related settings (to remove locale warnings):
export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
locale-gen en_US.UTF-8
dpkg-reconfigure locales
# Add, configure new user and login as him
adduser playlistapi
usermod -aG sudo playlistapi
su - playlistapi
# Configure firewall
sudo apt-get install -y ufw
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo ufw status
2 Install and Configure Postgres
# Update and install necessary software
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib
# Login as postgres and configure the db. Then exit back to previous user
sudo -i -u postgres
createdb playlist_api
createdb test_database # For testing reasons
psql
alter user postgres password 'YOUR POSTGRES PASS';
\q
exit
3 Install and Configure Elasticsearch
# Install java related requirements
sudo apt-get update
sudo apt-get install default-jre
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer
sudo apt-get update
# Download and Install current elastic (See current version here: https://www.elastic.co/downloads/elasticsearch )
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.3.deb
sudo dpkg -i elasticsearch-6.2.3.deb
# Configure
sudo nano /etc/elasticsearch/elasticsearch.yml
Change: network.host: 0.0.0.0
sudo systemctl enable elasticsearch.service
sudo systemctl start elasticsearch
# Test if it works. (If not see below)
curl -X GET 'http://localhost:9200'
# If error, check memory of the server. Change it to appropriate level following the steps below
sudo service elasticsearch status
sudo nano /etc/elasticsearch/jvm.options
(Change the size of the storage https://stackoverflow.com/questions/31677563/connection-refused-error-on-elastic-search)
e.g.
-Xms1g --> -Xms128m
-Xms1g --> -Xmx128m
sudo systemctl restart elasticsearch
4 Install and Configure the Project
# Clone the project from bitbucket
cd /home/playlistapi
git clone https://stavros0x00@bitbucket.org/stavros0x00/playlist_api.git
# Install python 3.6 and related packages:
sudo add-apt-repository ppa:jonathonf/python-3.6
sudo apt-get update
sudo apt-get install build-essential python3-dev python3.6 python3.6-dev python3-setuptools python-dev graphviz libgraphviz-dev pkg-config python-pygraphviz python3-distutils
# Install pipenv and needed python packages for the project
sudo apt-get install python3-pip
sudo pip3 install pipenv
cd /home/playlistapi/playlist_api
pipenv install
# Needed Environment keys in an .env file
# Create .env file in /home/playlistapi/playlist_api with the env variables below
* FLASK_APP=run.py
* SECRET_KEY=(YOUR APP SECRET KEY HERE)
* DATABASE_URL=postgresql://postgres:{YOUR POSTGRES PASS}@localhost:5432/playlist_api
* TEST_DATABASE_URL=postgresql://postgres:{YOUR POSTGRES PASS}@localhost:5432/test_database
* ELASTICSEARCH_URI=http://localhost:9200
* SENTRY_KEY= (optional)
* SPOTIPY_CLIENT_ID= (https://developer.spotify.com/dashboard/)
* SPOTIPY_CLIENT_SECRET= (https://developer.spotify.com/dashboard/)
* LAST_FM_API_KEY= (https://www.last.fm/api/authentication)
* LAST_FM_SHARED_SECRET= (https://www.last.fm/api/authentication)
* MAIL_USERNAME= (optional, for connecting to gmail server)
* MAIL_PASSWORD= (optional, for connecting to gmail server)
* NOTIFICATIONS_EMAIL= (optional, your email for notifications)
* SENDER_EMAIL= (optional, from who to send email)
# Run the virtual environment. And populate the database creating the schema and running the necessary scripts.
pipenv shell
flask db upgrade
mkdir /home/playlistapi/playlist_api/api/pickled_files/
python scripts/crawl_playlists.py
python scripts/sync_db_elastic.py
# Configure uwsgi
touch playlist_api.sock
touch uwsgi.log
echo '[uwsgi]
module = run:app
master = true
processes = 5
socket = playlist_api.sock
chmod-socket = 660
vacuum = true
logto = /home/playlistapi/playlist_api/uwsgi.log
for-readline = /home/playlistapi/playlist_api/.env
env = %(_)
endfor =
enable-threads = true
die-on-term = true' > playlist_api.ini
sudo nano /etc/systemd/system/playlist_api.service
(Copy the below lines in the created file and save)
(Where the lines for the virtual environment, replace with the location of yours)
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
[Service]
User=playlistapi
Group=www-data
WorkingDirectory=/home/playlistapi/playlist_api
Environment="PATH=/home/playlistapi/.local/share/virtualenvs/playlist_api-KjQVwPM-/bin"
ExecStart=/home/playlistapi/.local/share/virtualenvs/playlist_api-KjQVwPM-/bin/uwsgi --ini playlist_api.ini
[Install]
WantedBy=multi-user.target
sudo systemctl start playlist_api
sudo systemctl enable playlist_api
sudo systemctl restart playlist_api
5 Install and Configure the Nginx Server
# Install nginx
sudo apt-get update
sudo apt-get install nginx
# Configure nginx
sudo nano /etc/nginx/sites-available/playlist_api
(Copy the below lines in the created file and save)
(Replace the server_domain_or_IP with appropriate ip or hostname)
server {
listen 80;
server_name server_domain_or_IP;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/playlistapi/playlist_api/playlist_api.sock;
}
}
sudo ln -s /etc/nginx/sites-available/playlist_api /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx
sudo ufw allow 'Nginx Full'