diff --git a/Spotify/Spotify_Get_User_Top_Items.ipynb b/Spotify/Spotify_Get_User_Top_Items.ipynb
new file mode 100644
index 0000000000..c193a33a71
--- /dev/null
+++ b/Spotify/Spotify_Get_User_Top_Items.ipynb
@@ -0,0 +1,262 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "17b6bb99-2896-4773-a017-93fcb6a9d09a",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "faadb329-be43-4b38-8295-79fee5d6ff55",
+ "metadata": {},
+ "source": [
+ "# Spotify - Get User Top Items\n",
+ "
Give Feedback | Bug report"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "447e14b0-90d5-47cb-857d-19db420905dc",
+ "metadata": {},
+ "source": [
+ "**Tags:** #spotify #api #gettopitems #webapi #reference #snippet"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "35d783ed-8b09-4418-8423-3822b2ff271e",
+ "metadata": {},
+ "source": [
+ "**Author:** [Alton Liew](https://www.linkedin.com/in/alton-liew-749944182/)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9dbe7032-188e-4889-b049-ae727732ddfe",
+ "metadata": {},
+ "source": [
+ "**Last update:** 2023-12-14 (Created: 2023-12-10)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ae3f7f8e-8789-4339-ab6c-63d36fd9c523",
+ "metadata": {},
+ "source": [
+ "**Description:** This notebook retrieve the current user's top artists or tracks based on calculated affinity."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b76e0005-5175-466b-b912-cbdfe7483e86",
+ "metadata": {},
+ "source": [
+ "**References:**\n",
+ "- [Spotify Web API Reference - Get User Top Items](https://developer.spotify.com/documentation/web-api/reference/get-users-top-artists-and-tracks)\n",
+ "- [Spotify Developer Documentation](https://developer.spotify.com/documentation/)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3528794c-6bcc-40ad-a836-5412656c4b08",
+ "metadata": {},
+ "source": [
+ "## Input"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c0d95abe-03ba-4161-8b16-e10c1a124807",
+ "metadata": {},
+ "source": [
+ "### Import libraries"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "595c14e7-69e4-4108-96aa-f6c2550080c9",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "try:\n",
+ " import spotipy\n",
+ "except:\n",
+ " !pip install spotipy --user --upgrade\n",
+ " import spotipy\n",
+ "from spotipy.oauth2 import SpotifyClientCredentials\n",
+ "import naas\n",
+ "from IPython.display import Image, display\n",
+ "from spotipy.oauth2 import SpotifyOAuth"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e2f967d0-4871-40de-93f8-09601653c85d",
+ "metadata": {},
+ "source": [
+ "### Setup variables\n",
+ "- `client_id`: Your Spotify API client ID. [Get your client ID](https://developer.spotify.com/documentation/general/guides/app-settings/#register-your-app)\n",
+ "- `client_secret`: Your Spotify API client secret. [Get your client secret](https://developer.spotify.com/documentation/general/guides/app-settings/#register-your-app)\n",
+ "- `redirect_uri`: Your Spotify API redirect uri. This redirects users to a uri for authentication. [Get your redirect uri](https://developer.spotify.com/documentation/general/guides/app-settings/#register-your-app)\n",
+ "- `limit`: The amount of results you want to see.\n",
+ "- `time_range`: Over what time frame are the affinities computed. Valid-values: `short_term`, `medium_term`, `long_term`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a85464c9-9731-4227-9597-ab45681a1452",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "client_id = \"YOUR_SPOTIFY_CLIENT_ID\"\n",
+ "client_secret = \"YOUR_SPOTIFY_CLIENT_SECRET\"\n",
+ "redirect_uri = \"YOUR_SPOTIFY_REDIRECT_URI\"\n",
+ "\n",
+ "limit = 5\n",
+ "time_range = \"medium_term\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dd3919f3-0c2c-4c2f-8914-b16d86c3dabe",
+ "metadata": {},
+ "source": [
+ "## Model"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "c974d949-274e-420f-be08-83f827f543e7",
+ "metadata": {},
+ "source": [
+ "### Get user top items\n",
+ "* Retrieve current logged in user's top items both tracks and artists.\n",
+ "* Authenticates the user by redirecting the user to the uri and user must then authorize and copy the code in the URL and paste in the input.\n",
+ "* Once user is authenticated, `fetch_top_items` can not print the top items."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "6a9e38d6-92a4-4891-8b5c-0a7135d9704a",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "def authenticate_spotify(client_id, client_secret, redirect_uri):\n",
+ " # Create a Spotify API client\n",
+ " sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope=\"user-library-read user-top-read\"))\n",
+ "\n",
+ " # Get the authorization URL\n",
+ " auth_url = sp.auth_manager.get_authorize_url()\n",
+ "\n",
+ " # Prompt the user to visit the authorization URL\n",
+ " print(f\"Please visit this URL to authorize the application: {auth_url}\")\n",
+ "\n",
+ " # Ask the user to input the authorization code\n",
+ " authorization_code = input(\"Enter the authorization code from the URL: \")\n",
+ "\n",
+ " # Exchange authorization code for access token\n",
+ " token_info = sp.auth_manager.get_access_token(authorization_code)\n",
+ "\n",
+ " # Check authentication status\n",
+ " if sp.auth_manager.get_cached_token() is not None:\n",
+ " print(\"Successfully authenticated\")\n",
+ " return sp # Return the Spotify client for further use\n",
+ " else:\n",
+ " print(\"Authentication failed\")\n",
+ " return None\n",
+ " \n",
+ "def fetch_top_items(sp, limit, time_range):\n",
+ " try:\n",
+ " # Top tracks\n",
+ " print(\"\\nTop tracks:\")\n",
+ " top_tracks = sp.current_user_top_tracks(limit=limit, time_range=time_range)\n",
+ " for idx, track in enumerate(top_tracks['items'], 1):\n",
+ " print(f\"{idx}. {track['name']} by {track['artists'][0]['name']}, Track ID: {track['id']}\")\n",
+ " display(Image(url=track['album']['images'][0]['url'], width=200))\n",
+ " print(\"\\n\")\n",
+ " \n",
+ " # Top artists\n",
+ " print(\"\\nTop artists:\")\n",
+ " top_artists = sp.current_user_top_artists(limit=limit, time_range=time_range)\n",
+ " for idx, artist in enumerate(top_artists['items'], 1):\n",
+ " print(f\"{idx}. {artist['name']}, Artist ID: {artist['id']}\")\n",
+ " display(Image(url=artist['images'][0]['url'], width=200))\n",
+ " print(\"\\n\")\n",
+ "\n",
+ " except spotipy.SpotifyException as e:\n",
+ " print(f\"Spotify API error: {e}\")\n",
+ " except Exception as e:\n",
+ " print(f\"Error: {e}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "56d206d2-4a85-4125-938f-842928cfe77a",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2023-12-10T12:11:14.600539Z",
+ "iopub.status.busy": "2023-12-10T12:11:14.600161Z",
+ "iopub.status.idle": "2023-12-10T12:11:14.608299Z",
+ "shell.execute_reply": "2023-12-10T12:11:14.607649Z",
+ "shell.execute_reply.started": "2023-12-10T12:11:14.600442Z"
+ }
+ },
+ "source": [
+ "## Output"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "d0585798-7543-485d-af14-b5c520620871",
+ "metadata": {},
+ "source": [
+ "### Display result\n",
+ "* Calls the `authenticate_spotify` function to authenticate user then stores the client in the `spotify_client` variable.\n",
+ "* If `spotify_client` is available, then pass the client into `fetch_top_items` function and print out relevant information."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b5c9703e-cc72-48a2-9856-1f846c036cdc",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "spotify_client = authenticate_spotify(client_id, client_secret, redirect_uri)\n",
+ "if spotify_client:\n",
+ " fetch_top_items(spotify_client, limit, time_range)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.6"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}