Skip to content

refactor(api): rebuild the library on the endpoints Shazam still serves - #193

Open
Danipulok wants to merge 7 commits into
masterfrom
refactor/live-api-surface
Open

Danipulok wants to merge 7 commits into
masterfrom
refactor/live-api-surface

Conversation

@Danipulok

Copy link
Copy Markdown
Collaborator

Closes #146
Closes #109
Closes #130

What

Thirteen methods called services/* endpoints Shazam has retired. None of them failed cleanly: the edge answers a retired path with the website itself, 200 text/html, so every call surfaced as FailedDecodeJson and read like a parsing bug in this library rather than a removed endpoint upstream.

Charts, on master:

>>> await shazam.top_country_genre_tracks(country_code='ES', genre=GenreMusic.HIP_HOP_RAP, limit=4)
shazamio.exceptions.FailedDecodeJson: Failed to decode json (status=200): <!DOCTYPE html><html lang="en-us">...
>>> await shazam.top_world_tracks(limit=3)
shazamio.exceptions.FailedDecodeJson: Failed to decode json (status=200): <!DOCTYPE html><html lang="en-us">...

and here:

>>> for track in await shazam.top_country_genre_tracks('ES', genre=GenreMusic.HIP_HOP_RAP, limit=4): print(track)
rank=1 artist='FERNANDOCOSTA & Dollar Selmouni' title='Oye'
rank=2 artist='Wxoda' title='Vibin'
rank=3 artist='Anuel AA' title='Las mas bonitas son p#tas'
rank=4 artist='Pucho, Mia & Cristy' title='NON MI INNAMORERÓ'

>>> for track in await shazam.top_world_tracks(limit=3): print(track)
rank=1 artist='HUGEL, Imael Angel & Ultra Naté' title="Movin' To The Sun"
rank=2 artist='Imael Angel' title='Bad Times (Extended Version)'
rank=3 artist='Imael Angel' title='BAD TIMES'

Commit by commit:

  • The User-Agent list. 390 of the 490 strings were browser agents, and www.shazam.com serves a browser the website (or a 405) instead of the API. Only an agent shaped like the Shazam mobile app gets a real body — no User-Agent at all, curl/8.x and okhttp/4.12.0 all get the website too. The 390 browser strings are gone; the 100 Dalvik/... ones stay.

  • Thirteen methods removed: artist_about, search_artist, search_track, listening_counter, listening_counter_many, artist_albums, artist_album_info, search_artist_v2, top_artist_tracks, top_tracks_playlist and friends. services/search/v3, search/v4 and count/v2 answer 404 Not supported from the origin; the whole services/amapi/v1 surface answers 405 at the edge — it was an Apple Music proxy the website replaced with server-side MusicKit calls. Nothing rescues them, so they are deleted rather than left raising.

  • The five chart methods, rebuilt. Shazam publishes its charts as CSV under services/charts/csv/... and nowhere else. top_world_tracks, top_country_tracks, top_city_tracks, top_world_genre_tracks and top_country_genre_tracks return list[ChartTrack], each row a rank, an artist and a title — three columns is everything the service publishes, so a chart entry no longer carries ids or artwork and cannot be fed to Serialize. Country, city and genre slugs are resolved through services/charts/locations, which supplies them as urlName. limit now defaults to the whole chart and offset skips from the top; both are client-side, because the service ignores query parameters. regional-mexicano is dropped from GenreMusic: it was renamed upstream and has no chart under either spelling.

  • The schemas the removed methods were the only source of go with them, leaving Serialize.track and Serialize.full_track.

  • HTTPClient.request loses its *args, which existed only to forward a content type that was always the default.

  • Examples and README. Every entry point started its loop with asyncio.get_event_loop(), which raises on Python 3.14:

    RuntimeError: There is no current event loop in thread 'MainThread'.
    

    They now use asyncio.run(). The README demonstrated twelve methods that no longer reach an endpoint, and recognized dora.ogg, which returns no match; it documents the eight live methods and recognizes examples/data/Gloria.ogg.

This is a breaking change for anyone calling the removed methods, and for anyone indexing a chart result as a dict.

How to test

just lint && just test — the suite includes live checks for all five charts, the slug resolution, track metadata and recognition.

Every snippet in the README was executed against the live service before this was opened, as were examples/*.py.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chart Response results in a failed to decode json exception No top genre songs found? top_country_tracks does not return tracks

1 participant