# PR Description 1. `adjust_playback_position` - Adjust the playback position within the currently playing track 2. `skip_to_previous_track` - Skip to the previous track in the user's queue, if any 3. `skip_to_next_track` - Skip to the next track in the user's queue, if any 4. `pause_playback` - Pause the currently playing track, if any 5. `resume_playback` - Resume the currently playing track, if any 6. `start_tracks_playback_by_id` - Start playback of a list of tracks (songs) 7. `get_playback_state` - Get information about the user's current playback state, including track or episode, and active device 8. `get_currently_playing` - Get information about the user's currently playing track 9. `get_track_from_id` - Get information about a track 10. `get_recommendations` - Get track (song) recommendations based on seed artists, genres, and tracks, and multiple target audio stats 11. `get_tracks_audio_features` - Get audio features for a list of tracks (songs) ---------------------- My favorite feature of this toolkit is 1. Start playing my favorite song 2. Get the song that I'm currently playing 3. Get audio features of that song 4. Ask for recommended songs that are similar to it 5. Jam out ------------
136 lines
4.9 KiB
Python
136 lines
4.9 KiB
Python
from typing import Annotated, Optional
|
|
|
|
from arcade.sdk import ToolContext, tool
|
|
from arcade.sdk.auth import Spotify
|
|
from arcade_spotify.tools.utils import (
|
|
get_url,
|
|
send_spotify_request,
|
|
)
|
|
|
|
|
|
@tool(requires_auth=Spotify())
|
|
async def get_track_from_id(
|
|
context: ToolContext,
|
|
track_id: Annotated[str, "The Spotify ID of the track"],
|
|
) -> Annotated[dict, "Information about the track"]:
|
|
"""Get information about a track"""
|
|
url = get_url("tracks_get_track", track_id=track_id)
|
|
|
|
response = await send_spotify_request(context, "GET", url)
|
|
response.raise_for_status()
|
|
return response.json()
|
|
|
|
|
|
@tool(requires_auth=Spotify())
|
|
async def get_recommendations(
|
|
context: ToolContext,
|
|
seed_artists: Annotated[
|
|
list[str], "A list of Spotify artist IDs to seed the recommendations with"
|
|
],
|
|
seed_genres: Annotated[
|
|
list[str], "A list of Spotify genre IDs to seed the recommendations with"
|
|
],
|
|
seed_tracks: Annotated[
|
|
list[str], "A list of Spotify track IDs to seed the recommendations with"
|
|
],
|
|
limit: Annotated[int, "The maximum number of recommended tracks to return"] = 5,
|
|
target_acousticness: Annotated[
|
|
Optional[float],
|
|
"The target acousticness of the recommended tracks (between 0 and 1)",
|
|
] = None,
|
|
target_danceability: Annotated[
|
|
Optional[float],
|
|
"The target danceability of the recommended tracks (between 0 and 1)",
|
|
] = None,
|
|
target_duration_ms: Annotated[
|
|
Optional[int],
|
|
"The target duration of the recommended tracks in milliseconds",
|
|
] = None,
|
|
target_energy: Annotated[
|
|
Optional[float],
|
|
"The target energy of the recommended tracks (between 0 and 1)",
|
|
] = None,
|
|
target_instrumentalness: Annotated[
|
|
Optional[float],
|
|
"The target instrumentalness of the recommended tracks (between 0 and 1)",
|
|
] = None,
|
|
target_key: Annotated[
|
|
Optional[int],
|
|
"The target key of the recommended tracks (0-11)",
|
|
] = None,
|
|
target_liveness: Annotated[
|
|
Optional[float],
|
|
"The target liveness of the recommended tracks (between 0 and 1)",
|
|
] = None,
|
|
target_loudness: Annotated[
|
|
Optional[float],
|
|
"The target loudness of the recommended tracks (in decibels)",
|
|
] = None,
|
|
target_mode: Annotated[
|
|
Optional[int],
|
|
"The target mode of the recommended tracks (0 or 1)",
|
|
] = None,
|
|
target_popularity: Annotated[
|
|
Optional[int],
|
|
"The target popularity of the recommended tracks (0-100)",
|
|
] = None,
|
|
target_speechiness: Annotated[
|
|
Optional[float],
|
|
"The target speechiness of the recommended tracks (between 0 and 1)",
|
|
] = None,
|
|
target_tempo: Annotated[
|
|
Optional[float],
|
|
"The target tempo of the recommended tracks (in beats per minute)",
|
|
] = None,
|
|
target_time_signature: Annotated[
|
|
Optional[int],
|
|
"The target time signature of the recommended tracks",
|
|
] = None,
|
|
target_valence: Annotated[
|
|
Optional[float],
|
|
"The target valence of the recommended tracks (between 0 and 1)",
|
|
] = None,
|
|
) -> Annotated[dict, "A list of recommended tracks"]:
|
|
"""Get track (song) recommendations based on seed artists, genres, and tracks
|
|
If a provided target value is outside of the expected range, it will clamp to the nearest valid value.
|
|
"""
|
|
url = get_url("tracks_get_recommendations")
|
|
params = {
|
|
"seed_artists": seed_artists,
|
|
"seed_genres": seed_genres,
|
|
"seed_tracks": seed_tracks,
|
|
"limit": limit,
|
|
"target_acousticness": target_acousticness,
|
|
"target_danceability": target_danceability,
|
|
"target_duration_ms": target_duration_ms,
|
|
"target_energy": target_energy,
|
|
"target_instrumentalness": target_instrumentalness,
|
|
"target_key": target_key,
|
|
"target_liveness": target_liveness,
|
|
"target_loudness": target_loudness,
|
|
"target_mode": target_mode,
|
|
"target_popularity": target_popularity,
|
|
"target_speechiness": target_speechiness,
|
|
"target_tempo": target_tempo,
|
|
"target_time_signature": target_time_signature,
|
|
"target_valence": target_valence,
|
|
}
|
|
params = {k: v for k, v in params.items() if v is not None}
|
|
|
|
response = await send_spotify_request(context, "GET", url, params=params)
|
|
response.raise_for_status()
|
|
return response.json()
|
|
|
|
|
|
@tool(requires_auth=Spotify())
|
|
async def get_tracks_audio_features(
|
|
context: ToolContext,
|
|
track_ids: Annotated[list[str], "A list of Spotify track (song) IDs"],
|
|
) -> Annotated[dict, "A list of audio features for the tracks"]:
|
|
"""Get audio features for a list of tracks (songs)"""
|
|
url = get_url("tracks_get_audio_features")
|
|
params = {"ids": ",".join(track_ids)}
|
|
|
|
response = await send_spotify_request(context, "GET", url, params=params)
|
|
response.raise_for_status()
|
|
return response.json()
|