Skip to content

Latest commit

Β 

History

410 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

https://scrutinizer-ci.com/g/dotX12/ShazamIO/ https://scrutinizer-ci.com/g/dotX12/ShazamIO/ https://scrutinizer-ci.com/g/dotX12/ShazamIO/ https://badge.fury.io/py/shazamio https://pepy.tech/project/shazamio https://pepy.tech/project/shazamio https://github.com/dotX12/ShazamIO/blob/master/LICENSE.txt

🎡 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.


πŸ’Ώ Installation

πŸ’² pip install shazamio

πŸ’» Example

πŸ”ŽπŸŽ΅ 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())

πŸ”Œ Closing what you open

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.

πŸ“Š What the chart methods return

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.

πŸ”§ What data serialization gives you

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.

Open photo: What song information looks like (Dict)
Open photo: what song information looks like (Custom serializer)

About

🎡 Is a free asynchronous library from reverse engineered Shazam API written in Python 3.10+ with asyncio and aiohttp.

Topics

Resources

Code of conduct

Contributing

Stars

968 stars

Watchers

10 watching

Forks

Releases

Packages

Used by

Contributors

Languages