Create listening experiences for collections of songs, based on their relationships as/to samples.
- SAMPLIFY: The Sun Rises In The East
- SAMPLIFY: Lyricist Lounge Volume 2
- SAMPLIFY: Illmatic XX
- SAMPLIFY: Section 80
- SAMPLIFY: good kid, m.A.A.d city (deluxe)
Setup TLDR;
git clone https://github.com/qzdl/samplify.git && cd samplify && venv samplify && source samplify/bin/activate && pip -r requirements.txt - Ensure you are running python3 with venv
- Clone this repo with
git clone https://github.com/qzdl/samplify.git cdto the new directory, and create a new virtual environment withvenv samplify- Run
source samplify/bin/activateto activate the new environment. - Install the dependencies with
pip install -r requirements.txt- Refer to
requirements.txtfor a list of packages
- Refer to
If you haven't used the spotify API before:
- Head to the developer dashboard and register a new application
- Setup a redirect as
http://localhost:<SOME_FREE_PORT>- This can be found in the information page of a registered application > edit settings.
- Create
config.pyat the root of the repository, and populate it as follows: (NOTE: these are not valid credentials )
# ClientID from registered application at: # https://developers.spotify.com/dashboard/applications client = '7bf224e8jn954215s3g11degh599e3an' # Client Secret can be found below 'SHOW CLIENT SECRET' once you are on the info # page of a registered application secret = '7bf224e8jn954215s3g11degh599e3an' # The easiest way I've found to get this is to hit the /v1/me endpoint: # https://developer.spotify.com/console/get-current-user/ # find the "uri" property, e.g. "uri": "spotify:user:1134745600" username = '1134745600' # setup this redirect on a registered application. make sure it # is identical to the letter or you'll get "INVALID REDIRECT" redirect = 'http://localhost:8889'Detail about the CLI can be found by reading the documentation provided by the --help option flag. Documentation will but updated there as the project progresses.
(samplify) [samuel@qzdl spotify-samples]$ python samplify.py usage: samplify.py [-h] (-l LINK | -s SEARCH) (--album | --playlist | --song | --current-song) [--direction DIRECTION] [--output-name OUTPUT_NAME] [--output-type OUTPUT_TYPE] [--username USERNAME] samplify.py: error: one of the arguments -l/--link -s/--search is required(samplify) [samuel@qzdl spotify-samples]$ python samplify.py --help usage: samplify.py [-h] (-l LINK | -s SEARCH) (--album | --playlist | --song | --current-song) [--direction DIRECTION] [--output-name OUTPUT_NAME] [--output-type OUTPUT_TYPE] [--username USERNAME] optional arguments: -h, --help show this help message and exit -l LINK, --link LINK Click "Share" > "Copy Link" -s SEARCH, --search SEARCH Search as you would in the app --album --playlist --song --current-song --direction DIRECTION --output-name OUTPUT_NAME --output-type OUTPUT_TYPE --username USERNAME(samplify) [samuel@qzdl spotify-samples]$ python samplify.py --search 'uptown saturday night camp lo' --album # SAMPLIFY: Uptown Saturday Night This playlist was generated using Samplify. GitHub: https://github.com/qzdl/samplify The album, Uptown Saturday Night, has been broken down into: "contains samples of " Percentage Matched: 81.8% Songs with no match: Black Connection -> Love Is the Answer, by Van McCoy and The Soul City Symphony Sparkle - Mr. Midnight Mix -> Leyte (Live at the Funky Quarters), by Cal Tjader ==> search terms: Love Is the Answer van mccoy soul city symphony Leyte (Live at the Funky Quarters) cal tjader Sample Info: Luchini AKA This Is It -> Adventures in the Land of Music, by Dynasty Park Joint -> September 13, by Deodato Sparkle -> Leyte, by Cal Tjader Rockin' It AKA Spanish Harlem -> A Little Spice, by Loose Ends Rockin' It AKA Spanish Harlem -> Rockin' It, by The Fearless Four Rockin' It AKA Spanish Harlem -> The Bridge, by MC Shan Black Nostaljack AKA Come On -> Tripping Out, by Curtis Mayfield Coolie High -> Funny How Time Flies (When You're Having Fun), by Janet Jackson Coolie High -> It's a New Day, by Skull Snaps ==> search terms: Adventures in the Land of Music dynasty September 13 deodato Leyte cal tjader A Little Spice loose ends Rockin' It the fearless four The Bridge mc shan Tripping Out curtis mayfield Funny How Time Flies (When You're Having Fun) janet jackson It's a New Day skull snaps Created playlist SAMPLIFY: Uptown Saturday NightAribrary playlists, albums, and songs, are read from Spotify via a fork of spotipy. Song names and artists are stored and then located on Whosampled.com.
A request is sent to the site searching for the song name, selecting a result
with the matching artist name and storing the link to that song's page. A second
request is sent to that song page, and BeautifulSoup is used to scrape HTML for
sample details, while paging for >5 references to a category of a sample is recursively expanded in the scraper.
Next, the samples are located on Spotify, if they exist, by computing the Levenshtein distance between the a cleaned WhoSampled song title, and the top 10 search results - and choosing 'best match' - the highest ratio from this distance computation. Finally, a new playlist is created for the user, containing all the samples available on Spotify. These requests to add tracks are partioned to n requests, partitioned at 50, to side-skirt the rate-limiting imposed by Spotify's REST API for add-tracks-to-playlist.
Discovering how payloads differ to extend the functionality to albums, current song,
etc, is a process that requires some exploration. I'm sure there's examples of that
in the commit history.
album = None with open('test_payload_f.json', 'r') as f: import json album = json.loads(f.read()) album_ttle = album['name'] artist = album['artists'][0]['name'] tracks = album['tracks']['items'] track_info = [] for track in tracks: info = {} info['title'] = track['name'] info['uri'] = track['uri'] track_info.append(info) print(json.dumps(track_info, indent=2))This project is based on the work of Christopher Pease (cpease00)'s sample collection tool Spotify-Samples. Without his medium article on the topic, it would have been much more painful to produce the project as it is now.

