diff --git a/docs/.doctrees/environment.pickle b/docs/.doctrees/environment.pickle index f8504fa..7fb6c31 100644 Binary files a/docs/.doctrees/environment.pickle and b/docs/.doctrees/environment.pickle differ diff --git a/docs/.doctrees/notebooks/getting_started.doctree b/docs/.doctrees/notebooks/getting_started.doctree index 84117dd..6653549 100644 Binary files a/docs/.doctrees/notebooks/getting_started.doctree and b/docs/.doctrees/notebooks/getting_started.doctree differ diff --git a/docs/.doctrees/notebooks/start.doctree b/docs/.doctrees/notebooks/start.doctree deleted file mode 100644 index ff24e5f..0000000 Binary files a/docs/.doctrees/notebooks/start.doctree and /dev/null differ diff --git a/docs/_modules/index.html b/docs/_modules/index.html index 14b7e2e..fcb1362 100644 --- a/docs/_modules/index.html +++ b/docs/_modules/index.html @@ -8,7 +8,7 @@
[docs]
def levenshtein_ratio(
base: str, values: Union[str, list[str]]
- ) -> Union[float, list[float], np.ndarray[float]]:
+ ) -> Union[float, list[float], "np.ndarray[float]"]:
"""
Compute the Levenshtein ratio, a measure of similarity, for
diff --git a/docs/_sources/api/minim.qobuz.PrivateAPI.rst.txt b/docs/_sources/api/minim.qobuz.PrivateAPI.rst.txt
index e50e323..1638259 100644
--- a/docs/_sources/api/minim.qobuz.PrivateAPI.rst.txt
+++ b/docs/_sources/api/minim.qobuz.PrivateAPI.rst.txt
@@ -1,4 +1,4 @@
-PrivateAPI
+PrivateAPI
==========
.. currentmodule:: minim.qobuz
diff --git a/docs/_sources/notebooks/start.ipynb.txt b/docs/_sources/notebooks/start.ipynb.txt
deleted file mode 100644
index edbf208..0000000
--- a/docs/_sources/notebooks/start.ipynb.txt
+++ /dev/null
@@ -1,2199 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Getting Started\n",
- "\n",
- "## Installation\n",
- "\n",
- "Minim is a Python package and can be installed from source using pip, the package installer for Python.\n",
- "\n",
- ":::{note}\n",
- "Minim will be coming to PyPI and conda-forge once the [PEP 541 request](https://github.com/pypi/support/issues/3068) is resolved!\n",
- ":::\n",
- "\n",
- "1. Grab a copy of the Minim repository:\n",
- "\n",
- " git clone https://github.com/bbye98/minim.git\n",
- "\n",
- "2. Enter the repository directory:\n",
- "\n",
- " cd minim\n",
- "\n",
- "3. *Optional*: Create a virtual environment to prevent dependency conflicts. \n",
- "\n",
- " **Conda**\n",
- "\n",
- " - Create an environment named `minim` and install the required dependencies using one of the following commands:\n",
- "\n",
- " conda create -n minim --file requirements_minimal.txt # required dependencies only\n",
- " conda env create -f environment.yml # all dependencies\n",
- "\n",
- " - Activate the environment:\n",
- "\n",
- " conda activate minim\n",
- "\n",
- " **venv**\n",
- "\n",
- " - Create an environment named `minim`:\n",
- "\n",
- " python -m venv minim\n",
- "\n",
- " - Activate the environment using one of the following commands:\n",
- "\n",
- " source minim/bin/activate # POSIX: bash or zsh\n",
- " minim\\Scripts\\activate.bat # Windows: cmd.exe\n",
- " minim\\Scripts\\Activate.ps1 # Windows: PowerShell\n",
- "\n",
- " - The required dependencies will be installed automatically alongside Minim in the next step. To install all dependencies instead:\n",
- "\n",
- " python -m pip install -r requirements.txt\n",
- "\n",
- " **virtualenv**\n",
- "\n",
- " - Create an environment named `minim`:\n",
- "\n",
- " virtualenv minim\n",
- "\n",
- " - Activate the environment using one of the following commands:\n",
- "\n",
- " source minim/bin/activate # Linux or macOS\n",
- " .\\minim\\Scripts\\activate # Windows\n",
- "\n",
- " - The required dependencies will be installed automatically alongside Minim in the next step. To install all dependencies instead:\n",
- "\n",
- " python -m pip install -r requirements.txt\n",
- "\n",
- "4. Install Minim (and required dependencies, if you have not already done so) using pip:\n",
- "\n",
- " python -m pip install -e .\n",
- "\n",
- "5. Try importing Minim in Python:\n",
- "\n",
- " python -c \"import minim\"\n",
- "\n",
- " If no errors like `ModuleNotFoundError: No module named 'minim'` are raised, you have successfully installed Minim!\n",
- "\n",
- "## Usage\n",
- "\n",
- "### Music service APIs"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "from minim import itunes, qobuz, spotify, tidal"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Currently, clients for iTunes Search API, Qobuz API, Spotify Web API, and TIDAL APIs have been implemented. Other than the iTunes Search API, which does not require client credentials or support user authentication and can be used out of the box, the other APIs have a few additional prerequisite steps before they can be used. If you authenticate via Minim, the tokens and their related information will be cached and updated automatically as they expire and are refreshed.\n",
- "\n",
- "#### iTunes Search API (`minim.itunes.SearchAPI`)\n",
- "\n",
- "To use the iTunes Search API, simply create a client by instantiating a `minim.itunes.SearchAPI` object with no arguments:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "client_itunes = itunes.SearchAPI()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Private Qobuz API (`minim.qobuz.PrivateAPI`)\n",
- "\n",
- "If you already have a user authentication token, you can provide it and its accompanying app credentials to the client as keyword arguments `auth_token`, `app_id`, and `app_secret`, respectively, and skip this section.\n",
- "\n",
- "To use the Qobuz API without user authentication, simply create a client by instantiating a `minim.qobuz.PrivateAPI` object with no arguments:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [],
- "source": [
- "client_qobuz = qobuz.PrivateAPI()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "To use the Qobuz API with user authentication and get access to all public and protected endpoints, you can pass `flow=\"password\"` and provide your Qobuz email and password as keyword arguments `email` and `password` to the constructor:\n",
- "\n",
- "```python\n",
- "client_qobuz = qobuz.PrivateAPI(flow=\"password\", email=, password=)\n",
- "```\n",
- "\n",
- "which will authenticate you via a POST request to and retrieve the user authentication token from the Qobuz Web Player, or specify `browser=True` to have Minim spawn a web browser with the Qobuz Web Player login page:\n",
- "\n",
- "```python\n",
- "client_qobuz = qobuz.PrivateAPI(flow=\"password\", browser=True)\n",
- "```\n",
- "\n",
- "which you can use to log in normally.\n",
- "\n",
- "#### Private Spotify Lyrics Service (`minim.spotify.PrivateLyricsService`)\n",
- "\n",
- "If you already have a user access token, you can provide it and optionally its accompanying expiry time and `sp_dc` cookie to the client as keyword arguments `access_token`, `expiry`, and `sp_dc`, respectively, and skip this section.\n",
- "\n",
- "To use the Spotify Lyrics service,\n",
- "\n",
- "1. Launch a web browser and log into the [Spotify Web Player](https://accounts.spotify.com/en/login?continue=https%3A%2F%2Fopen.spotify.com%2F).\n",
- "\n",
- "2. Find the `sp_dc` cookie in your web browser's storage.\n",
- "\n",
- " - For Chromium-based browsers, press `F12` to open DevTools and navigate to `Application > Storage > Cookies > https://open.spotify.com`.\n",
- " \n",
- " - For Firefox, press `Shift` + `F9` to open Storage Inspector and nagivate to `Storage > Cookies > https://open.spotify.com`.\n",
- " \n",
- "3. Create a client by instantiating a `minim.spotify.WebAPI` object with the `sp_dc` cookie as a keyword argument:\n",
- "\n",
- " ```python\n",
- " client_spotify_lyrics = spotify.PrivateLyricsService(sp_dc=)\n",
- " ```\n",
- "\n",
- " or store the `sp_dc` cookie as an environment variable `SPOTIFY_SP_DC` and call the constructor with no arguments:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [],
- "source": [
- "client_spotify_lyrics = spotify.PrivateLyricsService()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Spotify Web API (`minim.spotify.WebAPI`)\n",
- "\n",
- "If you already have an access token, you can provide it and optionally its accompanying refresh token, expiry time, and client credentials to the client as keyword arguments `access_token`, `refresh_token`, `expiry`, `client_id`, and `client_secret`, respectively, and skip this section.\n",
- "\n",
- "First, register a Spotify application [here](https://developer.spotify.com/documentation/general/guides/authorization/app-settings/) and grab its client credentials. For the redirect URI, use `http://localhost:8888/callback`. You can replace `8888` with an open port of your choice, but you will need to pass `port=` when you create a client.\n",
- "\n",
- "To use the Spotify Web API without user authentication, you can provide the client credentials as keyword arguments `client_id` and `client_secret` to the constructor:\n",
- "\n",
- "```python\n",
- "client_spotify = spotify.WebAPI(client_id=, \n",
- " client_secret=)\n",
- "```\n",
- "\n",
- "or store the client credentials as environment variables `SPOTIFY_CLIENT_ID` and `SPOTIFY_CLIENT_SECRET` and call the constructor with no arguments:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {},
- "outputs": [],
- "source": [
- "client_spotify = spotify.WebAPI()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "To use the Spotify Web API with user authentication, \n",
- "\n",
- "1. Get the necessary authorization scopes using `spotify.WebAPI.get_authorization_scopes()`:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {},
- "outputs": [],
- "source": [
- "scopes = spotify.WebAPI.get_scopes(\"all\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "2. Create a client with `flow=\"pkce\"`, the client credentials in `client_id` and `client_secret`, the authorization scopes in `scopes`, and optionally `framework=True` to automate the authorization code retrieval process:\n",
- "\n",
- " ```python\n",
- " client_spotify = spotify.WebAPI(client_id=, \n",
- " client_secret=,\n",
- " flow=\"pkce\", scopes=scopes, framework=True)\n",
- " ```\n",
- "\n",
- "3. If `framework=False`, open the authorization URL in a web browser.\n",
- "\n",
- "4. Log into your Spotify account and authorize Minim by clicking `Agree`.\n",
- "\n",
- "5. If `framework=False`, copy and paste the redirect URI into the prompt."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### TIDAL API (`minim.tidal.API`)\n",
- "\n",
- "If you already have a client-only access token, you can provide it and optionally its accompanying refresh token, expiry time, and client credentials to the client as keyword arguments `access_token`, `refresh_token`, `expiry`, `client_id`, and `client_secret`, respectively, and skip this section.\n",
- "\n",
- "First, register a TIDAL application [here](https://developer.tidal.com/documentation/dashboard/dashboard-client-credentials) and jot down the client credentials.\n",
- "\n",
- "To use the TIDAL API, you can provide the client credentials as keyword arguments `client_id` and `client_secret` to the `minim.tidal.API` constructor:\n",
- "\n",
- "```python\n",
- "client_tidal = tidal.API(client_id=, client_secret=)\n",
- "```\n",
- "\n",
- "or store the client credentials as environment variables `TIDAL_CLIENT_ID` and `TIDAL_CLIENT_SECRET` and create a client with no arguments:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [],
- "source": [
- "client_tidal = tidal.API()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "#### Private TIDAL API (`minim.tidal.PrivateAPI`)\n",
- "\n",
- "If you already have an access token, you can provide it and optionally its accompanying refresh token, expiry time, and client credentials to the client as keyword arguments `access_token`, `refresh_token`, `expiry`, `client_id`, and `client_secret`, respectively, and skip this section.\n",
- "\n",
- "To use the TIDAL API without user authentication, simply create a client by instantiating a `minim.tidal.PrivateAPI` object with no arguments:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [],
- "source": [
- "client_tidal_private = tidal.PrivateAPI()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "To use the TIDAL API with user authentication,\n",
- "\n",
- "1. Get client credentials from the TIDAL Web Player or the Android, iOS, macOS, and Windows applications by using a web debugging proxy tool to intercept web traffic.\n",
- "\n",
- "2. Create a client with the client credentials in `client_id` and `client_secret` and optionally `browser=True` to automatically open a web browser for the authorization flow. Use the authorization code with PKCE flow:\n",
- "\n",
- " ```python\n",
- " client_tidal_private = tidal.PrivateAPI(client_id=, \n",
- " client_secret=,\n",
- " flow=\"pkce\", browser=True)\n",
- " ```\n",
- " \n",
- " if you obtained client credentials from the TIDAL Web Player or the desktop applications, or the device code flow:\n",
- "\n",
- " ```python\n",
- " client_tidal_private = tidal.PrivateAPI(client_id=, \n",
- " client_secret=,\n",
- " flow=\"device\", browser=True)\n",
- " ```\n",
- "\n",
- " if you obtained client credentials from the Android or iOS applications.\n",
- " \n",
- "3. Follow the instructions in the console (`browser=False`) or the web browser (`browser=True`) to log into your TIDAL account and authorize Minim.\n",
- "\n",
- "#### Examples\n",
- "\n",
- "##### Search for an artist\n",
- "\n",
- "Each of the APIs has a `search()` method that can be used to search for and retrieve information about an artist, such as the EDM group Galantis:\n",
- "\n",
- "###### iTunes Search API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'wrapperType': 'artist',\n",
- " 'artistType': 'Artist',\n",
- " 'artistName': 'Galantis',\n",
- " 'artistLinkUrl': 'https://music.apple.com/us/artist/galantis/543322169?uo=4',\n",
- " 'artistId': 543322169,\n",
- " 'amgArtistId': 2616267,\n",
- " 'primaryGenreName': 'Dance',\n",
- " 'primaryGenreId': 17}"
- ]
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "client_itunes.search(\"Galantis\", entity=\"musicArtist\", limit=1)[\"results\"][0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### Private Qobuz API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'picture': 'https://static.qobuz.com/images/artists/covers/small/8dcf30e5c8e30281ecbb13b0886426c8.jpg',\n",
- " 'image': {'small': 'https://static.qobuz.com/images/artists/covers/small/8dcf30e5c8e30281ecbb13b0886426c8.jpg',\n",
- " 'medium': 'https://static.qobuz.com/images/artists/covers/medium/8dcf30e5c8e30281ecbb13b0886426c8.jpg',\n",
- " 'large': 'https://static.qobuz.com/images/artists/covers/large/8dcf30e5c8e30281ecbb13b0886426c8.jpg',\n",
- " 'extralarge': 'https://static.qobuz.com/images/artists/covers/large/8dcf30e5c8e30281ecbb13b0886426c8.jpg',\n",
- " 'mega': 'https://static.qobuz.com/images/artists/covers/large/8dcf30e5c8e30281ecbb13b0886426c8.jpg'},\n",
- " 'name': 'Galantis',\n",
- " 'slug': 'galantis',\n",
- " 'albums_count': 126,\n",
- " 'id': 865362}"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "client_qobuz.search(\"Galantis\", limit=1, strict=True)[\"artists\"][\"items\"][0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### Spotify Web API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'external_urls': {'spotify': 'https://open.spotify.com/artist/4sTQVOfp9vEMCemLw50sbu'},\n",
- " 'followers': {'href': None, 'total': 3375748},\n",
- " 'genres': ['dance pop', 'edm', 'pop', 'pop dance'],\n",
- " 'href': 'https://api.spotify.com/v1/artists/4sTQVOfp9vEMCemLw50sbu',\n",
- " 'id': '4sTQVOfp9vEMCemLw50sbu',\n",
- " 'images': [{'height': 640,\n",
- " 'url': 'https://i.scdn.co/image/ab6761610000e5eb7bda087d6fb48d481efd3344',\n",
- " 'width': 640},\n",
- " {'height': 320,\n",
- " 'url': 'https://i.scdn.co/image/ab676161000051747bda087d6fb48d481efd3344',\n",
- " 'width': 320},\n",
- " {'height': 160,\n",
- " 'url': 'https://i.scdn.co/image/ab6761610000f1787bda087d6fb48d481efd3344',\n",
- " 'width': 160}],\n",
- " 'name': 'Galantis',\n",
- " 'popularity': 67,\n",
- " 'type': 'artist',\n",
- " 'uri': 'spotify:artist:4sTQVOfp9vEMCemLw50sbu'}"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "client_spotify.search(\"Galantis\", \"artist\", limit=1)[\"items\"][0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### TIDAL API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'resource': {'id': '4676988',\n",
- " 'name': 'Galantis',\n",
- " 'picture': [{'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/1024x256.jpg',\n",
- " 'width': 1024,\n",
- " 'height': 256},\n",
- " {'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/1080x720.jpg',\n",
- " 'width': 1080,\n",
- " 'height': 720},\n",
- " {'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/160x107.jpg',\n",
- " 'width': 160,\n",
- " 'height': 107},\n",
- " {'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/160x160.jpg',\n",
- " 'width': 160,\n",
- " 'height': 160},\n",
- " {'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/320x214.jpg',\n",
- " 'width': 320,\n",
- " 'height': 214},\n",
- " {'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/320x320.jpg',\n",
- " 'width': 320,\n",
- " 'height': 320},\n",
- " {'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/480x480.jpg',\n",
- " 'width': 480,\n",
- " 'height': 480},\n",
- " {'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/640x428.jpg',\n",
- " 'width': 640,\n",
- " 'height': 428},\n",
- " {'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/750x500.jpg',\n",
- " 'width': 750,\n",
- " 'height': 500},\n",
- " {'url': 'https://resources.tidal.com/images/a627e21c/60f7/4e90/b2bb/e50b178c4f0b/750x750.jpg',\n",
- " 'width': 750,\n",
- " 'height': 750}]},\n",
- " 'id': '4676988',\n",
- " 'status': 200,\n",
- " 'message': 'success'}"
- ]
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "client_tidal.search(\"Galantis\", \"US\", type=\"ARTISTS\", limit=1)[\"artists\"][0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### Private TIDAL API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'id': 4676988,\n",
- " 'name': 'Galantis',\n",
- " 'artistTypes': ['ARTIST', 'CONTRIBUTOR'],\n",
- " 'url': 'http://www.tidal.com/artist/4676988',\n",
- " 'picture': 'a627e21c-60f7-4e90-b2bb-e50b178c4f0b',\n",
- " 'popularity': 72,\n",
- " 'artistRoles': [{'categoryId': -1, 'category': 'Artist'},\n",
- " {'categoryId': 11, 'category': 'Performer'},\n",
- " {'categoryId': 3, 'category': 'Engineer'},\n",
- " {'categoryId': 10, 'category': 'Production team'},\n",
- " {'categoryId': 1, 'category': 'Producer'},\n",
- " {'categoryId': 2, 'category': 'Songwriter'}],\n",
- " 'mixes': {'ARTIST_MIX': '000202a7e72fd90d0c0df2ed56ddea'}}"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "client_tidal_private.search(\"Galantis\", type=\"artist\", limit=1)[\"items\"][0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "##### Search for a track\n",
- "\n",
- "The `search()` methods can also be used to search for and retrieve information about a track, such as \"Everybody Talks\" by Neon Trees:\n",
- "\n",
- "###### iTunes Search API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'wrapperType': 'track',\n",
- " 'kind': 'song',\n",
- " 'artistId': 350172836,\n",
- " 'collectionId': 1443469527,\n",
- " 'trackId': 1443469581,\n",
- " 'artistName': 'Neon Trees',\n",
- " 'collectionName': 'Picture Show',\n",
- " 'trackName': 'Everybody Talks',\n",
- " 'collectionCensoredName': 'Picture Show',\n",
- " 'trackCensoredName': 'Everybody Talks',\n",
- " 'artistViewUrl': 'https://music.apple.com/us/artist/neon-trees/350172836?uo=4',\n",
- " 'collectionViewUrl': 'https://music.apple.com/us/album/everybody-talks/1443469527?i=1443469581&uo=4',\n",
- " 'trackViewUrl': 'https://music.apple.com/us/album/everybody-talks/1443469527?i=1443469581&uo=4',\n",
- " 'previewUrl': 'https://audio-ssl.itunes.apple.com/itunes-assets/AudioPreview122/v4/5c/29/bf/5c29bf6b-ca2c-4e8b-2be6-c51a282c7dae/mzaf_1255557534804450018.plus.aac.p.m4a',\n",
- " 'artworkUrl30': 'https://is1-ssl.mzstatic.com/image/thumb/Music115/v4/80/e3/95/80e39565-35f9-2496-c6f8-6572490c4a7b/12UMGIM12509.rgb.jpg/30x30bb.jpg',\n",
- " 'artworkUrl60': 'https://is1-ssl.mzstatic.com/image/thumb/Music115/v4/80/e3/95/80e39565-35f9-2496-c6f8-6572490c4a7b/12UMGIM12509.rgb.jpg/60x60bb.jpg',\n",
- " 'artworkUrl100': 'https://is1-ssl.mzstatic.com/image/thumb/Music115/v4/80/e3/95/80e39565-35f9-2496-c6f8-6572490c4a7b/12UMGIM12509.rgb.jpg/100x100bb.jpg',\n",
- " 'collectionPrice': 6.99,\n",
- " 'trackPrice': 1.29,\n",
- " 'releaseDate': '2011-12-19T12:00:00Z',\n",
- " 'collectionExplicitness': 'explicit',\n",
- " 'trackExplicitness': 'explicit',\n",
- " 'discCount': 1,\n",
- " 'discNumber': 1,\n",
- " 'trackCount': 12,\n",
- " 'trackNumber': 3,\n",
- " 'trackTimeMillis': 177280,\n",
- " 'country': 'USA',\n",
- " 'currency': 'USD',\n",
- " 'primaryGenreName': 'Alternative',\n",
- " 'contentAdvisoryRating': 'Explicit',\n",
- " 'isStreamable': True}"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "client_itunes.search(\"Everybody Talks\", media=\"music\", limit=1)[\"results\"][0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### Private Qobuz API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'maximum_bit_depth': 16,\n",
- " 'copyright': '℗ 2011 UMG Recordings, Inc.',\n",
- " 'performers': 'Justin Meldal-Johnsen, Producer, Guitar, Additional Keyboards, Percussion, Programmer, AssociatedPerformer - Tim Pagnotta, ComposerLyricist - Greg Collins, Engineer, StudioPersonnel - Wesley Seidman, Asst. Recording Engineer, StudioPersonnel - Tyler Glenn, ComposerLyricist - Neon Trees, MainArtist - Matt Wiggers, Asst. Recording Engineer, StudioPersonnel - Bill Bush, Mixer, StudioPersonnel',\n",
- " 'audio_info': {'replaygain_track_peak': 0.999969,\n",
- " 'replaygain_track_gain': -11.63},\n",
- " 'performer': {'name': 'Neon Trees', 'id': 470727},\n",
- " 'album': {'image': {'small': 'https://static.qobuz.com/images/covers/42/54/0060252795442_230.jpg',\n",
- " 'thumbnail': 'https://static.qobuz.com/images/covers/42/54/0060252795442_50.jpg',\n",
- " 'large': 'https://static.qobuz.com/images/covers/42/54/0060252795442_600.jpg'},\n",
- " 'maximum_bit_depth': 16,\n",
- " 'media_count': 1,\n",
- " 'artist': {'image': None,\n",
- " 'name': 'Neon Trees',\n",
- " 'id': 470727,\n",
- " 'albums_count': 42,\n",
- " 'slug': 'neon-trees',\n",
- " 'picture': None},\n",
- " 'upc': '0060252795442',\n",
- " 'released_at': 1325372400,\n",
- " 'label': {'name': 'Mercury Records',\n",
- " 'id': 17487,\n",
- " 'albums_count': 774,\n",
- " 'supplier_id': 1,\n",
- " 'slug': 'mercury-records'},\n",
- " 'title': 'Picture Show',\n",
- " 'qobuz_id': 5653617,\n",
- " 'version': None,\n",
- " 'duration': 2785,\n",
- " 'parental_warning': True,\n",
- " 'tracks_count': 11,\n",
- " 'popularity': 0,\n",
- " 'genre': {'path': [112, 119, 113],\n",
- " 'color': '#0070ef',\n",
- " 'name': 'Alternative & Indie',\n",
- " 'id': 113,\n",
- " 'slug': 'alternatif-et-inde'},\n",
- " 'maximum_channel_count': 2,\n",
- " 'id': '0060252795442',\n",
- " 'maximum_sampling_rate': 44.1,\n",
- " 'previewable': True,\n",
- " 'sampleable': True,\n",
- " 'displayable': True,\n",
- " 'streamable': True,\n",
- " 'streamable_at': 1683529200,\n",
- " 'downloadable': False,\n",
- " 'purchasable_at': None,\n",
- " 'purchasable': False,\n",
- " 'release_date_original': '2012-01-01',\n",
- " 'release_date_download': '2012-01-01',\n",
- " 'release_date_stream': '2012-01-01',\n",
- " 'release_date_purchase': '2012-01-01',\n",
- " 'hires': False,\n",
- " 'hires_streamable': False},\n",
- " 'work': None,\n",
- " 'composer': {'name': 'Tyler Glenn', 'id': 583118},\n",
- " 'isrc': 'USUM71119189',\n",
- " 'title': 'Everybody Talks',\n",
- " 'version': 'Album Version',\n",
- " 'duration': 177,\n",
- " 'parental_warning': True,\n",
- " 'track_number': 3,\n",
- " 'maximum_channel_count': 2,\n",
- " 'id': 5653620,\n",
- " 'media_number': 1,\n",
- " 'maximum_sampling_rate': 44.1,\n",
- " 'release_date_original': None,\n",
- " 'release_date_download': None,\n",
- " 'release_date_stream': None,\n",
- " 'release_date_purchase': None,\n",
- " 'purchasable': True,\n",
- " 'streamable': True,\n",
- " 'previewable': True,\n",
- " 'sampleable': True,\n",
- " 'downloadable': True,\n",
- " 'displayable': True,\n",
- " 'purchasable_at': 1683702000,\n",
- " 'streamable_at': 1683529200,\n",
- " 'hires': False,\n",
- " 'hires_streamable': False}"
- ]
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "track_qobuz = client_qobuz.search(\"Everybody Talks\", \"ReleaseName\", limit=1, \n",
- " strict=True)[\"tracks\"][\"items\"][0]\n",
- "track_qobuz"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### Spotify Web API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'album': {'album_type': 'album',\n",
- " 'artists': [{'external_urls': {'spotify': 'https://open.spotify.com/artist/0RpddSzUHfncUWNJXKOsjy'},\n",
- " 'href': 'https://api.spotify.com/v1/artists/0RpddSzUHfncUWNJXKOsjy',\n",
- " 'id': '0RpddSzUHfncUWNJXKOsjy',\n",
- " 'name': 'Neon Trees',\n",
- " 'type': 'artist',\n",
- " 'uri': 'spotify:artist:0RpddSzUHfncUWNJXKOsjy'}],\n",
- " 'available_markets': ['AR',\n",
- " 'AU',\n",
- " 'AT',\n",
- " 'BE',\n",
- " 'BO',\n",
- " 'BR',\n",
- " 'BG',\n",
- " 'CA',\n",
- " 'CL',\n",
- " 'CO',\n",
- " 'CR',\n",
- " 'CY',\n",
- " 'CZ',\n",
- " 'DK',\n",
- " 'DO',\n",
- " 'DE',\n",
- " 'EC',\n",
- " 'EE',\n",
- " 'SV',\n",
- " 'FI',\n",
- " 'FR',\n",
- " 'GR',\n",
- " 'GT',\n",
- " 'HN',\n",
- " 'HK',\n",
- " 'HU',\n",
- " 'IS',\n",
- " 'IE',\n",
- " 'IT',\n",
- " 'LV',\n",
- " 'LT',\n",
- " 'LU',\n",
- " 'MY',\n",
- " 'MT',\n",
- " 'NL',\n",
- " 'NZ',\n",
- " 'NI',\n",
- " 'NO',\n",
- " 'PA',\n",
- " 'PY',\n",
- " 'PE',\n",
- " 'PH',\n",
- " 'PL',\n",
- " 'PT',\n",
- " 'SG',\n",
- " 'SK',\n",
- " 'ES',\n",
- " 'SE',\n",
- " 'CH',\n",
- " 'TW',\n",
- " 'TR',\n",
- " 'UY',\n",
- " 'US',\n",
- " 'GB',\n",
- " 'AD',\n",
- " 'LI',\n",
- " 'MC',\n",
- " 'ID',\n",
- " 'TH',\n",
- " 'VN',\n",
- " 'RO',\n",
- " 'IL',\n",
- " 'ZA',\n",
- " 'SA',\n",
- " 'AE',\n",
- " 'BH',\n",
- " 'QA',\n",
- " 'OM',\n",
- " 'KW',\n",
- " 'EG',\n",
- " 'TN',\n",
- " 'LB',\n",
- " 'JO',\n",
- " 'PS',\n",
- " 'IN',\n",
- " 'BY',\n",
- " 'KZ',\n",
- " 'MD',\n",
- " 'UA',\n",
- " 'AL',\n",
- " 'BA',\n",
- " 'HR',\n",
- " 'ME',\n",
- " 'MK',\n",
- " 'RS',\n",
- " 'SI',\n",
- " 'KR',\n",
- " 'BD',\n",
- " 'PK',\n",
- " 'LK',\n",
- " 'GH',\n",
- " 'KE',\n",
- " 'NG',\n",
- " 'TZ',\n",
- " 'UG',\n",
- " 'AG',\n",
- " 'AM',\n",
- " 'BS',\n",
- " 'BB',\n",
- " 'BZ',\n",
- " 'BT',\n",
- " 'BW',\n",
- " 'BF',\n",
- " 'CV',\n",
- " 'CW',\n",
- " 'DM',\n",
- " 'FJ',\n",
- " 'GM',\n",
- " 'GD',\n",
- " 'GW',\n",
- " 'GY',\n",
- " 'HT',\n",
- " 'JM',\n",
- " 'KI',\n",
- " 'LS',\n",
- " 'LR',\n",
- " 'MW',\n",
- " 'MV',\n",
- " 'ML',\n",
- " 'MH',\n",
- " 'FM',\n",
- " 'NA',\n",
- " 'NR',\n",
- " 'NE',\n",
- " 'PW',\n",
- " 'PG',\n",
- " 'WS',\n",
- " 'ST',\n",
- " 'SN',\n",
- " 'SC',\n",
- " 'SL',\n",
- " 'SB',\n",
- " 'KN',\n",
- " 'LC',\n",
- " 'VC',\n",
- " 'SR',\n",
- " 'TL',\n",
- " 'TO',\n",
- " 'TT',\n",
- " 'TV',\n",
- " 'AZ',\n",
- " 'BN',\n",
- " 'BI',\n",
- " 'KH',\n",
- " 'CM',\n",
- " 'TD',\n",
- " 'KM',\n",
- " 'GQ',\n",
- " 'SZ',\n",
- " 'GA',\n",
- " 'GN',\n",
- " 'KG',\n",
- " 'LA',\n",
- " 'MO',\n",
- " 'MR',\n",
- " 'MN',\n",
- " 'NP',\n",
- " 'RW',\n",
- " 'TG',\n",
- " 'UZ',\n",
- " 'ZW',\n",
- " 'BJ',\n",
- " 'MG',\n",
- " 'MU',\n",
- " 'MZ',\n",
- " 'AO',\n",
- " 'CI',\n",
- " 'DJ',\n",
- " 'ZM',\n",
- " 'CD',\n",
- " 'CG',\n",
- " 'IQ',\n",
- " 'TJ',\n",
- " 'VE',\n",
- " 'XK'],\n",
- " 'external_urls': {'spotify': 'https://open.spotify.com/album/0uRFz92JmjwDbZbB7hEBIr'},\n",
- " 'href': 'https://api.spotify.com/v1/albums/0uRFz92JmjwDbZbB7hEBIr',\n",
- " 'id': '0uRFz92JmjwDbZbB7hEBIr',\n",
- " 'images': [{'height': 640,\n",
- " 'url': 'https://i.scdn.co/image/ab67616d0000b2734a6c0376235e5aa44e59d2c2',\n",
- " 'width': 640},\n",
- " {'height': 300,\n",
- " 'url': 'https://i.scdn.co/image/ab67616d00001e024a6c0376235e5aa44e59d2c2',\n",
- " 'width': 300},\n",
- " {'height': 64,\n",
- " 'url': 'https://i.scdn.co/image/ab67616d000048514a6c0376235e5aa44e59d2c2',\n",
- " 'width': 64}],\n",
- " 'name': 'Picture Show',\n",
- " 'release_date': '2012-01-01',\n",
- " 'release_date_precision': 'day',\n",
- " 'total_tracks': 11,\n",
- " 'type': 'album',\n",
- " 'uri': 'spotify:album:0uRFz92JmjwDbZbB7hEBIr'},\n",
- " 'artists': [{'external_urls': {'spotify': 'https://open.spotify.com/artist/0RpddSzUHfncUWNJXKOsjy'},\n",
- " 'href': 'https://api.spotify.com/v1/artists/0RpddSzUHfncUWNJXKOsjy',\n",
- " 'id': '0RpddSzUHfncUWNJXKOsjy',\n",
- " 'name': 'Neon Trees',\n",
- " 'type': 'artist',\n",
- " 'uri': 'spotify:artist:0RpddSzUHfncUWNJXKOsjy'}],\n",
- " 'available_markets': ['AR',\n",
- " 'AU',\n",
- " 'AT',\n",
- " 'BE',\n",
- " 'BO',\n",
- " 'BR',\n",
- " 'BG',\n",
- " 'CA',\n",
- " 'CL',\n",
- " 'CO',\n",
- " 'CR',\n",
- " 'CY',\n",
- " 'CZ',\n",
- " 'DK',\n",
- " 'DO',\n",
- " 'DE',\n",
- " 'EC',\n",
- " 'EE',\n",
- " 'SV',\n",
- " 'FI',\n",
- " 'FR',\n",
- " 'GR',\n",
- " 'GT',\n",
- " 'HN',\n",
- " 'HK',\n",
- " 'HU',\n",
- " 'IS',\n",
- " 'IE',\n",
- " 'IT',\n",
- " 'LV',\n",
- " 'LT',\n",
- " 'LU',\n",
- " 'MY',\n",
- " 'MT',\n",
- " 'NL',\n",
- " 'NZ',\n",
- " 'NI',\n",
- " 'NO',\n",
- " 'PA',\n",
- " 'PY',\n",
- " 'PE',\n",
- " 'PH',\n",
- " 'PL',\n",
- " 'PT',\n",
- " 'SG',\n",
- " 'SK',\n",
- " 'ES',\n",
- " 'SE',\n",
- " 'CH',\n",
- " 'TW',\n",
- " 'TR',\n",
- " 'UY',\n",
- " 'US',\n",
- " 'GB',\n",
- " 'AD',\n",
- " 'LI',\n",
- " 'MC',\n",
- " 'ID',\n",
- " 'TH',\n",
- " 'VN',\n",
- " 'RO',\n",
- " 'IL',\n",
- " 'ZA',\n",
- " 'SA',\n",
- " 'AE',\n",
- " 'BH',\n",
- " 'QA',\n",
- " 'OM',\n",
- " 'KW',\n",
- " 'EG',\n",
- " 'TN',\n",
- " 'LB',\n",
- " 'JO',\n",
- " 'PS',\n",
- " 'IN',\n",
- " 'BY',\n",
- " 'KZ',\n",
- " 'MD',\n",
- " 'UA',\n",
- " 'AL',\n",
- " 'BA',\n",
- " 'HR',\n",
- " 'ME',\n",
- " 'MK',\n",
- " 'RS',\n",
- " 'SI',\n",
- " 'KR',\n",
- " 'BD',\n",
- " 'PK',\n",
- " 'LK',\n",
- " 'GH',\n",
- " 'KE',\n",
- " 'NG',\n",
- " 'TZ',\n",
- " 'UG',\n",
- " 'AG',\n",
- " 'AM',\n",
- " 'BS',\n",
- " 'BB',\n",
- " 'BZ',\n",
- " 'BT',\n",
- " 'BW',\n",
- " 'BF',\n",
- " 'CV',\n",
- " 'CW',\n",
- " 'DM',\n",
- " 'FJ',\n",
- " 'GM',\n",
- " 'GD',\n",
- " 'GW',\n",
- " 'GY',\n",
- " 'HT',\n",
- " 'JM',\n",
- " 'KI',\n",
- " 'LS',\n",
- " 'LR',\n",
- " 'MW',\n",
- " 'MV',\n",
- " 'ML',\n",
- " 'MH',\n",
- " 'FM',\n",
- " 'NA',\n",
- " 'NR',\n",
- " 'NE',\n",
- " 'PW',\n",
- " 'PG',\n",
- " 'WS',\n",
- " 'ST',\n",
- " 'SN',\n",
- " 'SC',\n",
- " 'SL',\n",
- " 'SB',\n",
- " 'KN',\n",
- " 'LC',\n",
- " 'VC',\n",
- " 'SR',\n",
- " 'TL',\n",
- " 'TO',\n",
- " 'TT',\n",
- " 'TV',\n",
- " 'AZ',\n",
- " 'BN',\n",
- " 'BI',\n",
- " 'KH',\n",
- " 'CM',\n",
- " 'TD',\n",
- " 'KM',\n",
- " 'GQ',\n",
- " 'SZ',\n",
- " 'GA',\n",
- " 'GN',\n",
- " 'KG',\n",
- " 'LA',\n",
- " 'MO',\n",
- " 'MR',\n",
- " 'MN',\n",
- " 'NP',\n",
- " 'RW',\n",
- " 'TG',\n",
- " 'UZ',\n",
- " 'ZW',\n",
- " 'BJ',\n",
- " 'MG',\n",
- " 'MU',\n",
- " 'MZ',\n",
- " 'AO',\n",
- " 'CI',\n",
- " 'DJ',\n",
- " 'ZM',\n",
- " 'CD',\n",
- " 'CG',\n",
- " 'IQ',\n",
- " 'TJ',\n",
- " 'VE',\n",
- " 'XK'],\n",
- " 'disc_number': 1,\n",
- " 'duration_ms': 177280,\n",
- " 'explicit': True,\n",
- " 'external_ids': {'isrc': 'USUM71119189'},\n",
- " 'external_urls': {'spotify': 'https://open.spotify.com/track/2iUmqdfGZcHIhS3b9E9EWq'},\n",
- " 'href': 'https://api.spotify.com/v1/tracks/2iUmqdfGZcHIhS3b9E9EWq',\n",
- " 'id': '2iUmqdfGZcHIhS3b9E9EWq',\n",
- " 'is_local': False,\n",
- " 'name': 'Everybody Talks',\n",
- " 'popularity': 81,\n",
- " 'preview_url': None,\n",
- " 'track_number': 3,\n",
- " 'type': 'track',\n",
- " 'uri': 'spotify:track:2iUmqdfGZcHIhS3b9E9EWq'}"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "track_spotify = client_spotify.search(\"Everybody Talks\", \"track\", \n",
- " limit=1)[\"items\"][0]\n",
- "track_spotify"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### TIDAL API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'id': '14492425',\n",
- " 'status': 451,\n",
- " 'message': 'Unavailable due to demand from the right-holders to prohibit access to the resource'}"
- ]
- },
- "execution_count": 17,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "client_tidal.search(\"Everybody Talks\", \"US\", type=\"TRACKS\", limit=1)[\"tracks\"][0]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### Private TIDAL API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'id': 14492425,\n",
- " 'title': 'Everybody Talks',\n",
- " 'duration': 177,\n",
- " 'replayGain': -11.7,\n",
- " 'peak': 0.999969,\n",
- " 'allowStreaming': True,\n",
- " 'streamReady': True,\n",
- " 'adSupportedStreamReady': True,\n",
- " 'djReady': True,\n",
- " 'stemReady': False,\n",
- " 'streamStartDate': '2012-04-17T00:00:00.000+0000',\n",
- " 'premiumStreamingOnly': False,\n",
- " 'trackNumber': 3,\n",
- " 'volumeNumber': 1,\n",
- " 'version': None,\n",
- " 'popularity': 55,\n",
- " 'copyright': 'A Mercury Records Release; ℗ 2011 UMG Recordings, Inc.',\n",
- " 'url': 'http://www.tidal.com/track/14492425',\n",
- " 'isrc': 'USUM71119189',\n",
- " 'editable': False,\n",
- " 'explicit': True,\n",
- " 'audioQuality': 'LOSSLESS',\n",
- " 'audioModes': ['STEREO'],\n",
- " 'mediaMetadata': {'tags': ['LOSSLESS']},\n",
- " 'artist': {'id': 3665225,\n",
- " 'name': 'Neon Trees',\n",
- " 'type': 'MAIN',\n",
- " 'picture': 'e6f17398-759e-45a0-9673-6ded6811e199'},\n",
- " 'artists': [{'id': 3665225,\n",
- " 'name': 'Neon Trees',\n",
- " 'type': 'MAIN',\n",
- " 'picture': 'e6f17398-759e-45a0-9673-6ded6811e199'}],\n",
- " 'album': {'id': 14492422,\n",
- " 'title': 'Picture Show',\n",
- " 'cover': '1c2d7c90-034e-485a-be1f-24a669c7e6ee',\n",
- " 'vibrantColor': '#f8af88',\n",
- " 'videoCover': None},\n",
- " 'mixes': {'TRACK_MIX': '0019768c833a193c29829e5bf473fc'}}"
- ]
- },
- "execution_count": 18,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "track_tidal_private = client_tidal_private.search(\"Everybody Talks\", \n",
- " type=\"track\", \n",
- " limit=1)[\"items\"][0]\n",
- "track_tidal_private"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "##### Create, modify, and delete personal playlists\n",
- "\n",
- "If the clients are authenticated, you can create and modify user playlists. As an example, we will create a private playlist named \"Minim\", make it public, add \"Everybody Talks\" by Neon Trees to it, and then delete it.\n",
- "\n",
- "###### Private Qobuz API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'owner': None,\n",
- " 'users_count': 0,\n",
- " 'images150': ['https://static.qobuz.com/images/covers/42/54/0060252795442_150.jpg'],\n",
- " 'images': ['https://static.qobuz.com/images/covers/42/54/0060252795442_50.jpg'],\n",
- " 'is_collaborative': False,\n",
- " 'description': 'A playlist created using Minim.',\n",
- " 'created_at': 1699760099,\n",
- " 'images300': ['https://static.qobuz.com/images/covers/42/54/0060252795442_300.jpg'],\n",
- " 'duration': 177,\n",
- " 'updated_at': 1699760100,\n",
- " 'published_to': None,\n",
- " 'genres': [],\n",
- " 'tracks_count': 1,\n",
- " 'public_at': 1699760100,\n",
- " 'name': 'Minim',\n",
- " 'is_public': True,\n",
- " 'published_from': None,\n",
- " 'id': 17864331,\n",
- " 'slug': 'minim-24',\n",
- " 'is_featured': False,\n",
- " 'tracks': {'offset': 0,\n",
- " 'limit': 50,\n",
- " 'total': 1,\n",
- " 'items': [{'maximum_bit_depth': 16,\n",
- " 'copyright': '℗ 2011 UMG Recordings, Inc.',\n",
- " 'performers': 'Justin Meldal-Johnsen, Producer, Guitar, Additional Keyboards, Percussion, Programmer, AssociatedPerformer - Tim Pagnotta, ComposerLyricist - Greg Collins, Engineer, StudioPersonnel - Wesley Seidman, Asst. Recording Engineer, StudioPersonnel - Tyler Glenn, ComposerLyricist - Neon Trees, MainArtist - Matt Wiggers, Asst. Recording Engineer, StudioPersonnel - Bill Bush, Mixer, StudioPersonnel',\n",
- " 'audio_info': {'replaygain_track_peak': 0.999969,\n",
- " 'replaygain_track_gain': -11.63},\n",
- " 'performer': {'name': 'Neon Trees', 'id': 470727},\n",
- " 'album': {'image': {'small': 'https://static.qobuz.com/images/covers/42/54/0060252795442_230.jpg',\n",
- " 'thumbnail': 'https://static.qobuz.com/images/covers/42/54/0060252795442_50.jpg',\n",
- " 'large': 'https://static.qobuz.com/images/covers/42/54/0060252795442_600.jpg'},\n",
- " 'maximum_bit_depth': 16,\n",
- " 'media_count': 1,\n",
- " 'artist': {'image': None,\n",
- " 'name': 'Neon Trees',\n",
- " 'id': 470727,\n",
- " 'albums_count': 42,\n",
- " 'slug': 'neon-trees',\n",
- " 'picture': None},\n",
- " 'upc': '0060252795442',\n",
- " 'released_at': 1325372400,\n",
- " 'label': {'name': 'Mercury Records',\n",
- " 'id': 17487,\n",
- " 'albums_count': 774,\n",
- " 'supplier_id': 1,\n",
- " 'slug': 'mercury-records'},\n",
- " 'title': 'Picture Show',\n",
- " 'qobuz_id': 5653617,\n",
- " 'version': None,\n",
- " 'duration': 2785,\n",
- " 'parental_warning': True,\n",
- " 'tracks_count': 11,\n",
- " 'popularity': 0,\n",
- " 'genre': {'path': [112, 119, 113],\n",
- " 'color': '#0070ef',\n",
- " 'name': 'Alternative & Indie',\n",
- " 'id': 113,\n",
- " 'slug': 'alternatif-et-inde'},\n",
- " 'maximum_channel_count': 2,\n",
- " 'id': '0060252795442',\n",
- " 'maximum_sampling_rate': 44.1,\n",
- " 'previewable': True,\n",
- " 'sampleable': True,\n",
- " 'displayable': True,\n",
- " 'streamable': True,\n",
- " 'streamable_at': 1683529200,\n",
- " 'downloadable': False,\n",
- " 'purchasable_at': None,\n",
- " 'purchasable': False,\n",
- " 'release_date_original': '2012-01-01',\n",
- " 'release_date_download': '2012-01-01',\n",
- " 'release_date_stream': '2012-01-01',\n",
- " 'release_date_purchase': '2012-01-01',\n",
- " 'hires': False,\n",
- " 'hires_streamable': False},\n",
- " 'work': None,\n",
- " 'composer': {'name': 'Tyler Glenn', 'id': 583118},\n",
- " 'isrc': 'USUM71119189',\n",
- " 'title': 'Everybody Talks',\n",
- " 'version': 'Album Version',\n",
- " 'duration': 177,\n",
- " 'parental_warning': True,\n",
- " 'track_number': 3,\n",
- " 'maximum_channel_count': 2,\n",
- " 'id': 5653620,\n",
- " 'media_number': 1,\n",
- " 'maximum_sampling_rate': 44.1,\n",
- " 'release_date_original': None,\n",
- " 'release_date_download': None,\n",
- " 'release_date_stream': None,\n",
- " 'release_date_purchase': None,\n",
- " 'purchasable': True,\n",
- " 'streamable': True,\n",
- " 'previewable': True,\n",
- " 'sampleable': True,\n",
- " 'downloadable': True,\n",
- " 'displayable': True,\n",
- " 'purchasable_at': 1683702000,\n",
- " 'streamable_at': 1683529200,\n",
- " 'hires': False,\n",
- " 'hires_streamable': False,\n",
- " 'position': 1,\n",
- " 'created_at': 1699760100,\n",
- " 'playlist_track_id': 3775048859}]}}"
- ]
- },
- "execution_count": 19,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "playlist_qobuz = client_qobuz.create_playlist(\n",
- " \"Minim\", \n",
- " description=\"A playlist created using Minim.\",\n",
- " public=False\n",
- ")\n",
- "client_qobuz.update_playlist(playlist_qobuz[\"id\"], public=True)\n",
- "client_qobuz.add_playlist_tracks(playlist_qobuz[\"id\"], track_qobuz[\"id\"])\n",
- "playlist_qobuz = client_qobuz.get_playlist(playlist_qobuz[\"id\"])\n",
- "playlist_qobuz[\"owner\"] = None # remove personal identifying information\n",
- "playlist_qobuz"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {},
- "outputs": [],
- "source": [
- "client_qobuz.delete_playlist(playlist_qobuz[\"id\"])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### Spotify Web API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'collaborative': False,\n",
- " 'description': 'A playlist created using Minim.',\n",
- " 'external_urls': {'spotify': 'https://open.spotify.com/playlist/1o95b3Y5b5szr7qJ7DUx1E'},\n",
- " 'followers': {'href': None, 'total': 0},\n",
- " 'href': 'https://api.spotify.com/v1/playlists/1o95b3Y5b5szr7qJ7DUx1E',\n",
- " 'id': '1o95b3Y5b5szr7qJ7DUx1E',\n",
- " 'images': [{'height': 640,\n",
- " 'url': 'https://i.scdn.co/image/ab67616d0000b2734a6c0376235e5aa44e59d2c2',\n",
- " 'width': 640}],\n",
- " 'name': 'Minim',\n",
- " 'owner': None,\n",
- " 'primary_color': None,\n",
- " 'public': True,\n",
- " 'snapshot_id': 'Myw4YTMwNzY1Y2FlNTdkYmNjYjdlYzQ3MGQzYjQyYjk2NzQ0OTcwZjRi',\n",
- " 'tracks': {'href': 'https://api.spotify.com/v1/playlists/1o95b3Y5b5szr7qJ7DUx1E/tracks?offset=0&limit=100',\n",
- " 'items': [{'added_at': '2023-11-12T03:35:02Z',\n",
- " 'added_by': None,\n",
- " 'is_local': False,\n",
- " 'primary_color': None,\n",
- " 'track': {'album': {'album_type': 'album',\n",
- " 'artists': [{'external_urls': {'spotify': 'https://open.spotify.com/artist/0RpddSzUHfncUWNJXKOsjy'},\n",
- " 'href': 'https://api.spotify.com/v1/artists/0RpddSzUHfncUWNJXKOsjy',\n",
- " 'id': '0RpddSzUHfncUWNJXKOsjy',\n",
- " 'name': 'Neon Trees',\n",
- " 'type': 'artist',\n",
- " 'uri': 'spotify:artist:0RpddSzUHfncUWNJXKOsjy'}],\n",
- " 'available_markets': ['AR',\n",
- " 'AU',\n",
- " 'AT',\n",
- " 'BE',\n",
- " 'BO',\n",
- " 'BR',\n",
- " 'BG',\n",
- " 'CA',\n",
- " 'CL',\n",
- " 'CO',\n",
- " 'CR',\n",
- " 'CY',\n",
- " 'CZ',\n",
- " 'DK',\n",
- " 'DO',\n",
- " 'DE',\n",
- " 'EC',\n",
- " 'EE',\n",
- " 'SV',\n",
- " 'FI',\n",
- " 'FR',\n",
- " 'GR',\n",
- " 'GT',\n",
- " 'HN',\n",
- " 'HK',\n",
- " 'HU',\n",
- " 'IS',\n",
- " 'IE',\n",
- " 'IT',\n",
- " 'LV',\n",
- " 'LT',\n",
- " 'LU',\n",
- " 'MY',\n",
- " 'MT',\n",
- " 'NL',\n",
- " 'NZ',\n",
- " 'NI',\n",
- " 'NO',\n",
- " 'PA',\n",
- " 'PY',\n",
- " 'PE',\n",
- " 'PH',\n",
- " 'PL',\n",
- " 'PT',\n",
- " 'SG',\n",
- " 'SK',\n",
- " 'ES',\n",
- " 'SE',\n",
- " 'CH',\n",
- " 'TW',\n",
- " 'TR',\n",
- " 'UY',\n",
- " 'US',\n",
- " 'GB',\n",
- " 'AD',\n",
- " 'LI',\n",
- " 'MC',\n",
- " 'ID',\n",
- " 'TH',\n",
- " 'VN',\n",
- " 'RO',\n",
- " 'IL',\n",
- " 'ZA',\n",
- " 'SA',\n",
- " 'AE',\n",
- " 'BH',\n",
- " 'QA',\n",
- " 'OM',\n",
- " 'KW',\n",
- " 'EG',\n",
- " 'TN',\n",
- " 'LB',\n",
- " 'JO',\n",
- " 'PS',\n",
- " 'IN',\n",
- " 'BY',\n",
- " 'KZ',\n",
- " 'MD',\n",
- " 'UA',\n",
- " 'AL',\n",
- " 'BA',\n",
- " 'HR',\n",
- " 'ME',\n",
- " 'MK',\n",
- " 'RS',\n",
- " 'SI',\n",
- " 'KR',\n",
- " 'BD',\n",
- " 'PK',\n",
- " 'LK',\n",
- " 'GH',\n",
- " 'KE',\n",
- " 'NG',\n",
- " 'TZ',\n",
- " 'UG',\n",
- " 'AG',\n",
- " 'AM',\n",
- " 'BS',\n",
- " 'BB',\n",
- " 'BZ',\n",
- " 'BT',\n",
- " 'BW',\n",
- " 'BF',\n",
- " 'CV',\n",
- " 'CW',\n",
- " 'DM',\n",
- " 'FJ',\n",
- " 'GM',\n",
- " 'GD',\n",
- " 'GW',\n",
- " 'GY',\n",
- " 'HT',\n",
- " 'JM',\n",
- " 'KI',\n",
- " 'LS',\n",
- " 'LR',\n",
- " 'MW',\n",
- " 'MV',\n",
- " 'ML',\n",
- " 'MH',\n",
- " 'FM',\n",
- " 'NA',\n",
- " 'NR',\n",
- " 'NE',\n",
- " 'PW',\n",
- " 'PG',\n",
- " 'WS',\n",
- " 'ST',\n",
- " 'SN',\n",
- " 'SC',\n",
- " 'SL',\n",
- " 'SB',\n",
- " 'KN',\n",
- " 'LC',\n",
- " 'VC',\n",
- " 'SR',\n",
- " 'TL',\n",
- " 'TO',\n",
- " 'TT',\n",
- " 'TV',\n",
- " 'AZ',\n",
- " 'BN',\n",
- " 'BI',\n",
- " 'KH',\n",
- " 'CM',\n",
- " 'TD',\n",
- " 'KM',\n",
- " 'GQ',\n",
- " 'SZ',\n",
- " 'GA',\n",
- " 'GN',\n",
- " 'KG',\n",
- " 'LA',\n",
- " 'MO',\n",
- " 'MR',\n",
- " 'MN',\n",
- " 'NP',\n",
- " 'RW',\n",
- " 'TG',\n",
- " 'UZ',\n",
- " 'ZW',\n",
- " 'BJ',\n",
- " 'MG',\n",
- " 'MU',\n",
- " 'MZ',\n",
- " 'AO',\n",
- " 'CI',\n",
- " 'DJ',\n",
- " 'ZM',\n",
- " 'CD',\n",
- " 'CG',\n",
- " 'IQ',\n",
- " 'TJ',\n",
- " 'VE',\n",
- " 'XK'],\n",
- " 'external_urls': {'spotify': 'https://open.spotify.com/album/0uRFz92JmjwDbZbB7hEBIr'},\n",
- " 'href': 'https://api.spotify.com/v1/albums/0uRFz92JmjwDbZbB7hEBIr',\n",
- " 'id': '0uRFz92JmjwDbZbB7hEBIr',\n",
- " 'images': [{'height': 640,\n",
- " 'url': 'https://i.scdn.co/image/ab67616d0000b2734a6c0376235e5aa44e59d2c2',\n",
- " 'width': 640},\n",
- " {'height': 300,\n",
- " 'url': 'https://i.scdn.co/image/ab67616d00001e024a6c0376235e5aa44e59d2c2',\n",
- " 'width': 300},\n",
- " {'height': 64,\n",
- " 'url': 'https://i.scdn.co/image/ab67616d000048514a6c0376235e5aa44e59d2c2',\n",
- " 'width': 64}],\n",
- " 'name': 'Picture Show',\n",
- " 'release_date': '2012-01-01',\n",
- " 'release_date_precision': 'day',\n",
- " 'total_tracks': 11,\n",
- " 'type': 'album',\n",
- " 'uri': 'spotify:album:0uRFz92JmjwDbZbB7hEBIr'},\n",
- " 'artists': [{'external_urls': {'spotify': 'https://open.spotify.com/artist/0RpddSzUHfncUWNJXKOsjy'},\n",
- " 'href': 'https://api.spotify.com/v1/artists/0RpddSzUHfncUWNJXKOsjy',\n",
- " 'id': '0RpddSzUHfncUWNJXKOsjy',\n",
- " 'name': 'Neon Trees',\n",
- " 'type': 'artist',\n",
- " 'uri': 'spotify:artist:0RpddSzUHfncUWNJXKOsjy'}],\n",
- " 'available_markets': ['AR',\n",
- " 'AU',\n",
- " 'AT',\n",
- " 'BE',\n",
- " 'BO',\n",
- " 'BR',\n",
- " 'BG',\n",
- " 'CA',\n",
- " 'CL',\n",
- " 'CO',\n",
- " 'CR',\n",
- " 'CY',\n",
- " 'CZ',\n",
- " 'DK',\n",
- " 'DO',\n",
- " 'DE',\n",
- " 'EC',\n",
- " 'EE',\n",
- " 'SV',\n",
- " 'FI',\n",
- " 'FR',\n",
- " 'GR',\n",
- " 'GT',\n",
- " 'HN',\n",
- " 'HK',\n",
- " 'HU',\n",
- " 'IS',\n",
- " 'IE',\n",
- " 'IT',\n",
- " 'LV',\n",
- " 'LT',\n",
- " 'LU',\n",
- " 'MY',\n",
- " 'MT',\n",
- " 'NL',\n",
- " 'NZ',\n",
- " 'NI',\n",
- " 'NO',\n",
- " 'PA',\n",
- " 'PY',\n",
- " 'PE',\n",
- " 'PH',\n",
- " 'PL',\n",
- " 'PT',\n",
- " 'SG',\n",
- " 'SK',\n",
- " 'ES',\n",
- " 'SE',\n",
- " 'CH',\n",
- " 'TW',\n",
- " 'TR',\n",
- " 'UY',\n",
- " 'US',\n",
- " 'GB',\n",
- " 'AD',\n",
- " 'LI',\n",
- " 'MC',\n",
- " 'ID',\n",
- " 'TH',\n",
- " 'VN',\n",
- " 'RO',\n",
- " 'IL',\n",
- " 'ZA',\n",
- " 'SA',\n",
- " 'AE',\n",
- " 'BH',\n",
- " 'QA',\n",
- " 'OM',\n",
- " 'KW',\n",
- " 'EG',\n",
- " 'TN',\n",
- " 'LB',\n",
- " 'JO',\n",
- " 'PS',\n",
- " 'IN',\n",
- " 'BY',\n",
- " 'KZ',\n",
- " 'MD',\n",
- " 'UA',\n",
- " 'AL',\n",
- " 'BA',\n",
- " 'HR',\n",
- " 'ME',\n",
- " 'MK',\n",
- " 'RS',\n",
- " 'SI',\n",
- " 'KR',\n",
- " 'BD',\n",
- " 'PK',\n",
- " 'LK',\n",
- " 'GH',\n",
- " 'KE',\n",
- " 'NG',\n",
- " 'TZ',\n",
- " 'UG',\n",
- " 'AG',\n",
- " 'AM',\n",
- " 'BS',\n",
- " 'BB',\n",
- " 'BZ',\n",
- " 'BT',\n",
- " 'BW',\n",
- " 'BF',\n",
- " 'CV',\n",
- " 'CW',\n",
- " 'DM',\n",
- " 'FJ',\n",
- " 'GM',\n",
- " 'GD',\n",
- " 'GW',\n",
- " 'GY',\n",
- " 'HT',\n",
- " 'JM',\n",
- " 'KI',\n",
- " 'LS',\n",
- " 'LR',\n",
- " 'MW',\n",
- " 'MV',\n",
- " 'ML',\n",
- " 'MH',\n",
- " 'FM',\n",
- " 'NA',\n",
- " 'NR',\n",
- " 'NE',\n",
- " 'PW',\n",
- " 'PG',\n",
- " 'WS',\n",
- " 'ST',\n",
- " 'SN',\n",
- " 'SC',\n",
- " 'SL',\n",
- " 'SB',\n",
- " 'KN',\n",
- " 'LC',\n",
- " 'VC',\n",
- " 'SR',\n",
- " 'TL',\n",
- " 'TO',\n",
- " 'TT',\n",
- " 'TV',\n",
- " 'AZ',\n",
- " 'BN',\n",
- " 'BI',\n",
- " 'KH',\n",
- " 'CM',\n",
- " 'TD',\n",
- " 'KM',\n",
- " 'GQ',\n",
- " 'SZ',\n",
- " 'GA',\n",
- " 'GN',\n",
- " 'KG',\n",
- " 'LA',\n",
- " 'MO',\n",
- " 'MR',\n",
- " 'MN',\n",
- " 'NP',\n",
- " 'RW',\n",
- " 'TG',\n",
- " 'UZ',\n",
- " 'ZW',\n",
- " 'BJ',\n",
- " 'MG',\n",
- " 'MU',\n",
- " 'MZ',\n",
- " 'AO',\n",
- " 'CI',\n",
- " 'DJ',\n",
- " 'ZM',\n",
- " 'CD',\n",
- " 'CG',\n",
- " 'IQ',\n",
- " 'TJ',\n",
- " 'VE',\n",
- " 'XK'],\n",
- " 'disc_number': 1,\n",
- " 'duration_ms': 177280,\n",
- " 'episode': False,\n",
- " 'explicit': True,\n",
- " 'external_ids': {'isrc': 'USUM71119189'},\n",
- " 'external_urls': {'spotify': 'https://open.spotify.com/track/2iUmqdfGZcHIhS3b9E9EWq'},\n",
- " 'href': 'https://api.spotify.com/v1/tracks/2iUmqdfGZcHIhS3b9E9EWq',\n",
- " 'id': '2iUmqdfGZcHIhS3b9E9EWq',\n",
- " 'is_local': False,\n",
- " 'name': 'Everybody Talks',\n",
- " 'popularity': 81,\n",
- " 'preview_url': None,\n",
- " 'track': True,\n",
- " 'track_number': 3,\n",
- " 'type': 'track',\n",
- " 'uri': 'spotify:track:2iUmqdfGZcHIhS3b9E9EWq'},\n",
- " 'video_thumbnail': {'url': None}}],\n",
- " 'limit': 100,\n",
- " 'next': None,\n",
- " 'offset': 0,\n",
- " 'previous': None,\n",
- " 'total': 1},\n",
- " 'type': 'playlist',\n",
- " 'uri': 'spotify:playlist:1o95b3Y5b5szr7qJ7DUx1E'}"
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "playlist_spotify = client_spotify.create_playlist(\n",
- " \"Minim\", \n",
- " description=\"A playlist created using Minim.\",\n",
- " public=False\n",
- ")\n",
- "client_spotify.change_playlist_details(playlist_spotify[\"id\"], public=True)\n",
- "client_spotify.add_playlist_items(playlist_spotify[\"id\"], \n",
- " [f\"spotify:track:{track_spotify['id']}\"])\n",
- "playlist_spotify = client_spotify.get_playlist(playlist_spotify[\"id\"])\n",
- "# remove personal identifying information\n",
- "playlist_spotify[\"owner\"] = playlist_spotify[\"tracks\"][\"items\"][0][\"added_by\"] = None\n",
- "playlist_spotify"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {},
- "outputs": [],
- "source": [
- "client_spotify.unfollow_playlist(playlist_spotify[\"id\"])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "###### Private TIDAL API"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{'playlist': {'uuid': 'f4d88c7b-40ca-4264-95ab-7831a7c916e3',\n",
- " 'type': 'USER',\n",
- " 'creator': None,\n",
- " 'contentBehavior': 'UNRESTRICTED',\n",
- " 'sharingLevel': 'PUBLIC',\n",
- " 'status': 'READY',\n",
- " 'source': 'DEFAULT',\n",
- " 'title': 'Minim',\n",
- " 'description': 'A playlist created using Minim.',\n",
- " 'image': 'c856783e-1888-4578-ae8f-cc303357904a',\n",
- " 'squareImage': '34a871ed-e1f3-4150-ae64-5ab98a33d25a',\n",
- " 'url': 'http://www.tidal.com/playlist/f4d88c7b-40ca-4264-95ab-7831a7c916e3',\n",
- " 'created': '2023-11-12T03:35:03.480+0000',\n",
- " 'lastUpdated': '2023-11-12T03:35:04.032+0000',\n",
- " 'lastItemAddedAt': '2023-11-12T03:35:04.032+0000',\n",
- " 'duration': 177,\n",
- " 'numberOfTracks': 1,\n",
- " 'numberOfVideos': 0,\n",
- " 'promotedArtists': [],\n",
- " 'trn': 'trn:playlist:f4d88c7b-40ca-4264-95ab-7831a7c916e3'},\n",
- " 'followInfo': {'nrOfFollowers': 0,\n",
- " 'tidalResourceName': 'trn:playlist:f4d88c7b-40ca-4264-95ab-7831a7c916e3',\n",
- " 'followed': True,\n",
- " 'followType': 'PLAYLIST'},\n",
- " 'profile': None}"
- ]
- },
- "execution_count": 23,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "playlist_tidal_private = client_tidal_private.create_playlist(\n",
- " \"Minim\", \n",
- " description=\"A playlist created using Minim.\",\n",
- " public=False\n",
- ")\n",
- "client_tidal_private.set_playlist_privacy(playlist_tidal_private[\"data\"][\"uuid\"], \n",
- " True)\n",
- "client_tidal_private.add_playlist_items(playlist_tidal_private[\"data\"][\"uuid\"], \n",
- " track_tidal_private[\"id\"])\n",
- "playlist_tidal_private = client_tidal_private.get_user_playlist(\n",
- " playlist_tidal_private[\"data\"][\"uuid\"]\n",
- ")\n",
- "# remove personal identifying information\n",
- "playlist_tidal_private[\"playlist\"][\"creator\"] = playlist_tidal_private[\"profile\"] = None\n",
- "playlist_tidal_private"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {},
- "outputs": [],
- "source": [
- "client_tidal_private.delete_playlist(playlist_tidal_private[\"playlist\"][\"uuid\"])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Audio file handlers"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {},
- "outputs": [],
- "source": [
- "from pathlib import Path\n",
- "from minim.audio import Audio, FLACAudio, MP3Audio, MP4Audio, OggAudio, WAVEAudio"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Minim uses [Mutagen](https://mutagen.readthedocs.io/en/latest/) to load and edit audio files and [FFmpeg](https://ffmpeg.org/) to convert between different audio formats. Currently, the most common audio formats, such as AAC, ALAC, FLAC, MP3, Opus, Vorbis, and WAVE, are supported.\n",
- "\n",
- "#### Examples\n",
- "\n",
- "##### Load and edit an audio file\n",
- "\n",
- "To load an audio file, pass the filename as a `str` or a `pathlib.Path` object either to the `minim.audio.Audio` constructor for Minim to automatically detect the audio format:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {},
- "outputs": [],
- "source": [
- "file = Path().resolve().parents[2] / \"tests/data/middle_c.wav\"\n",
- "middle_c = Audio(file)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "or the specific class for the audio format if known (in this case, `minim.audio.WAVEAudio`):\n",
- "\n",
- "```python\n",
- "middle_c = WAVEAudio(Path().resolve().parents[2] / \"tests/data/middle_c.wav\")\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "For this example, both approaches return a `minim.audio.WAVEAudio` object:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "minim.audio.WAVEAudio"
- ]
- },
- "execution_count": 27,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(middle_c)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The metadata stored in the audio file can be accessed using dot notation or `getattr()`:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 28,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Title: Middle C\n",
- "Album: Minim\n",
- "Artist: Square Wave\n",
- "Genre: Game\n",
- "Codec: lpcm\n",
- "Bit depth: 24\n"
- ]
- }
- ],
- "source": [
- "for attr in [\"title\", \"album\", \"artist\", \"genre\", \"codec\", \"bit_depth\"]:\n",
- " print(f\"{attr.capitalize().replace('_', ' ')}: {getattr(middle_c, attr)}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "and edited similarly using dot notation or `setattr()`:\n",
- "\n",
- "```python\n",
- "middle_c.title = \"Middle C (261.63 Hz)\"\n",
- "middle_c.write_metadata()\n",
- "```\n",
- "\n",
- "If changes are made, don't forget to write them to file using `minim.audio.Audio.write_metadata()`.\n",
- "\n",
- "##### Convert between audio formats\n",
- "\n",
- "Conversion between the supported audio formats is powered by FFmpeg.\n",
- "\n",
- "To re-encode the previous WAVE audio using the ALAC codec and store it in a MP4 container, use the `minim.audio.Audio.convert()` method:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 29,
- "metadata": {
- "tags": [
- "hide-output"
- ]
- },
- "outputs": [
- {
- "name": "stderr",
- "output_type": "stream",
- "text": [
- "size= 116kB time=00:00:01.02 bitrate= 930.3kbits/s speed= 164x \n"
- ]
- }
- ],
- "source": [
- "middle_c.convert(\"alac\", \"middle_c_alac\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The call above not only converts the WAVE audio into ALAC audio, but also updates the variable `middle_c` to now point to a `minim.audio.MP4Audio` file handler for the new file `middle_c.m4a` and maintains the metadata:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 30,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "minim.audio.MP4Audio"
- ]
- },
- "execution_count": 30,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "type(middle_c)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 31,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Title: Middle C\n",
- "Album: Minim\n",
- "Artist: Square Wave\n",
- "Genre: Game\n",
- "Codec: alac\n",
- "Bit depth: 24\n"
- ]
- }
- ],
- "source": [
- "for attr in [\"title\", \"album\", \"artist\", \"genre\", \"codec\", \"bit_depth\"]:\n",
- " print(f\"{attr.capitalize().replace('_', ' ')}: {getattr(middle_c, attr)}\")"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "base",
- "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.11.6"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/docs/api.html b/docs/api.html
index 45c16e5..f6b978c 100644
--- a/docs/api.html
+++ b/docs/api.html
@@ -9,7 +9,7 @@
<no title> - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.audio.Audio.html b/docs/api/minim.audio.Audio.html
index 033ad2e..48cb057 100644
--- a/docs/api/minim.audio.Audio.html
+++ b/docs/api/minim.audio.Audio.html
@@ -9,7 +9,7 @@
Audio - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.audio.FLACAudio.html b/docs/api/minim.audio.FLACAudio.html
index e5e7075..151c4aa 100644
--- a/docs/api/minim.audio.FLACAudio.html
+++ b/docs/api/minim.audio.FLACAudio.html
@@ -9,7 +9,7 @@
FLACAudio - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.audio.MP3Audio.html b/docs/api/minim.audio.MP3Audio.html
index 36d3e37..4fed614 100644
--- a/docs/api/minim.audio.MP3Audio.html
+++ b/docs/api/minim.audio.MP3Audio.html
@@ -9,7 +9,7 @@
MP3Audio - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.audio.MP4Audio.html b/docs/api/minim.audio.MP4Audio.html
index 857622a..c6965bd 100644
--- a/docs/api/minim.audio.MP4Audio.html
+++ b/docs/api/minim.audio.MP4Audio.html
@@ -9,7 +9,7 @@
MP4Audio - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.audio.OGGAudio.html b/docs/api/minim.audio.OGGAudio.html
index 370c2de..3f34150 100644
--- a/docs/api/minim.audio.OGGAudio.html
+++ b/docs/api/minim.audio.OGGAudio.html
@@ -9,7 +9,7 @@
OggAudio - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
@@ -238,11 +238,21 @@ OggAudio
-
class minim.audio.OggAudio(*args, **kwargs)[source]#
Bases: Audio
, _VorbisComment
-An Ogg audio file.
+Ogg audio file handler.
+
+See also
+For a full list of attributes and their descriptions, see
+Audio
.
+
- Parameters:
-- filenamestr
WAVE audio filename.
+- filestr or pathlib.Path
Ogg audio file.
+
+- codecstr, optional
Audio codec. If not specified, it will be determined
+automatically.
+Valid values: "flac"
, "opus"
, or
+"vorbis"
.
- patterntuple, keyword-only, optional
Regular expression search pattern and the corresponding metadata
field(s).
@@ -292,10 +302,10 @@ OggAudio
Populate tags using data retrieved from the Qobuz API.
-Populate tags using data retrieved from the Spotify Web API.
+Populate tags using data retrieved from the Spotify Web API and Spotify Lyrics service.
-Populate tags using data retrieved from the private TIDAL API.
+Populate tags using data retrieved from the TIDAL API.
Write metadata to file.
@@ -351,7 +361,7 @@ OggAudio
"mp3"
for a MP3 audio container, which only
supports MP3 audio.
"ogg"
for an Ogg audio container, which
-supports Opus and Vorbis audio.
+supports FLAC, Opus, and Vorbis audio.
"wav"
or "wave"
for an WAVE audio
container, which only supports LPCM audio.
@@ -364,20 +374,20 @@ OggAudio
Defaults:
-"-c:a aac -b:a 256k"
(or
+
AAC audio: "-c:a aac -b:a 256k"
(or
"-c:a libfdk_aac -b:a 256k"
if FFmpeg was
-compiled with --enable-libfdk-aac
) for AAC
-audio.
-"-c:a alac"
for ALAC audio.
-"-c:a flac"
for FLAC audio.
-"-c:a libmp3lame -q:a 0"
for MP3 audio.
-"-c:a libopus -b:a 256k -vn"
for Opus audio.
-"-c:a vorbis -strict experimental -vn"
(or
+compiled with --enable-libfdk-aac
)
+ALAC audio: "-c:a alac"
+FLAC audio: "-c:a flac"
+MP3 audio: "-c:a libmp3lame -q:a 0"
+Opus audio: "-c:a libopus -b:a 256k -vn"
+Vorbis audio:
+"-c:a vorbis -strict experimental -vn"
(or
"-c:a libvorbis -vn"
if FFmpeg was compiled
-with --enable-libvorbis
) for Vorbis audio.
-"-c:a pcm_s16le"
or "-c:a pcm_s24le"
-for WAVE audio, depending on the bit depth of the
-original audio file.
+with --enable-libvorbis
)
+WAVE audio: "-c:a pcm_s16le"
or
+"-c:a pcm_s24le"
, depending on the bit depth of
+the original audio file.
@@ -394,7 +404,7 @@ OggAudio
-
-set_metadata_using_itunes(data: dict, *, album_data: dict = None, artwork_size: int | str = 1400, artwork_format: str = 'jpg', overwrite: bool = False) → None#
+set_metadata_using_itunes(data: dict[str, Any], *, album_data: dict[str, Any] = None, artwork_size: int | str = 1400, artwork_format: str = 'jpg', overwrite: bool = False) → None#
Populate tags using data retrieved from the iTunes Search API.
- Parameters:
@@ -425,37 +435,18 @@ OggAudio
-
-set_metadata_using_qobuz(data: dict, main_artist: str | list[str] = None, feat_artist: str | list[str] = None, composer: str | list[str] = None, artwork: bytes = None, comment: str = None, overwrite: bool = False) → None#
+set_metadata_using_qobuz(data: dict[str, Any], *, artwork_size: str = 'large', comment: str = None, overwrite: bool = False) → None#
Populate tags using data retrieved from the Qobuz API.
-
-Attention
-This method is pending a major refactor.
-
- Parameters:
- datadict
Information about the track in JSON format obtained using
-the Qobuz API via minim.qobuz.PrivateAPI.get_track()
.
-
-- main_artiststr or list, keyword-only, optional
Information about the track’s main artists obtained using
the Qobuz API via minim.qobuz.PrivateAPI.get_track()
-and/or minim.qobuz.PrivateAPI.get_track_credits()
. If not
-provided, only information about the primary artist will be
-available.
-
-- feat_artiststr or list, keyword-only, optional
Information about the track’s featured artists obtained
-using the Qobuz API via minim.qobuz.PrivateAPI.get_track()
-and/or minim.qobuz.PrivateAPI.get_track_credits()
. If not
-provided, the featured artists will not be listed in the
-track’s title.
-
-- composerstr or list, keyword-only, optional
Information about the track’s composers obtained using the
-Qobuz API via minim.qobuz.PrivateAPI.get_track()
and/or
-minim.qobuz.PrivateAPI.get_track_credits()
. If not
-provided, songwriting credits are unavailable.
+or minim.qobuz.PrivateAPI.search()
.
-- artworkstr, keyword-only, optional
Qobuz URL of the track cover art obtained using the Qobuz
-API via minim.qobuz.PrivateAPI.get_track()
.
+- artwork_sizestr, keyword-only, default:
"large"
Artwork size.
+Valid values: "large"
, "small"
, or
+"thumbnail"
.
- commentstr, keyword-only, optional
Comment or description.
@@ -468,8 +459,9 @@ OggAudio
-
-set_metadata_using_spotify(data: dict, *, audio_features: dict[str, Any] = None, lyrics: str | dict[str, Any] = None, overwrite: bool = False) → None#
-Populate tags using data retrieved from the Spotify Web API.
+set_metadata_using_spotify(data: dict[str, Any], *, audio_features: dict[str, Any] = None, lyrics: str | dict[str, Any] = None, overwrite: bool = False) → None#
+Populate tags using data retrieved from the Spotify Web API
+and Spotify Lyrics service.
- Parameters:
@@ -483,7 +475,7 @@ OggAudio
If not provided, tempo information is unavailable.
- lyricsstr or dict, keyword-only
Information about the track’s formatted or time-synced
-lyrics obtained using the Spotify Lyrics API via
+lyrics obtained using the Spotify Lyrics service via
minim.spotify.PrivateLyricsService.get_lyrics()
. If not
provided, lyrics are unavailable.
@@ -496,32 +488,36 @@ OggAudio
-
-set_metadata_using_tidal(data: dict, *, album_data: dict = None, composer: str | list[str] = None, artwork: bytes = None, lyrics: dict[str, Any] = None, comment: str = None, overwrite: bool = False) → None#
-Populate tags using data retrieved from the private TIDAL API.
-
-Attention
-This method is pending a major refactor.
-
+set_metadata_using_tidal(data: dict[str, Any], *, album_data: dict[str, Any] = None, artwork_size: int = 1280, composers: str | list[str] | dict[str, Any] = None, lyrics: dict[str, Any] = None, comment: str = None, overwrite: bool = False) → None#
+Populate tags using data retrieved from the TIDAL API.
- Parameters:
- datadict
Information about the track in JSON format obtained using
-the TIDAL API via minim.tidal.PrivateAPI.get_track()
.
+the TIDAL API via minim.tidal.API.get_track()
,
+minim.tidal.API.search()
,
+minim.tidal.PrivateAPI.get_track()
, or
+minim.tidal.PrivateAPI.search()
.
- album_datadict, keyword-only, optional
Information about the track’s album in JSON format obtained
-using the TIDAL API via
-minim.tidal.PrivateAPI.get_album()
. If not provided,
-album artist, copyright, and disc and track numbering
-information is unavailable.
-
-- composerstr or list, keyword-only, optional
Information about the track’s composers obtained using the
-TIDAL API via
-minim.tidal.PrivateAPI.get_track_composers()
. If not
+using the TIDAL API via minim.tidal.API.get_album()
,
+minim.tidal.API.search()
,
+minim.tidal.PrivateAPI.get_album()
, or
+minim.tidal.PrivateAPI.search()
. If not provided,
+album artist and disc and track numbering information is
+unavailable.
+
+- artwork_sizeint, keyword-only, default:
1280
Maximum artwork size in pixels.
+Valid values: artwork_size should be between
+80
and 1280
.
+
+- composersstr, list, or dict, keyword-only, optional
Information about the track’s composers in a formatted
+str, a list, or a dict obtained using the TIDAL API
+via minim.tidal.PrivateAPI.get_track_composers()
,
+minim.tidal.PrivateAPI.get_track_contributors()
, or
+minim.tidal.PrivateAPI.get_track_credits()
. If not
provided, songwriting credits are unavailable.
-- artworkstr, keyword-only, optional
TIDAL URL of the track cover art obtained using the TIDAL
-API via minim.tidal.PrivateAPI.get_image()
.
-
- lyricsstr or dict, keyword-only, optional
The track’s lyrics obtained using the TIDAL API via
minim.tidal.PrivateAPI.get_track_lyrics()
.
diff --git a/docs/api/minim.audio.WAVEAudio.html b/docs/api/minim.audio.WAVEAudio.html
index a96a035..55192ae 100644
--- a/docs/api/minim.audio.WAVEAudio.html
+++ b/docs/api/minim.audio.WAVEAudio.html
@@ -9,7 +9,7 @@
WAVEAudio - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.audio.html b/docs/api/minim.audio.html
index 3b15b06..921d5b5 100644
--- a/docs/api/minim.audio.html
+++ b/docs/api/minim.audio.html
@@ -9,7 +9,7 @@
audio - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.html b/docs/api/minim.html
index 8ba1c63..5d21b0b 100644
--- a/docs/api/minim.html
+++ b/docs/api/minim.html
@@ -9,7 +9,7 @@
minim - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.itunes.SearchAPI.html b/docs/api/minim.itunes.SearchAPI.html
index 2934c0c..fa9980b 100644
--- a/docs/api/minim.itunes.SearchAPI.html
+++ b/docs/api/minim.itunes.SearchAPI.html
@@ -9,7 +9,7 @@
SearchAPI - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.itunes.html b/docs/api/minim.itunes.html
index e705b94..127f503 100644
--- a/docs/api/minim.itunes.html
+++ b/docs/api/minim.itunes.html
@@ -9,7 +9,7 @@
itunes - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.qobuz.PrivateAPI.html b/docs/api/minim.qobuz.PrivateAPI.html
index be704be..c15059f 100644
--- a/docs/api/minim.qobuz.PrivateAPI.html
+++ b/docs/api/minim.qobuz.PrivateAPI.html
@@ -9,7 +9,7 @@
PrivateAPI - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.qobuz.html b/docs/api/minim.qobuz.html
index a9875bd..25013c6 100644
--- a/docs/api/minim.qobuz.html
+++ b/docs/api/minim.qobuz.html
@@ -9,7 +9,7 @@
qobuz - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.spotify.PrivateLyricsService.html b/docs/api/minim.spotify.PrivateLyricsService.html
index 6da8b68..c39718e 100644
--- a/docs/api/minim.spotify.PrivateLyricsService.html
+++ b/docs/api/minim.spotify.PrivateLyricsService.html
@@ -9,7 +9,7 @@
PrivateLyricsService - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.spotify.WebAPI.html b/docs/api/minim.spotify.WebAPI.html
index 43ceac5..a8c2e7b 100644
--- a/docs/api/minim.spotify.WebAPI.html
+++ b/docs/api/minim.spotify.WebAPI.html
@@ -9,7 +9,7 @@
WebAPI - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.spotify.html b/docs/api/minim.spotify.html
index 83d893f..3b472ba 100644
--- a/docs/api/minim.spotify.html
+++ b/docs/api/minim.spotify.html
@@ -9,7 +9,7 @@
spotify - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.tidal.API.html b/docs/api/minim.tidal.API.html
index c152c38..353e821 100644
--- a/docs/api/minim.tidal.API.html
+++ b/docs/api/minim.tidal.API.html
@@ -9,7 +9,7 @@
API - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.tidal.PrivateAPI.html b/docs/api/minim.tidal.PrivateAPI.html
index a60bcbd..7adc02e 100644
--- a/docs/api/minim.tidal.PrivateAPI.html
+++ b/docs/api/minim.tidal.PrivateAPI.html
@@ -9,7 +9,7 @@
PrivateAPI - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.tidal.html b/docs/api/minim.tidal.html
index 77d2c6d..3708b0f 100644
--- a/docs/api/minim.tidal.html
+++ b/docs/api/minim.tidal.html
@@ -9,7 +9,7 @@
tidal - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.utility.html b/docs/api/minim.utility.html
index 5776083..7efa25e 100644
--- a/docs/api/minim.utility.html
+++ b/docs/api/minim.utility.html
@@ -9,7 +9,7 @@
utility - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.utility.levenshtein_ratio.html b/docs/api/minim.utility.levenshtein_ratio.html
index d14fa36..ac4a14c 100644
--- a/docs/api/minim.utility.levenshtein_ratio.html
+++ b/docs/api/minim.utility.levenshtein_ratio.html
@@ -9,7 +9,7 @@
levenshtein_ratio - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/api/minim.utility.multivalue_formatter.html b/docs/api/minim.utility.multivalue_formatter.html
index 7a4fa6e..1c4e710 100644
--- a/docs/api/minim.utility.multivalue_formatter.html
+++ b/docs/api/minim.utility.multivalue_formatter.html
@@ -9,7 +9,7 @@
multivalue_formatter - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@
- Home
-- Getting Started
+- Getting Started
- User Guide
- API Reference
- audio
diff --git a/docs/genindex.html b/docs/genindex.html
index 55e7733..d2a11de 100644
--- a/docs/genindex.html
+++ b/docs/genindex.html
@@ -7,7 +7,7 @@
Index - Minim 1.0.0 documentation
-
+
diff --git a/docs/guide.html b/docs/guide.html
index 2f15f62..8467ba8 100644
--- a/docs/guide.html
+++ b/docs/guide.html
@@ -3,13 +3,13 @@
-
+
User Guide - Minim 1.0.0 documentation
-
+
@@ -161,7 +161,7 @@