Festival Coding
- Skylar Castator
- Jun 21, 2023
- 7 min read
Updated: Jun 21, 2023

While I travel I find I always have ideas for fun projects to do optimizations or figure out fun problems. A few weekends ago, I was at EDC (Electric Daisy Carnival) a large electronic music festival. To explain how big it is, it has 9 different stages and around 230 artists giving shows.
I've heard of a few of these musicians, but if you are anything like me, I usually let Spotify suggest different artist and add them to playlists without paying attention to a lot of the details. I started to look through the lists and try to play through the official EDC playlist, but I could spend hours doing that and still not know exactly who to see when.
I was talking to my friends about the website for the event and how they could improve the experience for their users. I start describing an application that can scrape my activity of different people I've liked in the past and figure out the best schedule for the festival... So there I was the evening of the first show I started to make this tool and had a list of artist before the first night that worked for me and my friends.
This blog post describes the process of making the application and how you too can start linking up festivals to the application for future use.
The GitHub project can be found at the link below:
I'm also hosting the project on Streamlit found at the link below:
Spotify

Connecting to the API
Spotify has a great Rest-API that is easy to link up to. When I script in python, I usually make a class to manage an API in a single object. I do this so I can make different functions for each Spotify API call without having to always retrieve the authorization information. More information of the API can be found below: https://developer.spotify.com/documentation/web-api
import requests
class SpotifyManager: def __init__(self, client_id, client_secret): auth_url = 'https://accounts.spotify.com/api/token' auth_response = requests.post(auth_url, { 'grant_type': 'client_credentials', 'client_id': client_id, 'client_secret': client_secret }) auth_data = auth_response.json() self.access_token = auth_data['access_token'] self.headers = { 'Authorization': f'Bearer {self.access_token}', 'Content-Type': 'application/json' } print ("Connected to spotify")
These lines provide the initialization of the API and retrieves the auth tokens to be able to access the API in the class's different function calls. What you will also see is that I initialize the class itself by passing in the credentials for the application. On the application I'm hosting, I pass these parameters in, but if you were to write the code yourself, you would need to create an account and developer application with Spotify. One of the other things to mention here is I'm doing raw requests to Spotify in this project and not using an python library. This was a personal choice. I wanted more control of the system and honestly its better to just understand the underlying communication that goes on.
Connecting to User Playlists
The next step is to connect to Spotify and getting data for my account. I found the API call only requires a username and then I just pass that in to the code below which will connect the headers to its parent class we made above.
def find_playlists(self, username): """ Returns a list of playlist from a user :param username: Name of user searched """ playlist_url = f'https://api.spotify.com/v1/users/{username}/playlists' playlist_response = requests.get(playlist_url, headers=self.headers) playlist_data = playlist_response.json() return playlist_data['items']
Searching For Artist
Once we got the list of playlist names, we can now iterate through each playlist looking for artist data. At this point I needed to start collecting data for the show and find out which artist I show scrap my account for. I will go into more detail on how I managed the festival data below but to give a rough Idea on how I was able to start testing getting artist data these are some example code snippet.
playlist_tracks_url = f'https://api.spotify.com/v1/playlists/{playlist["id"]}/tracks' playlist_tracks_response = requests.get(playlist_tracks_url, headers=self.headers) playlist_tracks_data = playlist_tracks_response.json() for track in playlist_tracks_data['items']: track_artists = [artist['name'] for artist in track['track']['artists']] for artist in artists_to_search: if artist in track_artists: artist_data[artist].append(track['track']['name'])
In the code above, I get the playlist tracks and then iterate over all of them to collect all of the artists in the playlist. Next the artists_to_search variable is a list of artist from the festival. I check if the name match the artist from the festival to the playlist and create a list of artist and the tracks my playlist contains. (Note this is yet to be optimized. If I created a hash-table/dictionary of the artist in the playlist, I could actually search much faster verse iteration over the lists.)

