

π΅ Is a FREE asynchronous library from reverse engineered Shazam API written in Python 3.10+ with asyncio and aiohttp. Recognizes a song from a file or from bytes, reads a track and the tracks related to it, and returns every chart Shazam publishes.
π² pip install shazamio
ππ΅ Recognize track
Recognize a track from a file, a pathlib.Path, or the bytes of one. The
sample below ships with the repository, in examples/data/
import asyncio
from shazamio import Serialize, Shazam
async def main():
async with Shazam() as shazam:
out = await shazam.recognize("Gloria.ogg")
print(out) # dict
print(Serialize.full_track(out).track.title) # I Will Survive
asyncio.run(main())π΅π About track
Get track information
https://www.shazam.com/track/552406075/ale-jazz
import asyncio
from shazamio import Serialize, Shazam
async def main():
async with Shazam() as shazam:
about_track = await shazam.track_about(track_id=552406075)
print(about_track) # dict
print(Serialize.track(data=about_track)) # pydantic model
asyncio.run(main())πΆπ¬ Similar songs
Similar songs based on a song id
https://www.shazam.com/track/546891609/2-phu%CC%81t-ho%CC%9Bn-kaiz-remix
import asyncio
from shazamio import Shazam
async def main():
async with Shazam() as shazam:
related = await shazam.related_tracks(track_id=546891609, limit=5, offset=2)
print(related)
asyncio.run(main())ππ Apple Music ids to Shazam track keys
Resolve Apple Music track ids to the Shazam track keys track_about takes, in
one request. A call with several ids keys every entry by the id Shazam stores,
which can be one you never sent, so read the values instead of indexing by what
you asked for. A call with a single id keys it by that id. Either way an id
Shazam has no track for is absent, so the map can be shorter than the list you
passed.
import asyncio
from shazamio import Shazam
async def main():
async with Shazam() as shazam:
keys = await shazam.track_keys_from_apple_ids([1125281672, 1440650711])
print(keys) # {'1125281672': '325127876', '6781023657': '56670613'}
asyncio.run(main())ππΆπ Top tracks in world
The 200 most shazamed tracks worldwide
https://www.shazam.com/charts/top-200/world
import asyncio
from shazamio import Shazam
async def main():
async with Shazam() as shazam:
tracks = await shazam.top_world_tracks(limit=10)
for track in tracks:
print(f"{track.rank}. {track.artist} - {track.title}")
asyncio.run(main())ππΆπ³οΈ Top tracks in country
The 200 most shazamed tracks in a country
https://www.shazam.com/charts/top-200/netherlands
import asyncio
from shazamio import Shazam
async def main():
async with Shazam() as shazam:
tracks = await shazam.top_country_tracks(
country_code="NL",
limit=5,
)
for track in tracks:
print(f"{track.rank}. {track.artist} - {track.title}")
asyncio.run(main())ππΆποΈ Top tracks in city
The 50 most shazamed tracks in a city. The city name is the one
services/charts/locations publishes
https://www.shazam.com/charts/top-50/russia/moscow
import asyncio
from shazamio import Shazam
async def main():
async with Shazam() as shazam:
tracks = await shazam.top_city_tracks(
country_code="RU",
city_name="Moscow",
limit=10,
)
for track in tracks:
print(f"{track.rank}. {track.artist} - {track.title}")
asyncio.run(main())ππΆππΈ Top tracks in world by genre
The most shazamed tracks worldwide in one genre
https://www.shazam.com/charts/genre/world/rock
import asyncio
from shazamio import GenreMusic, Shazam
async def main():
async with Shazam() as shazam:
tracks = await shazam.top_world_genre_tracks(
genre=GenreMusic.ROCK,
limit=10,
)
for track in tracks:
print(f"{track.rank}. {track.artist} - {track.title}")
asyncio.run(main())ππΆπ³οΈπΈ Top tracks in country by genre
The most shazamed tracks in a country in one genre. Shazam offers only a
handful of genres per country, and asking for one it does not offer answers
404, which surfaces as aiohttp.ClientResponseError
https://www.shazam.com/charts/genre/spain/hip-hop-rap
import asyncio
from shazamio import GenreMusic, Shazam
async def main():
async with Shazam() as shazam:
tracks = await shazam.top_country_genre_tracks(
country_code="ES",
genre=GenreMusic.HIP_HOP_RAP,
limit=4,
)
for track in tracks:
print(f"{track.rank}. {track.artist} - {track.title}")
asyncio.run(main())A Shazam opens one connection pool on its first request and reuses it for
every later one, so ten calls no longer cost ten connections. The pool lives
until you close it, which async with does for you:
async with Shazam() as shazam:
...Without a close the pool stays open and aiohttp reports it when the object is
collected: Unclosed client session. await shazam.close() does the same job
where a block does not fit, and a request after either one raises
RuntimeError: Session is closed.
An HTTPClient you build yourself is yours to close: Shazam closes only the
client it builds for itself. examples/recognize_song.py shows both blocks.
Shazam publishes its charts as CSV with three columns, so a chart entry is a
ChartTrack carrying a rank, an artist and a title, and nothing else. A chart
has no ids, no artwork and no provider links, so a chart entry cannot be passed
to Serialize. Nothing in the library resolves a chart row to a track id
either: Shazam retired the search endpoints that used to do it.
limit defaults to the whole chart, and offset skips entries from the top:
both are applied to the chart the service returns, which is always the full
one.
Serialize.full_track turns the output of recognize into a ResponseTrack,
and Serialize.track turns the output of track_about into a TrackInfo.
Both carry the title, the artist, the artwork and the provider links, so you
no longer have to pick the fields out of the raw dictionary by hand.

