From 1fef60807441d2b555b9446912201cfe1db8804f Mon Sep 17 00:00:00 2001 From: Devika Date: Tue, 20 May 2025 14:56:54 +0200 Subject: [PATCH] lab solved --- lab-apissolved.ipynb | 566 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 566 insertions(+) create mode 100644 lab-apissolved.ipynb diff --git a/lab-apissolved.ipynb b/lab-apissolved.ipynb new file mode 100644 index 0000000..e923554 --- /dev/null +++ b/lab-apissolved.ipynb @@ -0,0 +1,566 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "27422808-8a16-4be1-897f-57b379af8991", + "metadata": {}, + "source": [ + "# Lab | APIs" + ] + }, + { + "cell_type": "markdown", + "id": "50f30950-3e31-499a-92ea-1535422c570b", + "metadata": {}, + "source": [ + "In order to use the `Spotify` API (`SpotiPy`), create an account in `Spotify` and follow [these](https://developer.spotify.com/documentation/general/guides/app-settings/) steps. " + ] + }, + { + "cell_type": "markdown", + "id": "a0479b95-6ca5-415e-b894-1f5cb17b055b", + "metadata": {}, + "source": [ + "## Authentication and initializing the API" + ] + }, + { + "cell_type": "markdown", + "id": "47d71611-c617-4972-a0c3-7090c24b399c", + "metadata": {}, + "source": [ + "Save your client ID and your client secret in your preferred way, and read it or load it into the following variables:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea44c82a-5c07-4dbc-beb2-bba2601bb75e", + "metadata": {}, + "outputs": [], + "source": [ + "CLIENT_ID = \"\"\n", + "CLIENT_SECRET = \"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "319cfd4e-f6fb-4419-80e0-e3983cd25e43", + "metadata": {}, + "outputs": [], + "source": [ + "CLIENT_ID = \"4109b2d9f5014671863bb2df1d1fbdd3\"\n", + "CLIENT_SECRET = \"5cb719fae80c4191a9c0b288f51bfe50\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04e12954-fd70-4311-88a5-fb7e2c29799c", + "metadata": {}, + "outputs": [], + "source": [ + "# If you havent done so, install the spotipy wrapper\n", + "!pip install spotipy" + ] + }, + { + "cell_type": "markdown", + "id": "dc0e86da-8846-4207-84c3-cd20b9e01d0e", + "metadata": {}, + "source": [ + "Once you have done it, we will start initializing the API." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "03034bc6-9858-412a-83b7-18abdc345d7e", + "metadata": {}, + "outputs": [], + "source": [ + "import spotipy\n", + "from spotipy.oauth2 import SpotifyClientCredentials\n", + "\n", + "#Initialize SpotiPy with user credentials\n", + "sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials(client_id=CLIENT_ID,\n", + " client_secret=CLIENT_SECRET))\n" + ] + }, + { + "cell_type": "markdown", + "id": "8fed9628-08d7-4290-a4be-5527696b01c5", + "metadata": {}, + "source": [ + "## Using the search method" + ] + }, + { + "cell_type": "markdown", + "id": "6575a3c6-f25a-4905-b1f3-c0efd50dcc1e", + "metadata": {}, + "source": [ + "Now, let's use the search method by introducing a \"query\". For example, let's try searching for \"Lady Gaga\":" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7772a1e0-9692-4d04-a590-76111a272d8d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "results = sp.search(q='Lady Gaga', limit=50)\n", + "results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "edc14c95-474b-4e2a-aea3-bdfd0a205546", + "metadata": {}, + "outputs": [], + "source": [ + "results.keys() # We can see that we only have tracks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad8ef934-1dbb-4008-ac8e-f5c29823fe6a", + "metadata": {}, + "outputs": [], + "source": [ + "results[\"tracks\"].keys() # Let's check the values" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "004b7814-4dd5-408e-b7ba-1da87f9250cb", + "metadata": {}, + "outputs": [], + "source": [ + "results[\"tracks\"][\"href\"] # Query we have searched " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7285cedd-fbe1-47cf-98d5-a7fdc3e5c8b8", + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [], + "source": [ + "results[\"tracks\"][\"items\"] #items (actual tracks)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "529fff56-47d3-4d78-8ff5-9530fe290d1d", + "metadata": {}, + "outputs": [], + "source": [ + "results[\"tracks\"][\"limit\"]#Limit we have chosen" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92c64c57-3bd2-4d42-bbd1-84a040f1e02a", + "metadata": {}, + "outputs": [], + "source": [ + "results[\"tracks\"][\"next\"] #link to the next page (next 50 tracks)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f5ccdf79-5d9e-40de-adb9-2cc1e5b7c74a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "results[\"tracks\"][\"offset\"] # Actual offset (starting point)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "356730c1-60a2-4ea8-bd2c-e0522bab8a4d", + "metadata": {}, + "outputs": [], + "source": [ + "results[\"tracks\"][\"previous\"] #Previous search" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c44c8fd-63ea-45ba-94bd-5c5e8e1458b3", + "metadata": {}, + "outputs": [], + "source": [ + "results[\"tracks\"][\"total\"] # Number of matches" + ] + }, + { + "cell_type": "markdown", + "id": "7a127c64-3274-4ecc-aa0f-83ae34af4655", + "metadata": {}, + "source": [ + "## Exploring the tracks" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c3541a2-0fd2-41e0-9b27-60a7dc36c4cb", + "metadata": { + "scrolled": true, + "tags": [] + }, + "outputs": [], + "source": [ + "results[\"tracks\"][\"items\"][0] # Explore the first song" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2c35eb2-3ea6-4329-9f29-7c062f466638", + "metadata": {}, + "outputs": [], + "source": [ + "results[\"tracks\"][\"items\"][0].keys() # We will focus on album, artists, id, name, popularity, type and uri" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "889ca3c3-b0c8-4037-96fb-6add847f537f", + "metadata": {}, + "outputs": [], + "source": [ + "# Track artists\n", + "results[\"tracks\"][\"items\"][0][\"artists\"] " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9c6a0b2-cea7-48ff-8c51-179d15388aa2", + "metadata": {}, + "outputs": [], + "source": [ + "# Track artists names\n", + "for artist in results[\"tracks\"][\"items\"][0][\"artists\"]:\n", + " print(artist[\"name\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6a826e9c-d2e7-4537-a82c-3dc3a2b80b9f", + "metadata": {}, + "outputs": [], + "source": [ + "# Track ID\n", + "results[\"tracks\"][\"items\"][0][\"id\"] " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a5bd871b-6087-4680-819c-1a1d8ba879bc", + "metadata": {}, + "outputs": [], + "source": [ + "# Track name\n", + "results[\"tracks\"][\"items\"][0][\"name\"] " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "812661f1-29db-452f-a719-cdfbe95ba9f6", + "metadata": {}, + "outputs": [], + "source": [ + "# Popularity index\n", + "results[\"tracks\"][\"items\"][0][\"popularity\"] " + ] + }, + { + "cell_type": "markdown", + "id": "0e81c762-e6c5-424e-a4eb-12ab45dffb9f", + "metadata": {}, + "source": [ + "Spotify songs are identified by either a \"url\", a \"uri\", or an \"id\". \n", + "\n", + "- The `id` is an alphanumeric code, and it's the nuclear part of the identifier.\n", + "\n", + "- The `uri` contains \"spotify:track\" before the id. An uri is useful because it can be searched manually in the Spotify app.\n", + "\n", + "- The `url` is a link to the song on the Spotify web player.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8bcdccfc-dde9-4f4b-8af5-3caa335b89b5", + "metadata": {}, + "outputs": [], + "source": [ + "results[\"tracks\"][\"items\"][0][\"uri\"]" + ] + }, + { + "cell_type": "markdown", + "id": "71c3c9c1-4ec2-42bf-a243-b21105ae1699", + "metadata": {}, + "source": [ + "## Exercise 1: Discovering New Music through Your Favorite Artists\n", + "\n", + "**Objective:** \n", + "Uncover new music by exploring the top tracks of your favorite artists and their related artists.\n", + "\n", + "**Instructions:**\n", + "\n", + "1. **List Your Favorite Artists**:\n", + " - Make a list of your three favorite artists and store it in a variable named `artists`.\n", + " - Example: `artists = [\"Los Fabulosos Cadillacs\", \"Manu Chao\", \"Muchachito Bombo Infierno\"]`.\n", + "\n", + "2. **Fetch Top Tracks**:\n", + " - Write a function named `get_top_tracks`.\n", + " - This function should accept an artist's name and return the name of the first 5 top tracks by that artist.\n", + " - Use the function `get_top_tracks` to get the first 5 top tracks for each artist in your `artists` list and store the results in a new list named `top_tracks_list`.\n", + "\n", + "3. **Discover Related Artists**:\n", + " - Write a function named `find_related_artists`.\n", + " - This function should accept an artist's name and return the names of the first 5 artists related to the provided artist.\n", + " - Store the results in a list named `related_artists_list`.\n", + "\n", + "**Challenge:** \n", + "Combine the above steps to create a playlist that includes the top tracks of your favorite artists and the top tracks of the artists related to them." + ] + }, + { + "cell_type": "markdown", + "id": "0c442378-e26f-47c8-b4f1-b4fa07089935", + "metadata": {}, + "source": [ + "**Hint Section for 3. **Discover Related Artists**:**\n", + "\n", + "1. **Getting Artist ID**:\n", + " - Remember that every artist on Spotify has a unique identifier: their `id`. To get the related artists, you first need to fetch the ID of the given artist.\n", + " - Consider using the `sp.search` method to query the artist's name. The method requires a `q` parameter, which is your query (in this case, the artist's name). It also has a `limit` parameter, which specifies the number of tracks it returns. In this case, 1 track is enough, since we just want the artist ID. \n", + " - Each track in the results has an associated 'artists' field. This field is a list containing details about all artists involved in that track.\n", + " - For most tracks, especially those by a single artist, this list will contain one artist. From this artist's details, you can extract the 'id' field, which is the unique identifier for that artist on Spotify.\n", + "\n", + "\n", + "3. **Fetching Related Artists**:\n", + " - Once you have the artist's ID, you can use another SpotiPy method to fetch related artists. Think about which SpotiPy method allows you to get related artists using an artist's ID. Here is the documentation link: https://spotipy.readthedocs.io/en/2.22.1/. \n", + " - This method will return a list of related artists. You'll need to extract the relevant details (artist names) from this list.\n", + "\n", + "4. **Iterating for Multiple Artists**:\n", + " - Once you have a function that returns related artists names for one artist, you can use a list comprehension to apply this function to a list of artist names.\n", + "\n", + "5. **Testing**:\n", + " - Always test your function with one artist name first. Once you're confident it works, then apply it to the entire list.\n", + "\n", + "Remember, the key is to break the problem down into manageable steps. Use the SpotiPy documentation as a resource to understand available methods and their return structures." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29694252-f217-454d-8881-681b2b6eeb1e", + "metadata": {}, + "outputs": [], + "source": [ + "# Your answer here" + ] + }, + { + "cell_type": "markdown", + "id": "94ad5fdc-22e5-4521-8aa1-c6833eb7e949", + "metadata": {}, + "source": [ + "## Playlists\n", + "\n", + "The `sp.featured_playlists()` method in `spotipy` fetches a list of Spotify's featured playlists at a given moment. These are curated playlists that Spotify often highlights on the platform's homepage. The method provides a snapshot of the playlists that are being promoted or featured by Spotify at the time of the request.\n", + "\n", + "Once you've fetched the featured playlists, you can extract their IDs (and other details)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25fb0cf8-c13a-41b0-b8f8-7e0700fd1e41", + "metadata": {}, + "outputs": [], + "source": [ + "sp.featured_playlists() # We get a playlist id of a playlist we like" + ] + }, + { + "cell_type": "markdown", + "id": "90f558f3-c638-4df4-b5a4-e24f7847d52a", + "metadata": {}, + "source": [ + "### Getting a Playlist's Details\n", + "To fetch details about a specific playlist, you can use the playlist method. You'll need the playlist's Spotify ID." + ] + }, + { + "cell_type": "markdown", + "id": "0eef529f-617f-4ea3-8156-07472ac8e6d5", + "metadata": {}, + "source": [ + "In this example, we will use the following playlist id: *37i9dQZF1DXd9zR7tdziuQ*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "46d35121-9256-4cf4-81f5-118b87f7af32", + "metadata": {}, + "outputs": [], + "source": [ + "playlist_id = \"37i9dQZF1DXd9zR7tdziuQ\"\n", + "playlist = sp.playlist(playlist_id)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5260f67f-6024-4fee-8449-30904f03bf76", + "metadata": {}, + "outputs": [], + "source": [ + "print(playlist['name']) # Print the playlist's name\n", + "print(playlist['description']) # Print the playlist's description" + ] + }, + { + "cell_type": "markdown", + "id": "13bc8631-69f0-4b98-9cc9-5baecbaea9ba", + "metadata": {}, + "source": [ + "### Getting Tracks from a Playlist\n", + "If you want to get the tracks from a specific playlist, you can use the playlist_tracks method." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "69c78f8d-7e6a-4d15-bcbb-fc93edb82433", + "metadata": {}, + "outputs": [], + "source": [ + "tracks = sp.playlist_tracks(playlist_id)\n", + "for track in tracks['items']:\n", + " print(track['track']['name']) # Print each track's name" + ] + }, + { + "cell_type": "markdown", + "id": "2775714d-acc7-4555-96bd-2c541ab0855e", + "metadata": {}, + "source": [ + "### Getting Artists from a Playlist\n", + "\n", + "To extract all the artists from the tracks in a playlist, you'd typically follow these steps:\n", + "\n", + "1. Fetch the playlist's tracks.\n", + "2. Iterate through each track.\n", + "3. For each track, extract the associated artists." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65c5e5c4-f186-42c6-b136-4ef02b0b01ff", + "metadata": {}, + "outputs": [], + "source": [ + "# List to store unique artist names\n", + "artists_list = []\n", + "\n", + "for track_item in tracks['items']:\n", + " track = track_item['track']\n", + " for artist in track['artists']:\n", + " artist_name = artist['name']\n", + " if artist_name not in artists_list: # This ensures each artist is added only once\n", + " artists_list.append(artist_name)\n", + "\n", + "print(artists_list)" + ] + }, + { + "cell_type": "markdown", + "id": "7b52207e-a4f0-4f90-9f4e-3170d7f0f3fe", + "metadata": {}, + "source": [ + "## Exercise 2: Unraveling the World of Playlists\n", + "\n", + "\n", + "1. **Featured Exploration**: \n", + " - Fetch the list of Spotify's current featured playlists. \n", + " - Extract and display the names and IDs of the top 5 featured playlists.\n", + " \n", + "2. **Deep Dive**:\n", + " - Choose any one of the top 5 featured playlists (you can choose the one you personally find most interesting or simply pick one randomly).\n", + " - Fetch and display its name, description, and total track count.\n", + "\n", + "3. **Track-tastic**:\n", + " - Extract and display the names of the first 10 tracks in the chosen playlist.\n", + "\n", + "4. **Artistic Flair**:\n", + " - Create a dictionary where the keys are the names of the first 10 tracks, and the values are lists containing the names of the artists associated with each track.\n", + " - For example: `{\"TrackName1\": [\"Artist1\", \"Artist2\"], \"TrackName2\": [\"Artist3\"]}`\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ed92d961-9646-4375-a386-ccc320a958f5", + "metadata": {}, + "outputs": [], + "source": [ + "# Your answer here" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}