Now we have collected the data from Spotify, lets start looking at the data management system for the festival planner.
Festival Data
JSON Data
The JSON snippet below is an example of how I managing the information for the festival.
{
"name": "EDC (Electric Daisy Carnival)",
"year": "2023",
"date": "May 19, 2023 – May 21, 2023",
"description": "Electric Daisy Carnival, commonly known as EDC, is an electronic dance music festival organized by promoter and distributor Insomniac. The annual flagship event, EDC Las Vegas, is held in May at the Las Vegas Motor Speedway, and is currently the largest electronic dance music festival in North America.",
"image_url": "https://d3vhc53cl8e8km.cloudfront.net/hello-staging/wp-content/uploads/sites/21/2023/05/24095051/edclv_2024_mk_te_fest_site_seo_1200x630_r02.jpg",
"map_image_url": "https://www.edmtunes.com/wp-content/uploads/2023/05/image-14.png",
"line_ups": [
{
"date": "May 19, 2023",
"start-time": "07:00 PM",
"end-time": "05:30 AM",
"shows": {
"Galantis": {
"start-time": "4:24 AM",
"end-time": "5:28 AM",
"stage": "Kinetic Field"
},
}
}]
}
JSON References
The JSON above is read into my Streamlit application shown at the beginning of the blog post. Each of the parameters is used to introduce the festival and can be changed out for different festivals in the future.
'name': Name of the festival, this is used in my Streamlit example to show information about the festival
'year': This is the year of the festival
'date': Date of the festival
'description': This is a overall description of the festival
'image_url': This contains an image for the show to be displayed.
'map_image_url': Contains a map of the festival for easy use.
The next sector is associated to the shows themselves. The 'line_ups' variable is used to maintain a list of each day of the show and its consecutive data.
For each day of the show it contains this information: 'date': This is the date of the lineup. This is used to help identify the lineup object with the correct date.
'start_time': This is the start time of that date.
'end_time': This is the end time of that date.
'shows': This is a dictionary of artist and their show data. Inside of the 'shows' dictionary you will find the artist data. The data is managed by the key of the artist name. This speeds up the search process in the dictionary so that it runs in O(n) time for searching. The artist data currently includes:
'start_time': Start of the set time.
'end_time': End of the set time.
'stage': The stage the artist is performing at.
Uploading A Festival
With the information above you can fill in concert details for your own festivals. This can be quite time intensive process but there are some tricks I used to speed up the process. When I first started to collect the data I was trying to scrape the entire EDC lineup webpage and then fill in the JSON myself. I found doing this an hour or 2 before leaving to be difficult and frustrating against the time schedule.
The solution I came up with was to use ChatGPT. I was able to get a text for a days line up and then teach ChatGPT to organize the data as I felt fit.
This is an example of the data I used:
Kinetic Field
Kaskade Redux 04:16 AM - 05:28 AM
SLANDER 03:03 AM - 04:13 AM
Armin van Buuren 01:45 AM - 03:00 AM
Fireworks 01:39 AM - 01:45 AM
Martin Garrix 12:29 AM - 01:39 AM
Loud Luxury 11:19 PM - 12:24 AM
Gareth Emery 10:16 PM - 11:16 PM
Dombresky 09:05 PM - 10:10 PM
Ship Wrek 08:00 PM - 09:05 PM
Marten Hørger 07:00 PM - 08:00 PM
Once I taught ChatGPT to organize the JSON for me I just put in all the shows and organized them into the line-up dates.
Making the Planner
Now we have the festival data and the Spotify user information, I can now use it to figure out my optimal schedule.

Based on my Spotify playlist, I was able to organize a list of each artist I listened to and then made a table of which artist was playing on a particular date. This worked out pretty well until I realized I had several conflicting shows of people I wanted to see. then they were all in one table I had to sort the shows in my head and figure out which shows had conflicts, instead I wanted my code to solve for this so what I did was a simple 2 pointer algorithm to sort which shows intersected with each other.
def sort_artist_conflicts(self, artists_dict):
"""
From the list of artist in the user's playlist, find the available shows and organize
them into a schedule.
:param artists_dict: Artist in playlist
"""
artists_start_times = [(artist, details['start-time'], details['end-time'], details['stage']) for
artist, details in artists_dict.items()]
artists_start_times.sort(key=lambda x: (x[1], x[2]))
recommended_artists = []
conflicting_artist = []
conflicts = {}
for p1 in range(len(artists_start_times)):
for p2 in range(p1+1, len(artists_start_times)):
if self.check_conflicts(artists_start_times[p1], artists_start_times[p2]):
if artists_start_times[p1][0] not in conflicts:
conflicts[artists_start_times[p1][0]] = artists_start_times
if artists_start_times[p2][0] not in conflicts:
conflicts[artists_start_times[p2][0]] = artists_start_times
for artist, start_time, end_time, stage in artists_start_times:
if artist in conflicts:
conflicting_artist.append((artist, start_time, end_time, stage))
else:
recommended_artists.append((artist, start_time, end_time, stage))
return recommended_artists, conflicting_artist
The code above just does a quick search through the array to find conflicting shows and appends a dictionary. (I chose a dictionary because (1) I could quickly search for already conflicting artist (2) Later I plan to show all conflicting shows for a given artist and can use linear solving to optimize search times) Once its found all conflicts I send them out to arrays with the information for each show to be shown in the tables above.
Conclusion
The project was a fun experiment to make in a single weekend. I wanted to share the code with people so I took some extra time to move over into Streamlit so anyone could run their own playlists and festival data without having to set up their own programming environment. Reach out if you have any questions about the project and feel free to make bug reports or PRs for the project. I plan to update the blog and code as things get fixed and are improved so stay tuned!
Current bugs in project:
Festival JSON is not updating the Streamlit page data.
Finish implementing Linear Solver for schedule.
Issues with cached data from Streamlit interfering showing other user's accounts.