Remove tools relying on deprecated Spotify endpoints (#196)

Spotify deprecated several endpoints in Nov, 2024. Two of them were
being used in Tracks tools. We're removing those from the Toolkit.

Spotify announcement:
https://developer.spotify.com/blog/2024-11-27-changes-to-the-web-api
Archive: https://archive.is/LMBe5
This commit is contained in:
Renato Byrro 2025-01-08 16:40:36 -03:00 committed by GitHub
parent cd837a363d
commit c5e29693e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 2 additions and 191 deletions

View file

@ -10,7 +10,5 @@ ENDPOINTS = {
"player_skip_to_previous": "/me/player/previous",
"player_seek_to_position": "/me/player/seek",
"tracks_get_track": "/tracks/{track_id}",
"tracks_get_recommendations": "/recommendations",
"tracks_get_audio_features": "/audio-features",
"search": "/search",
}

View file

@ -1,4 +1,4 @@
from typing import Annotated, Optional
from typing import Annotated
from arcade.sdk import ToolContext, tool
from arcade.sdk.auth import Spotify
@ -20,119 +20,3 @@ async def get_track_from_id(
response = await send_spotify_request(context, "GET", url)
response.raise_for_status()
return dict(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 dict(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 dict(response.json())

View file

@ -100,35 +100,6 @@ history_2 = [
{"role": "assistant", "content": 'The song now playing is "Tempestade" by Philó.'},
]
# This history is a conversation where the user asks for what is currently playing, and then asks for more information about the track, then asks for the audio features for the track.
history_3 = [
{"role": "user", "content": "get info about 14CQdqVFygEls6szbfwuTL"},
{
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "call_bFqQIQY89z82BXJqSXhlkiro",
"type": "function",
"function": {
"name": "Spotify_GetTrackFromId",
"arguments": '{"track_id":"14CQdqVFygEls6szbfwuTL"}',
},
}
],
},
{
"role": "tool",
"content": '{"album":{"album_type":"single","artists":[{"external_urls":{"spotify":"https://open.spotify.com/artist/4ev14fn325vhWuykve3QtA"},"href":"https://api.spotify.com/v1/artists/4ev14fn325vhWuykve3QtA","id":"4ev14fn325vhWuykve3QtA","name":"The Dawning","type":"artist","uri":"spotify:artist:4ev14fn325vhWuykve3QtA"}],"available_markets":["AR","AU","AT","BE","BO","BR","BG","CA","CL","CO","CR","CY","CZ","DK","DO","DE","EC","EE","SV","FI","FR","GR","GT","HN","HK","HU","IS","IE","IT","LV","LT","LU","MY","MT","MX","NL","NZ","NI","NO","PA","PY","PE","PH","PL","PT","SG","SK","ES","SE","CH","TW","TR","UY","US","GB","AD","LI","MC","ID","JP","TH","VN","RO","IL","ZA","SA","AE","BH","QA","OM","KW","EG","MA","DZ","TN","LB","JO","PS","IN","BY","KZ","MD","UA","AL","BA","HR","ME","MK","RS","SI","KR","BD","PK","LK","GH","KE","NG","TZ","UG","AG","AM","BS","BB","BZ","BT","BW","BF","CV","CW","DM","FJ","GM","GE","GD","GW","GY","HT","JM","KI","LS","LR","MW","MV","ML","MH","FM","NA","NR","NE","PW","PG","PR","WS","SM","ST","SN","SC","SL","SB","KN","LC","VC","SR","TL","TO","TT","TV","VU","AZ","BN","BI","KH","CM","TD","KM","GQ","SZ","GA","GN","KG","LA","MO","MR","MN","NP","RW","TG","UZ","ZW","BJ","MG","MU","MZ","AO","CI","DJ","ZM","CD","CG","IQ","LY","TJ","VE","ET","XK"],"external_urls":{"spotify":"https://open.spotify.com/album/2dmrP48hhdCIoxeYJFMSVO"},"href":"https://api.spotify.com/v1/albums/2dmrP48hhdCIoxeYJFMSVO","id":"2dmrP48hhdCIoxeYJFMSVO","images":[{"height":640,"url":"https://i.scdn.co/image/ab67616d0000b2730046525154a4201332796065","width":640},{"height":300,"url":"https://i.scdn.co/image/ab67616d00001e020046525154a4201332796065","width":300},{"height":64,"url":"https://i.scdn.co/image/ab67616d000048510046525154a4201332796065","width":64}],"name":"summer breeze","release_date":"2024-08-02","release_date_precision":"day","total_tracks":1,"type":"album","uri":"spotify:album:2dmrP48hhdCIoxeYJFMSVO"},"artists":[{"external_urls":{"spotify":"https://open.spotify.com/artist/4ev14fn325vhWuykve3QtA"},"href":"https://api.spotify.com/v1/artists/4ev14fn325vhWuykve3QtA","id":"4ev14fn325vhWuykve3QtA","name":"The Dawning","type":"artist","uri":"spotify:artist:4ev14fn325vhWuykve3QtA"}],"available_markets":["AR","AU","AT","BE","BO","BR","BG","CA","CL","CO","CR","CY","CZ","DK","DO","DE","EC","EE","SV","FI","FR","GR","GT","HN","HK","HU","IS","IE","IT","LV","LT","LU","MY","MT","MX","NL","NZ","NI","NO","PA","PY","PE","PH","PL","PT","SG","SK","ES","SE","CH","TW","TR","UY","US","GB","AD","LI","MC","ID","JP","TH","VN","RO","IL","ZA","SA","AE","BH","QA","OM","KW","EG","MA","DZ","TN","LB","JO","PS","IN","BY","KZ","MD","UA","AL","BA","HR","ME","MK","RS","SI","KR","BD","PK","LK","GH","KE","NG","TZ","UG","AG","AM","BS","BB","BZ","BT","BW","BF","CV","CW","DM","FJ","GM","GE","GD","GW","GY","HT","JM","KI","LS","LR","MW","MV","ML","MH","FM","NA","NR","NE","PW","PG","PR","WS","SM","ST","SN","SC","SL","SB","KN","LC","VC","SR","TL","TO","TT","TV","VU","AZ","BN","BI","KH","CM","TD","KM","GQ","SZ","GA","GN","KG","LA","MO","MR","MN","NP","RW","TG","UZ","ZW","BJ","MG","MU","MZ","AO","CI","DJ","ZM","CD","CG","IQ","LY","TJ","VE","ET","XK"],"disc_number":1,"duration_ms":165811,"explicit":false,"external_ids":{"isrc":"SE69N2406255"},"external_urls":{"spotify":"https://open.spotify.com/track/14CQdqVFygEls6szbfwuTL"},"href":"https://api.spotify.com/v1/tracks/14CQdqVFygEls6szbfwuTL","id":"14CQdqVFygEls6szbfwuTL","is_local":false,"name":"summer breeze","popularity":60,"preview_url":"https://p.scdn.co/mp3-preview/9b2ac80563d092f9b1d442f09635ccf646ccb3e0?cid=26913f34d26f4c16a15d5a93e309a1dc","track_number":1,"type":"track","uri":"spotify:track:14CQdqVFygEls6szbfwuTL"}',
"tool_call_id": "call_bFqQIQY89z82BXJqSXhlkiro",
"name": "Spotify_GetTrackFromId",
},
{
"role": "assistant",
"content": 'The track "Summer Breeze" by The Dawning is available on Spotify. Here are some details about the track:\n\n- **Artist:** [The Dawning](https://open.spotify.com/artist/4ev14fn325vhWuykve3QtA)\n- **Album:** [Summer Breeze](https://open.spotify.com/album/2dmrP48hhdCIoxeYJFMSVO) (Single)\n- **Release Date:** August 2, 2024\n- **Duration:** 2 minutes and 45 seconds\n- **Popularity:** 60\n- **ISRC:** SE69N2406255\n- **Explicit Content:** No\n\nThe track is available in numerous markets, including the US, UK, Canada, Australia, and many more. You can listen to a preview of the track [here](https://p.scdn.co/mp3-preview/9b2ac80563d092f9b1d442f09635ccf646ccb3e0?cid=26913f34d26f4c16a15d5a93e309a1dc).',
},
]
@tool_eval()
def spotify_tracks_eval_suite() -> EvalSuite:
@ -157,46 +128,4 @@ def spotify_tracks_eval_suite() -> EvalSuite:
additional_messages=history,
)
suite.add_case(
name="Get audio features for a track",
user_message="what bpm is that song?",
expected_tool_calls=[
ExpectedToolCall(
func=get_tracks_audio_features,
args={
"track_ids": [
"14CQdqVFygEls6szbfwuTL",
"5r9fTbn6YZVxHKaU4Rze3t",
]
},
)
],
critics=[
BinaryCritic(critic_field="track_id", weight=1.0),
],
additional_messages=history_2,
)
suite.add_case(
name="Get recommendations based on a specific track",
user_message="Give me 6 recommendations based on this song.",
expected_tool_calls=[
ExpectedToolCall(
func=get_recommendations,
args={
"seed_artists": ["4ev14fn325vhWuykve3QtA"],
"seed_genres": [], # None provided in the history
"seed_tracks": ["14CQdqVFygEls6szbfwuTL"],
"limit": 6,
},
)
],
critics=[
BinaryCritic(critic_field="seed_artists", weight=0.3),
BinaryCritic(critic_field="seed_genres", weight=0.3),
BinaryCritic(critic_field="seed_tracks", weight=0.3),
],
additional_messages=history_3,
)
return suite

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "arcade_spotify"
version = "0.1.8"
version = "0.2.0"
description = "Arcade tools for Spotify"
authors = ["Arcade AI <dev@arcade-ai.com>"]