Skip to content

session.py

This module contains the Session class.

Session ¤

A session is required to connect to Deezer's unofficial API.

__init__(self, arl_token: str, proxy: str = None) special ¤

Creates a new Deezer session instance.

Parameters:

Name Type Description Default
arl_token str

The arl token is used to make API requests on Deezer's unofficial API

required
proxy str

The proxy configuration to use, e.g "http://user:pass@some.proxy.com"

Info

The session uses the proxy configuration from the HTTP_PROXY environment variables if present.

None

Exceptions:

Type Description
DeezerLoginError

The specified arl token is not valid.

Source code in deethon/session.py
def __init__(self, arl_token: str, proxy: str = None):
    """
    Creates a new Deezer session instance.

    Args:
        arl_token: The arl token is used to make API requests
            on Deezer's unofficial API
        proxy: The proxy configuration to use, e.g `"http://user:pass@some.proxy.com"`
            !!! Info
                The session uses the proxy configuration from the `HTTP_PROXY`
                environment variables if present.
    Raises:
        DeezerLoginError: The specified arl token is not valid.
    """
    self._proxy = proxy
    self._arl_token: str = arl_token
    cookies = {"arl": self._arl_token}
    self._http = aiohttp.ClientSession(cookies=cookies, trust_env=True)
    self._csrf_token = ""
    self._session_expires = 0

download(self, url: str, quality: Quality = <Quality.FLAC: '9'>, progress_callback: Optional[Callable[[int, int], NoneType]] = None) async ¤

Downloads the given Deezer url if possible.

Parameters:

Name Type Description Default
url str

The URL of the track or album to download.

required
quality Quality

The preferred quality to download.

<Quality.FLAC: '9'>
progress_callback Optional[Callable[[int, int], NoneType]]

A callable that accepts current and total arguments.

None

Exceptions:

Type Description
ActionNotSupported

The specified URL is not (yet) supported for download.

InvalidUrlError

The specified URL is not a valid Deezer link.

Source code in deethon/session.py
async def download(self,
                   url: str,
                   quality: Quality = Quality.FLAC,
                   progress_callback: Optional[Callable[[int, int], None]] = None):
    """
    Downloads the given Deezer url if possible.

    Args:
        url: The URL of the track or album to download.
        quality: The preferred quality to download.
        progress_callback: A callable that accepts
            `current` and `total` arguments.

    Raises:
        ActionNotSupported: The specified URL is not (yet)
            supported for download.
        InvalidUrlError: The specified URL is not a valid Deezer link.
    """
    match = re.match(
        r"https?://(?:www\.)?deezer\.com/(?:\w+/)?(\w+)/(\d+)", url)
    if match:
        mode = match.group(1)
        content_id = int(match.group(2))
        if mode == "track":
            return await self.download_track(await Track.fetch(self, content_id), quality,
                                             progress_callback)
        if mode == "album":
            return self.download_album(await Album.fetch(self, content_id), quality)
        raise errors.ActionNotSupported(mode)
    raise errors.InvalidUrlError(url)

download_album(self, album: Union[deethon.types.Album, int], quality: Quality = <Quality.FLAC: '9'>) ¤

Downloads an album from Deezer using the specified Album object.

Parameters:

Name Type Description Default
album Union[deethon.types.Album, int]

An Album instance or album id.

required
quality Quality

The preferred quality to download.

<Quality.FLAC: '9'>

Returns:

Type Description

The file paths.

Source code in deethon/session.py
async def download_album(
        self,
        album: Union[Album, int],
        quality: Quality = Quality.FLAC,
):
    """
    Downloads an album from Deezer using the specified Album object.

    Args:
        album: An [Album][deethon.types.Album] instance or album id.
        quality: The preferred quality to download.

    Returns:
        The file paths.
    """
    if not isinstance(album, Album):
        album = await Album.fetch(self, album)
    async for track in album.fetch_tracks():
        yield await self.download_track(track, quality)

download_track(self, track: Union[deethon.types.Track, int], quality: Quality = <Quality.FLAC: '9'>, progress_callback: Optional[Callable[[int, int], NoneType]] = None) -> Path async ¤

Downloads the given Track object.

Parameters:

Name Type Description Default
track Union[deethon.types.Track, int]

A Track instance or track id.

required
quality Quality

The preferred quality to download.

<Quality.FLAC: '9'>
progress_callback Optional[Callable[[int, int], NoneType]]

A callable that accepts current and total arguments.

None

Returns:

Type Description
Path

The file path of the downloaded track.

Exceptions:

Type Description
DownloadError

The track is not downloadable.

Source code in deethon/session.py
async def download_track(self,
                         track: Union[Track, int],
                         quality: Quality = Quality.FLAC,
                         progress_callback: Optional[Callable[[int, int], None]] = None) -> Path:
    """
    Downloads the given [Track][deethon.types.Track] object.

    Args:
        track: A [Track][deethon.types.Track] instance or track id.
        quality: The preferred quality to download.
        progress_callback: A callable that accepts
            `current` and `total` arguments.

    Returns:
        The file path of the downloaded track.

    Raises:
        DownloadError: The track is not downloadable.
    """
    if not isinstance(track, Track):
        track = await Track.fetch(self, track)
    download_url = track.get_stream_url(quality)
    file_path = utils.get_file_path(track, quality.get_file_ext())
    response = await self._http.get(download_url, proxy=self._proxy)
    total = response.content_length
    current = 0

    if not total:
        fallback_bitrate = quality.get_fallback_quality()
        if fallback_bitrate is None:
            raise errors.DownloadError(track.id)
        return await self.download_track(track, fallback_bitrate, progress_callback)

    with file_path.open("wb") as f:
        async for data, _ in response.content.iter_chunks():
            current += len(data)
            f.write(data)
            if progress_callback:
                progress_callback(current, total)

    tag(file_path, track, await track.album.download_cover(1200, 95))

    return file_path.absolute()