pydrag

https://github.com/tefra/pydrag/workflows/tests/badge.svg https://readthedocs.org/projects/pydrag/badge https://codecov.io/gh/tefra/pydrag/branch/master/graph/badge.svg https://img.shields.io/github/languages/top/tefra/pydrag.svg https://www.codefactor.io/repository/github/tefra/pydrag/badge https://img.shields.io/pypi/pyversions/pydrag.svg https://img.shields.io/pypi/v/pydrag.svg

pydrag is a modern api wrapper for the Last.fm api with a fluent syntax!

Quick Start

Apply for a last.fm api key and write down your key and secret.

Install

$ pip install pydrag

Example

>>> from pydrag import User, configure
>>> configure(api_key='54062d8af7afdc_not_real_3459048a4')
>>> rj = User.find("RJ")
>>> rj.real_name
'Richard Jones '
>>> recent = rj.get_recent_tracks(limit=1, page=1)
>>> first = recent.pop()
>>> first.name
'Fu-Gee-La'
>>> similar = first.get_similar(limit=1)
>>> similar[0].name
'Family Business'
>>> similar[0].artist.name
'Fugees'
>>>
>>> for friend in rj.get_friends(recent_tracks=True):
...     friend.name, friend.recent_track.name
...
('meichi', 'Pi')
('demkod', '(bottle back)')
('STBKilla', 'Nowhere Fast')
('keret221', 'Letter Home')
('Lilfix', 'Namorar pra Quê?')
('Yoji', 'Empire State of Mind (feat. Alicia Keys)')
('Kastishka', 'Wipe Your Eyes')
('comingsoon_', 'I Want It All')
('Bagheera', 'Welcome Home')

Development

Use you favorite tool to create a python >= 3.6 virtual environment

$ git clone git@github.com:tefra/pydrag.git
$ pip install .[dev]
$ pre-commit install
$ pytest
$ tox

pydrag uses vcrpy library to record and replay last.fm responses for its unit tests and python-dotenv to auto-configure itself.

All sensitive information like keys and credentials are automatically censored.

So when it’s necessary to record a new response it’s super useful to have a .env file with your configuration!

LASTFM_API_KEY=your_api_key
LASTFM_API_SECRET=your_api_secret
LASTFM_USERNAME=You
LASTFM_PASSWORD=YouPass

Changelog: 22.5 (2022-05-08)

  • Replaced attrs with dataclasses

  • Added support for python 3.10

Advanced example

For write operations you need to be authenticated. Last.fm has multiple ways to authenticate users the most simple is to provide your full credentials.

Find a track by artist and name, retrieve the album, add some user tags and love the Back in Black

>>> import pydrag

>>> pydrag.configure("<api_key>", "<api_secret>", "<username>", "<password>")
lets say it worked
>>> track = pydrag.Track.find(artist="AC / DC", track="Hells Bell")
>>> album = track.album
>>> album.to_dict()
{'attr': {'position': 1}, 'name': 'Back in Black', 'mbid': '38914b29-7788-4cff-80b7-1ced523f8675', 'url': 'https://www.last.fm/music/AC%2FDC/Back+in+Black', 'image': [{'size'
: 'small', 'text': 'https://lastfm-img2.akamaized.net/i/u/34s/3d359b955132742bc2fc3eacdff90b8c.png'}, {'size': 'medium', 'text': 'https://lastfm-img2.akamaized.net/i/u/64s/3d
359b955132742bc2fc3eacdff90b8c.png'}, {'size': 'large', 'text': 'https://lastfm-img2.akamaized.net/i/u/174s/3d359b955132742bc2fc3eacdff90b8c.png'}, {'size': 'extralarge', 'te
xt': 'https://lastfm-img2.akamaized.net/i/u/300x300/3d359b955132742bc2fc3eacdff90b8c.png'}], 'artist': {'name': 'AC/DC'}}
>>> full_album_info = track.album.get_info()
>>>
>>> full_album_info.add_tags(["awesome", "love"])
>>>
>>> back_in_black = next(track for track in full_album_info.tracks if track.name == "Back in Black")
>>> write_op = back_in_black.get_info().love()
>>> write_op.params
{'method': 'track.love', 'artist': 'AC/DC', 'track': 'Back in Black'}
>>>

Table of Contents

Usage Examples

This page lists examples on how to use pydrag

Authentication

Apart from your last.fm api key and secret you also need to be authenticated if you wish to perform write operations like scrobbling, adding/removing tags.

Mobile Applications

This is what Last.fm calls simple authentication with credentials, it’s indented to be used with non-browser application.

Last.fm states that Session keys have an infinite lifetime by default, so generate one and keep using it.

>>> from pydrag import configure, Album, Config, AuthSession
>>>
>>> configurate(api_key='aaaaaaaaaa', api_secret='bbbbbbbbbbb', username='foo', password='bar')
>>>
>>>
>>> session = AuthSession.authenticate()
>>> session.key
'2Y5jNDz1111111111111Zq3ZTNjl'
>>>
>>>
>>> configure(api_key='aaaaaaaaaa', api_secret='bbbbbbbbbbb', session='2Y5jNDz1111111111111Zq3ZTNjl')
>>> album = Album.find_by_mbid("6defd963-fe91-4550-b18e-82c685603c2b")
>>> album.add_tags(['great', 'rock'])
>>> Config.instance().session  # store this somewhere and next time
>>> configurate(api_key='aaaaaaaaaa', api_secret='bbbbbbbbbbb', session='ssssss')
Desktop Application

This method is indented for desktop applications, whatever that means.

Step 1: Generate an unauthorized token

1@app.route("/gen-token")
2def gen_token():
3    global tokens
4
5    token = AuthToken.generate()
6    tokens.update({token.token: None})
7    return redirect(url_for("index"))

Step 2: Send the user to the last.fm site to authorize the token

1@app.route("/authorize/<token>", methods=["GET"])
2def authorize_token(token):
3    global tokens
4    tokens[token] = True
5    token = AuthToken(token=token)
6    return redirect(token.auth_url)

Step 3: Retrieve a session with the authorized token

1@app.route("/get-session/<token>", methods=["GET"])
2def get_session(token):
3    global tokens
4    session = AuthSession.from_token(token)
5    tokens[token] = session
6    return redirect(url_for("index"))
Web Application

This method is very similar to the above but a lot simpler and makes more sense to me!

Step 1: Send the user to the last.fm site to authorize your application and provide a callback url which will include the authorized token for you!

 1@app.route("/session", methods=["POST", "GET"])
 2def gen_session():
 3    if request.method == "POST":
 4        url = "http://www.last.fm/api/auth/?api_key={}&cb={}".format(
 5            Config.instance().api_key, url_for("gen_session", _external=True)
 6        )
 7        return redirect(url)
 8    else:
 9        token = request.args.get("token")
10        return redirect(url_for("get_session", token=token))

Step 3: Retrieve a session with the authorized token

1@app.route("/get-session/<token>", methods=["GET"])
2def get_session(token):
3    global tokens
4    session = AuthSession.from_token(token)
5    tokens[token] = session
6    return redirect(url_for("index"))

Note

You can find the full demo application built with flask Here

$ pip install -r docs/examples/web/requirements.txt
$ FLASK_APP=docs/examples/web/app.py FLASK_DEBUG=1 python -m flask run

User Webservices

Retrieve user
>>> from pydrag import User
>>> me = User.find("Zaratoustre")
>>> me
User(playlists=0, playcount=34816, gender='n', name='Zaratoustre', url='https://www.last.fm/user/Zaratoustre', country='Greece', image=[Image(size='small', text='https://lastfm-img2.akamaized.net/i/u/34s/a4503fbd410046dcc63317f0fa19613a.png'), Image(size='medium', text='https://lastfm-img2.akamaized.net/i/u/64s/a4503fbd410046dcc63317f0fa19613a.png'), Image(size='large', text='https://lastfm-img2.akamaized.net/i/u/174s/a4503fbd410046dcc63317f0fa19613a.png'), Image(size='extralarge', text='https://lastfm-img2.akamaized.net/i/u/300x300/a4503fbd410046dcc63317f0fa19613a.png')], age=0, registered=1263647609, real_name='Chris T', recent_track=None)
>>>
>>> me.name
'Zaratoustre'
>>> me.date_registered
datetime.datetime(2010, 1, 16, 13, 13, 29)
>>>
Retrieve friends
>>> from pydrag import User
>>>
>>> me = User.find("Zaratoustre")
>>> friends = me.get_friends(recent_tracks=True, limit=10, page=1)
>>> [(x.name, x.recent_track.name) for x in friends]
[('meichi', 'Pi'), ('demkod', '(bottle back)'), ('STBKilla', 'Nowhere Fast'), ('keret221', 'Letter Home'), ('Lilfix', 'Namorar pra Quê?'), ('Yoji', 'Empire State of Mind (fea
t. Alicia Keys)'), ('Kastishka', 'Wipe Your Eyes'), ('comingsoon_', 'I Want It All'), ('Bagheera', 'Welcome Home')]
>>>
Retrieve Artist Lists
>>> from pydrag import User
>>> from pydrag.constants import Period
>>>
>>> me = User.find("Zaratoustre")
>>>
>>> artists = me.get_artists(limit=5)

>>> [x.name for x in artists]
['System of a Down', 'Eminem', 'Red Hot Chili Peppers', 'Serj Tankian', 'FF.C']
>>>
>>> artists = me.get_top_artists(period=Period.week, limit=5)
>>> [x.name for x in artists]
['FF.C', 'Άλφα Γάμα', 'Terror X Crew', 'Αρτέμης / Ευθύμης', 'DMX']
>>>
>>> artists = me.get_weekly_artist_chart()
>>> [x.name for x in artists]
['FF.C', 'Άλφα Γάμα', 'Terror X Crew', 'Αρτέμης / Ευθύμης', 'DMX', 'Eminem', 'Black Eyed Peas', 'Ζωντανοί Νεκροί', "Goin' Through", 'Wu-Tang Clan', '50 Cent', 'The Beatnuts', 'Xzibit', 'Nathaniel Rateliff', 'Placebo', 'Rage Against the Machine', 'Ελένη Βιτάλη']
Retrieve Album Lists
>>> from pydrag import User
>>> from pydrag.constants import Period
>>>
>>> me = User.find("Zaratoustre")
>>>
>>> albums = me.get_top_albums(period=Period.overall)
>>> [x.name for x in albums]
['Nathaniel Rateliff & The Night Sweats', 'Elect the Dead', 'Relapse', 'Toxicity', 'Με Λένε Πόπη', 'Hypnotize', 'Mezmerize', 'Steal This Album!', 'Bestwishes', 'Past Masters', 'The Better Life', 'System of a Down', 'Californication', 'Demon Days', 'A Real Dead One', 'Κλασικα Ηχογραφημενα', 'Hot Fuss', 'The Black Parade', 'Back to Bedlam', 'Recovery', 'Monkey Business', 'The Getaway', 'Danger Days: The True Lives of the Fabulous Killjoys', 'Live in Texas', 'Harakiri', 'Αντιληψίες συνείδησης', "It's Dark And Hell Is Hot", 'Sting In The Tail', 'Blood Sugar Sex Magik', 'American IV: The Man Comes Around', 'Η Απειλή', 'True Blood Volume 1', 'Lovers', 'Sigh No More', 'Imperfect Harmonies', 'Before I Self Destruct', 'The Eminem Show', "Υπ'Οψιν", 'Hengen Jizai no Magical Star', 'Beggars Banquet', 'History Begins', 'The Razors Edge', 'Back in Black', 'The Best Damn Thing', 'Deep Purple in Rock: Anniversary Edition 1995', 'Let It Be', 'With the Lights Out', 'Ο Ρομπέν των χαζών (Rodon Live)', 'Appetite for Destruction', 'Fear of the Dark']
>>>
>>> albums = me.get_weekly_album_chart()
>>> [x.name for x in albums]
['Αγνωστοφοβία', 'Κλασικα Ηχογραφημενα', "Υπ'Οψιν", 'Η Απειλή', "Σ'άλλη Διάσταση", 'Αντιληψίες συνείδησης', 'Έσσεται Ήμαρ', 'Οχυρωμένη αντίληψη', 'Η Πόλις Εάλω', 'Monkey Business', 'Εγείρεσθε άγωμεν εντεύθεν', 'ΖΝ Εντολές', 'Νεοέλληνα Άκου', 'Ο διαλεχτός της άρνησης κι ο ακριβογιός της πίστης', 'The Duets', 'The Marshall Mathers LP2', 'The W', 'Year Of The Dog... Again', '8 Mile', 'Before I Self Destruct', "It's Dark And Hell Is Hot", 'Restless', 'TAKE IT OR SQUEEZE IT', 'Σκληροί Καιροί', 'Nathaniel Rateliff & The Night Sweats', 'Rage Against the Machine', 'Sleeping with Ghosts', 'Terror X Crew', 'Η γεύση του μένους', 'Το απέναντι μπαλκόνι']
Retrieve Track Lists
>>> from pydrag import User
>>> from pydrag.constants import Period
>>>
>>> me = User.find("Zaratoustre")
>>>
>>> tracks = me.get_artist_tracks(artist="queen", page=2)
>>> set([x.name for x in tracks])
{'We Will Rock You', 'The Miracle', 'You and I', 'White Queen (As It Began)', 'Somebody to Love', 'Under Pressure', 'The Show Must Go On', "'39", "You're My Best Friend", 'Spread Your Wings', 'Another One Bites the Dust', 'Killer Queen', 'We Are the Champions', 'Nevermore', 'Fat Bottomed Girls', "Modern Times Rock 'N' Roll", 'Gimme the Prize', 'Bohemian Rhapsody', 'A Kind of Magic', 'Delilah', 'Bicycle Race', "Don't Stop Me Now", 'Misfire', 'Crazy Little Thing Called Love'}
>>>
>>> tracks = me.get_recent_tracks(limit=2, page=2)
>>> set([x.name for x in tracks])
{'Η Κλίκα της Στάχτης', 'Το Τελευταίο Γράμμα Ενός Αυτόχειρα'}
>>>
>>> tracks = me.get_top_tracks(period=Period.month, limit=2, page=2)
>>> set([x.name for x in tracks])
{'Beauty and the Beast', 'Kryptonite'}
>>>
>>>
>>> tracks = me.get_weekly_track_chart()
>>> set([x.name for x in tracks])
{'Άσε Με Να Σου Πω', 'Όσο και να σκέφτηκα (Remix)', 'Εφιάλτες', "Ruff Ryder's Anthem", 'Δεύτερον', 'X (Feat. Snoop Dogg)', 'Παλιό Ποτό', 'MCs & DJs', 'Κράτα απόσταση (ft. Dash)', 'Χρηματολαγνεία', 'Ο κύκλος', 'Δεν αρκεί', 'Αντίδοτο', 'Παραμύθι (feat Deadlock) Remix', "No Escapin' This", 'Rap God', 'Dibi Dibi Song', 'Μη Φοβάσαι', 'Το Τελευταίο Γράμμα Ενός Αυτόχειρα', 'Ορχηστρικό 2', 'Πάρε Λίγο Φως (Remix)', 'Ω, Ναι', 'Οι Στίχοι Μας Ποτέ Δεν Σταματάνε', 'Έλα Μου', 'Επιτέλους Αρχή', 'Αγνωστοφοβία', 'Το Ημερολόγιο', 'Μακρύς, Βαρύς Χειμώνας', 'Στημένο παιχνίδι', 'Η δικιά μου Ιθάκη', 'Δήλωση', 'Βαρέθηκα', 'Η Αφύπνησις', 'συνοποσία', 'Άλλη Μια Άρχη', 'Το όριο', 'Φταίω Κι Εγώ', 'WE GOT TO PUMP IT UP', 'Ανάθεμα', 'Άλλο Ένα Αντίο', 'Θολά Νερά', 'Έτσι Το Ζω', 'Δέκα Πόντους Τακούνι', 'Άντε Να Δούμε Που Θα Φτάσει', 'Λεπτή γραμμή', 'Η νύχτα των ζωντανών νεκρών', 'Με χρέος μεγάλο', 'Ανήθικο μου στυλ (ft. Χαρμάνης)', 'Είσαι Ακόμα Εδώ', 'Όπως πρώτα (βαρεία μίξις)', 'Επίλογος', 'Ο dj alx στον τεκέ', 'Νεοέλληνα Άκου', 'Αρκετά Για Να Μαθαίνεις', 'Η κιβωτός', 'Προοίμιον', 'Όπως πρώτα (Gauloise mix)', 'Παιχνίδια του μυαλού', 'Απολογισμός', 'Οι στίχοι μας ποτέ δεν σταματάνε (ηλεκτρική καρέκλα)', 'Goodbye', "Don't Phunk with My Heart", 'Πισώπλατα', 'Hold Me Down', "Ριμοθέτηση '98", 'Ωδή εις το γκούτσι φόρεμα', 'Εκδοχή', 'The Bitter End', 'Μια φορά και έναν καιρό', 'Ριπή', 'Όσα μου έμαθες εσύ', 'Ποτέ Δεν Είναι Αργά', 'Περίφημη Τετράδα', 'Παραμύθι', 'Άδειο Σκηνικό', 'Ξύπνιος μέσα στα όνειρα κάποιων άλλων', 'I Need Never Get Old', 'Η Κλίκα της Στάχτης', 'Killing in the Name', 'Μια διαπίστωση', 'Νέος τρόπος σκέψης', 'Pump It', 'Φωτεινός Ορίζοντας', 'Για τα λεφτά γίνονται όλα', 'Περσεφόνη', 'Το ξόδι (σκοταδισμός Β Α)', "Που 'ν' οι Πέννες σας;", 'Ο Έλληνας που έχεις συνηθίσει', 'Funky scratch', 'Δίκασμα', 'Υποθέσεις', 'Ηλιακή φύσις', 'Συζητώντας Με Έμενα', 'Ψυχικά νεκρός', 'Η πιο παλιά μάχη', 'Lose Yourself', 'Outro (ορχηστρικό)', 'Σημεία Των Καιρών', "Συναγερμός (Jungle Mix ''''98)", 'Πανικόβλητον', 'Η πτώση (feat. Ημισκούμπρια, Terror X Crew)', 'Protect Ya Neck (The Jump Off)', 'Δούρειος ήχος', 'Πρίσμα Φαντασίας', 'Κάποιοι', 'Ρυθμοδαμαστής & Πάνας'}
>>>
>>> tracks = me.get_loved_tracks(limit=5, page=2)
>>> set([x.name for x in tracks])
{'Carry on Wayward Son', 'Το Τελευταίο Γράμμα Ενός Αυτόχειρα', 'Εχω Το Θεμα Μου', 'Πάρε Λίγο Φως (Remix)', 'Strange Love'}
>>>
Retrieve Tag Lists
>>> from pydrag import User
>>>
>>> me = User.find("Zaratoustre")
>>>
>>> tags = me.get_personal_tags(tag="metal", category="artist")
>>> [t.name for t in tags]
>>>
>>> tags = me.get_personal_tags(tag="metal", category="album")
>>> [t.name for t in tags]
>>>
>>> tags = me.get_personal_tags(tag="metal", category="track")
>>> [t.name for t in tags]
>>>
>>> tags = me.get_top_tags(limit=5)
>>> [t.name for t in tags]
['foo', 'bar', 'super']

Album Webservices

Retrieve album
>>> from pydrag import Album
>>>
>>> album = Album.find(artist="Queen", album="A Night at the Opera")
>>> len(album.tracks)
12
>>> [x.name for x in album.tracks]
['Death on Two Legs (Dedicated to ...)', 'Lazing on a Sunday Afternoon', "I'm in Love With My Car", "You're My Best Friend", "'39", 'Sweet Lady', 'Good Company', 'Seaside Rendezvous', "The Prophet's Song", 'Love of My Life', 'Bohemian Rhapsody', 'God Save the Queen']
>>>

You can also use MusicBrainz ids to retrieve tracks

>>> album = Album.find_by_mbid("6defd963-fe91-4550-b18e-82c685603c2b")
>>> album.listeners
609001
>>> album.wiki.summary
'A Night at the Opera is a 1975 album by English rock band Queen. It was produced by Roy Thomas Baker and Queen, and reportedly was, at the time of its release, the most expensive album ever made. It was originally released by EMI in the UK where it topped the charts for nine weeks, a record at the time, and Elektra Records in the United States where the album peaked at #4 and has been certified Triple Platinum (three million copies sold).\nThe album takes its name from the Marx Brothers film of the same name <a href="http://www.last.fm/music/Queen/A+Night+at+the+Opera">Read more on Last.fm</a>.'
>>>
Search albums
>>> result = Album.search("fire", limit=5)
>>> [x.name for x in result]
['Room on Fire', 'Holy Fire', 'Friendly Fires', 'I Am... Sasha Fierce', 'The Suburbs']
>>>
Album Tagging
>>> album = Album.find(artist="Queen", album="A Night at the Opera")
>>> album.add_tags(["super", "hot"])
>>> album.remove_tag("hot")
Get user album tags
>>>
>>> tags = album.get_tags(user="Zaratoustre")
>>> [x.name for x in tags]
['foo']
>>>
Get top album tags

Fix me!!!!

>>> album = Album.find(artist="Queen", album="A Night at the Opera")
al>>> tags = album.get_top_tags()
>>> [x.name for x in tags]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Tag' object is not iterable
>>> tags
Tag(name=6, reach=None, url=None, taggings=None, count=None, total=None, wiki=None)
>>>

Track Webservices

Retrieve track
>>> from pydrag import Track
>>> track = Track.find(artist="AC / DC", track="Hells Bell")
>>> track.name
'Hells Bells'
>>> track.album
Album(name='Back in Black', mbid='38914b29-7788-4cff-80b7-1ced523f8675', url='https://www.last.fm/music/AC%2FDC/Back+in+Black', image=[Image(size='small', text='https://lastfm-img2.akamaized.net/i/u/34s/3d359b955132742bc2fc3eacdff90b8c.png'), Image(size='medium', text='https://lastfm-img2.akamaized.net/i/u/64s/3d359b955132742bc2fc3eacdff90b8c.png'), Image(size='large', text='https://lastfm-img2.akamaized.net/i/u/174s/3d359b955132742bc2fc3eacdff90b8c.png'), Image(size='extralarge', text='https://lastfm-img2.akamaized.net/i/u/300x300/3d359b955132742bc2fc3eacdff90b8c.png')], playcount=None, artist=Artist(name='AC/DC', mbid=None, url=None, tag_count=None, listeners=None, playcount=None, userplaycount=None, image=None, match=None, tags=None, bio=None, on_tour=None, similar=None, rank=None), listeners=None, tags=None, tracks=None, wiki=None, rank=1)
>>>
>>>
>>> track.album.name
'Back in Black'
>>>

You can also use MusicBrainz ids to retrieve tracks

>>> from pydrag import Track
>>>
>>> track = Track.find_by_mbid("dfee97091197486fbe21c6217e4a8402")
Search tracks
>>> from pydrag import Track
>>>
>>> tracks = Track.search(track="wait and bleed")
>>> [t.name for t in tracks]
['Wait and Bleed', 'Wait and Bleed (Terry Date mix)', 'Wait and Bleed [Terry Date Mix]', 'Wait & Bleed', 'Wait and Bleed (live)']
Top tracks by country
>>> from pydrag import Track
>>>
>>> tracks = Track.get_top_tracks_by_country(country="italy", limit=5)
>>> [t.name for t in tracks]
['Creep', 'Smells Like Teen Spirit', 'Karma Police', 'Come as You Are', 'Burn the Witch']
Top tracks chart
>>> from pydrag import Track
>>>
>>> tracks =  Track.get_top_tracks_chart(limit=3)
>>> [t.name for t in tracks]
['Thank U, Next', 'Bohemian Rhapsody - Remastered 2011', 'SICKO MODE']
>>>
Love / Unlove tracks

We probably need to rethink the response for write operations…

>>> track = Track.find(artist="AC / DC", track="Hells Bell")
>>> track.love()
RawResponse(data=None)
>>>
>>> track.unlove()
RawResponse(data=None)
Tracks Tagging
>>> track = Track.find(artist="AC / DC", track="Hells Bell")
>>> track.add_tags(["super", "hot"])
>>> track.remove_tag("hot")
Update Now Playing

The response contains various validation messages which don’t make much sense…

>>> status = Track.update_now_playing(track="Hells Bells", artist="AC/DC", track_number=2)
>>> status.to_dict()
{'album': {'text': '', 'corrected': 0}, 'artist': {'text': 'AC/DC', 'corrected': 0}, 'track': {'text': 'Hells Bells', 'corrected': 0}, 'ignored_message': {'text': '', 'code': '0'}, 'album_artist': {'text': '', 'corrected': 0}}
>>>
Scrobble Tracks

Last.fm has a limit on how many tracks you can scrobble at once, pydrag allows you to take control of the batch size but internally it will max out to 50 tracks per batch.

>>> from datetime import datetime, timedelta
>>> import time
>>> from pydrag import Track
>>> from pydrag.models.common import ScrobbleTrack
>>>
>>> entries = (
...     ("Green Day", "Bang Bang"),
...     ("Please Fail", "Now"),
...     ("The Head and the Heart", "All We Ever Knew"),
...     ("Kaleo", "Way Down We Go"),
...     ("Disturbed", "The Sound of Silence"),
... )
>>>
>>> tracks = []
>>> date = datetime.now()
>>> for artist, track in entries:
...     date = date - timedelta(minutes=5)
...     timestamp = int(time.mktime(date.timetuple()))
...     tracks.append(
...         ScrobbleTrack(artist=artist, track=track, timestamp=timestamp)
...     )
...
>>> result = Track.scrobble_tracks(tracks, batch_size=2)
>>> result.to_dict()
{'data': [{'artist': 'Green Day', 'track': 'Bang Bang', 'timestamp': 1544365120}, {'artist': 'Please Fail', 'track': 'Now', 'timestamp': 1544364820}, {'artist': 'The Head and the Heart', 'track': 'All We Ever Knew', 'timestamp': 1544364520}, {'artist': 'Kaleo', 'track': 'Way Down We Go', 'timestamp': 1544364220}, {'artist': 'Disturbed', 'track': 'The Sound of Silence', 'timestamp': 1544363920}]}
>>>

Caution

Nothing really fails in the scrobble api

_images/nothing_fails.png

Artist Webservices

Retrieve artist
>>> from pydrag import Artist
>>> artist = Artist.find("Guns N' Roses")
>>> artist.name
"Guns N' Roses"
>>> artist.listeners
3211107
>>>

You can also use MusicBrainz ids to retrieve tracks

>>> artist = Artist.find_by_mbid("xxxxxxxx")
Get top artist tracks
>>> artist = Artist.find("Guns N' Roses")
>>> tracks = artist.get_top_tracks(limit=2)
>>> [t.name for t in tracks]
["Sweet Child o' Mine", 'Welcome to the Jungle']
>>>
Get similar artists
>>> similar = artist.get_similar(limit=2)
>>> [t.name for t in similar]
['Slash', 'Aerosmith']
>>>
Search artists
>>> search = Artist.search("gun", limit=5)
>>> [x.name for x in search]
["Guns N' Roses", 'Guano Apes', 'Shiny Toy Guns', 'Machine Gun Kelly', 'G-Unit']
Artist Tagging
>>> artist = Artist.find("Guns N' Roses")
>>> artist.add_tags(["super", "hot"])
>>> artist.remove_tag("hot")
Get user artist tags
>>>
>>> tags = artist.get_tags(user="Zaratoustre")
>>> [x.name for x in tags]
['foo']
>>>
Get top artist tags
 >>> artist = Artist.find("Guns N' Roses")
>>> tags = artist.get_top_tags()
>>> [x.name for x in tags]
['hard rock', 'rock', 'classic rock', '80s', 'metal', 'heavy metal', 'seen live', 'Guns N Roses', 'american', 'hair metal', '90s', 'glam rock', 'alternative', 'Glam Metal', "Guns N' Roses", 'Slash', 'rock n roll', 'USA', 'sleaze rock', 'alternative rock', 'guitar', 'Axl Rose', 'male vocalists', 'punk', 'blues rock']
Top artists by country
>>> artists = Artist.get_top_artists_by_country(country="italy", limit=5)
>>> [t.name for t in artists]
['David Bowie', 'Radiohead', 'Pink Floyd', 'Coldplay', 'The Beatles']
>>>
Top artists chart
>>> artists =  Artist.get_top_artists_chart(limit=3)
>>> [t.name for t in artists]
['Queen', 'Ariana Grande', 'Imagine Dragons']
>>>

Tag Webservices

Retrieve tag
>>> from pydrag import Tag
>>>
>>> tag = Tag.find(name="rap", lang="en")
>>> tag.name
'rap'
>>> tag
Tag(name='rap', reach=100855, url=None, taggings=None, count=None, total=542012, wiki=Wiki(content='Rap is a vocal style, usually coming together with hip-hop, the musical genre off-shoot of the hip hop culture. Rapping itself, also known as emceeing, MCing, spitting, or just rhyming, is the rhythmic spoken delivery of rhymes and wordplay. Rapping is one of the four pillars of the hip hop culture, along with DJing, graffiti, and breaking.\n\nRap is also considered a separate genre from hip hop in some cases where the artists do not make music compatible with the hip hop culture. Some of these cases include Lil Wayne, Juelz Santana, Lil Jon, 50 Cent, T.I., The Game, and Nelly. Rap music has a general focus on pop, hyphy, and snap beats, while hip hop has a general focus on the other four pillars of hip hop. <a href="http://www.last.fm/tag/rap">Read more on Last.fm</a>. User-contributed text is available under the Creative Commons By-SA License; additional terms may apply.', summary='Rap is a vocal style, usually coming together with hip-hop, the musical genre off-shoot of the hip hop culture. Rapping itself, also known as emceeing, MCing, spitting, or just rhyming, is the rhythmic spoken delivery of rhymes and wordplay. Rapping is one of the four pillars of the hip hop culture, along with DJing, graffiti, and breaking.\n\nRap is also considered a separate genre from hip hop in some cases where the artists do not make music compatible with the hip hop culture. <a href="http://www.last.fm/tag/rap">Read more on Last.fm</a>.', published=None, links=None))
>>>
Get top tags
>>> from pydrag import Tag
>>> tags = Tag.get_top_tags(limit=10, page=1)
>>> [x.name for x in tags]
['rock', 'electronic', 'seen live', 'alternative', 'indie', 'pop', 'female vocalists', 'metal', 'alternative rock', 'classic rock']
>>>
Get top tags chart
>>> tags = Tag.get_top_tags_chart(limit=10, page=1)
>>> tags[0]
Tag(name='rock', reach=393484, url='https://www.last.fm/tag/rock', taggings=3949977, count=None, total=None, wiki=Wiki(content=None, summary=None, published=None, links=None))
Get similar tags
>>> tag = Tag.find(name="rock", lang="en")
>>> tags = tag.get_similar()
>>> [x.name for x in tags]
[]
>>>
Get tag top albums
>>> tag = Tag.find(name="rap", lang="en")
>>> albums = tag.get_top_albums(limit=5)
>>> [x.name for x in albums]
['The Eminem Show', 'Views', 'Relapse', 'The Blueprint 3', 'Beerbongs & Bentleys']
>>>
Get tag top artists
>>> tag = Tag.find(name="rap", lang="en")
>>> artists = tag.get_top_artists(limit=5)
>>> [x.name for x in artists]
['Eminem', "Lil' Wayne", '2Pac', 'Dr. Dre', '50 Cent']
>>>
Get tag top tracks
>>> tag = Tag.find(name="rap", lang="en")
>>> tracks = tag.get_top_tracks(limit=5)
>>> [x.name for x in tracks]
['Stronger', 'Clint Eastwood', 'Lollipop', 'Best I Ever Had', 'Heartless']
>>>
Get tag weekly chart list
>>> charts = tag.get_weekly_chart_list()
>>> charts[0]
Chart(text='', from_date='1108296000', to_date='1108900800')
>>> charts[1]
Chart(text='', from_date='1108900800', to_date='1109505600')
>>> charts[10]
Chart(text='', from_date='1114344000', to_date='1114948800')
>>>

API Reference

This page lists all of the last.fm interfaces exposed by the pydrag package.

Track Class

class pydrag.Track(name, artist, url=None, mbid=None, image=None, playcount=None, userplaycount=None, listeners=None, duration=None, match=None, wiki=None, album=None, top_tags=None, loved=None, timestamp=None, rank=None)[source]

Bases: pydrag.services.ApiMixin, pydrag.models.common.BaseModel

Last.FM track, chart and geo api wrapper.

Parameters
property date: Optional[datetime.datetime]

If the timestamp property is available return a datetime instance.

Return type

datetime.datetime

classmethod from_dict(data)[source]

Construct a BaseModel from a dictionary based on the class fields type annotations. Only primitive types are supported.

Parameters

data (Type[BaseModel]) –

Return type

BaseModel

classmethod find(artist, track, user=None, lang='en')[source]

Get the metadata for a track.

Parameters
  • artist (str) – The artist name

  • track (str) – The track name

  • user (Optional[str]) – The username for the context of the request. If supplied, response will include the user’s playcount for this track

  • lang (str) – The language to return the biography in, ISO 639

Return type

Track

classmethod find_by_mbid(mbid, user=None, lang='en')[source]

Get the metadata for a track.

Parameters
  • mbid (str) – The musicbrainz id for the track

  • user (Optional[str]) – The username for the context of the request. If supplied, response will include the user’s playcount for this track

  • lang (str) – The language to return the biography in, ISO 639

Return type

Track

get_info(user=None, lang='en')[source]

There are many ways we end up with an incomplete instance of a track instance likes charts, tags etc, This is a quick method to refresh our object with complete data from the find methods.

Parameters
  • user (Optional[str]) – The username for the context of the request. If supplied, response will include the user’s playcount and loved status

  • lang (str) – The language to return the biography in, ISO-639

Return type

Track

classmethod get_correction(track, artist)[source]

Use the last.fm corrections data to check whether the supplied track has a correction to a canonical track.

Return type

Track

classmethod search(track, limit=50, page=1)[source]

Search for an track by name. Returns track matches sorted by relevance.

Parameters
  • track (str) – The track name.

  • page (int) – The page number to fetch.

  • limit (int) – The number of results to fetch per page.

Return type

pydrag.models.common.ListModel of Track

classmethod get_top_tracks_by_country(country, limit=50, page=1)[source]
Parameters
  • country (str) – The country to fetch the top tracks.

  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

pydrag.models.common.ListModel of Track

classmethod get_top_tracks_chart(limit=50, page=1)[source]

Get the top tracks chart.

Parameters
  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

pydrag.models.common.ListModel of Track

add_tags(tags)[source]

Tag an track with one or more user supplied tags.

Parameters

tags (list of str) – A list of user supplied tags to apply to this track. Accepts a maximum of 10 tags.

Return type

RawResponse

remove_tag(tag)[source]

Remove a user’s tag from an track.

Parameters

tag (str) – A single user tag to remove from this track.

Return type

RawResponse

get_similar(limit=50)[source]

Get all the tracks similar to this track.

Parameters

limit (int) – Limit the number of similar tracks returned

Return type

pydrag.models.common.ListModel of Track

get_tags(user)[source]

Get the tags applied by an individual user to an track on Last.fm.

Parameters

user (str) – The username for the context of the request.

Return type

pydrag.models.common.ListModel of Tag

get_top_tags()[source]

Get the top tags for an track on Last.fm, ordered by popularity.

Return type

pydrag.models.common.ListModel of Tag

love()[source]

Love a track for a user profile.

Return type

RawResponse

unlove()[source]

Unlove a track for a user profile.

Return type

RawResponse

classmethod scrobble_tracks(tracks, batch_size=10)[source]

Split tracks into the desired batch size, with maximum size set to 50 and send the tracks for processing, I am debating if this even belongs here.

Parameters
  • tracks (List[ScrobbleTrack]) – The tracks to scrobble

  • batch_size – The number of tracks to submit per cycle

Return type

pydrag.models.common.ListModel of ScrobbleTrack

classmethod update_now_playing(artist, track, album=None, track_number=None, context=None, duration=None, album_artist=None)[source]
Parameters
  • artist (str) – The artist name

  • track (str) – The track name

  • album (Optional[str]) – The album name

  • track_number (Optional[int]) – The track number of the track on the album

  • context (Optional[str]) – Sub-client version (not public)

  • duration (Optional[int]) – The length of the track in seconds

  • album_artist (Optional[str]) – The album artist

Return type

RawResponse

Album Class

class pydrag.Album(name, mbid=None, url=None, image=None, playcount=None, artist=None, listeners=None, tags=None, tracks=None, wiki=None, rank=None)[source]

Bases: pydrag.models.common.BaseModel, pydrag.services.ApiMixin

Last.FM track, chart and geo api wrapper.

Parameters
classmethod from_dict(data)[source]

Construct a BaseModel from a dictionary based on the class fields type annotations. Only primitive types are supported.

Parameters

data (Type[BaseModel]) –

Return type

BaseModel

classmethod find(artist, album, user=None, lang='en')[source]

Get the metadata and tracklist for an album on Last.fm.

Parameters
  • album (str) – The album name to find.

  • artist (str) – The album artist to find.

  • user (Optional[str]) – The username for the context of the request. If supplied, response will include the user’s playcount for this album

  • lang (str) – The language to return the biography in, ISO-639

Return type

Album

classmethod find_by_mbid(mbid, user=None, lang='en')[source]

Get the metadata and tracklist for an album on Last.fm.

Parameters
  • mbid (str) – The musicbrainz id for the album.

  • user (Optional[str]) – The username for the context of the request. If supplied, response will include the user’s playcount for this album

  • lang (str) – The language to return the biography in, ISO-639

Return type

Album

get_info(user=None, lang='en')[source]

There are many ways we end up with an incomplete instance of an album instance likes charts, tags etc, This is a quick method to refresh our object with complete data from the find methods.

Parameters
  • user (Optional[str]) – The username for the context of the request. If supplied, response will include the user’s playcount

  • lang (str) – The language to return the biography in, ISO-639

Return type

Album

classmethod search(album, limit=50, page=1)[source]

Search for an album by name.Returns album matches sorted by relevance.

Parameters
  • album (str) – The album name to search.

  • page (int) – The page number to fetch.

  • limit (int) – The number of results to fetch per page.

Return type

pydrag.models.common.ListModel of Album

add_tags(tags)[source]

Tag an album using a list of user supplied tags.

Parameters

tags (List[str]) – A list of user supplied tags to apply to this album. Accepts a maximum of 10 tags.

Return type

RawResponse

remove_tag(tag)[source]

Remove a user’s tag from an album.

Parameters

tag (str) – A single user tag to remove from this album.

Return type

RawResponse

get_tags(user)[source]

Get the tags applied by an individual user to an album on Last.fm.

Parameters

user (str) – The username for the context of the request.

Return type

pydrag.models.common.ListModel of Tag

get_top_tags()[source]

Get the top tags for an album on Last.fm, ordered by popularity.

Return type

pydrag.models.common.ListModel of Tag

Artist Class

class pydrag.Artist(name, mbid=None, url=None, tag_count=None, listeners=None, playcount=None, userplaycount=None, image=None, match=None, tags=None, bio=None, on_tour=None, similar=None, rank=None)[source]

Bases: pydrag.models.common.BaseModel, pydrag.services.ApiMixin

Last.FM track, chart and geo api wrapper.

Parameters
classmethod from_dict(data)[source]

Construct a BaseModel from a dictionary based on the class fields type annotations. Only primitive types are supported.

Parameters

data (Type[BaseModel]) –

Return type

BaseModel

classmethod find(artist, user=None, lang='en')[source]

Get the metadata for an artist. Includes biography, truncated at 300 characters.

Parameters
  • artist (str) – The artist name to retrieve.

  • user (Optional[str]) – The username for the context of the request. If supplied, response will include the user’s playcount

  • lang (str) – The language to return the biography in, ISO-639

Return type

Artist

classmethod find_by_mbid(mbid, user=None, lang='en')[source]

Get the metadata for an artist. Includes biography, truncated at 300 characters.

Parameters
  • mbid (str) – The musicbrainz id for the artist

  • user (Optional[str]) – The username for the context of the request. If supplied, response will include the user’s playcount

  • lang (str) – The language to return the biography in, ISO-639

Return type

Artist

get_info(user=None, lang='en')[source]

There are many ways we end up with an incomplete instance of an artist instance likes charts, tags etc, This is a quick method to refresh our object with complete data from the find methods.

Parameters
  • user (Optional[str]) – The username for the context of the request. If supplied, response will include the user’s playcount

  • lang (str) – The language to return the biography in, ISO-639

Return type

Artist

classmethod search(artist, limit=50, page=1)[source]

Search for an artist by name. Returns artist matches sorted by relevance.

Parameters
  • artist (str) – The artist name to search.

  • page (int) – The page number to fetch.

  • limit (int) – The number of results to fetch per page.

Return type

pydrag.models.common.ListModel of Artist

classmethod get_top_artists_by_country(country, limit=50, page=1)[source]
Parameters
  • country (str) – The country name to fetch results.

  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

pydrag.models.common.ListModel of Artist

classmethod get_top_artists_chart(limit=50, page=1)[source]

Get the top artists chart.

Parameters
  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

pydrag.models.common.ListModel of Artist

add_tags(tags)[source]

Tag an artist with one or more user supplied tags.

Parameters

tags (List[str]) – A list of user supplied tags to apply to this artist. Accepts a maximum of 10 tags.

Return type

RawResponse

remove_tag(tag)[source]

Remove a user’s tag from an artist.

Parameters

tag (str) – A single user tag to remove from this artist.

Return type

RawResponse

get_correction()[source]

Use the last.fm corrections data to check whether the supplied artist has a correction to a canonical artist.

Return type

Artist

get_similar(limit=50)[source]

Get all the artists similar to this artist.

Parameters

limit (int) – Limit the number of similar artists returned

Return type

pydrag.models.common.ListModel of Artist

get_tags(user)[source]

Get the tags applied by an individual user to an artist on Last.fm.

Parameters

user (str) – The username for the context of the request.

Return type

pydrag.models.common.ListModel of Tag

get_top_tags()[source]

Get the top tags for an artist on Last.fm, ordered by popularity.

Return type

pydrag.models.common.ListModel of Tag

get_top_tracks(limit=50, page=1)[source]

Get the top tags for an artist on Last.fm, ordered by popularity.

Parameters
  • page (int) – The page number to fetch.

  • limit (int) – The number of results to fetch per page.

Return type

pydrag.models.common.ListModel of Track

User Class

class pydrag.User(playlists, playcount, gender, name, url, country, image, age, registered, real_name=None, recent_track=None)[source]

Bases: pydrag.models.common.BaseModel, pydrag.services.ApiMixin

Last.FM user and user library api wrapper.

Parameters
  • playcount (int) – Total track playcount

  • gender (str) – Gender

  • name (str) – Display name

  • url (str) – Last.fm profile url

  • country (str) – Country name

  • image (List[Image]) – User’s avatar in multiple sizes

  • age (int) – Self explanatory

  • registered (int) – Unix timestamp of the registration date

  • real_name (Optional[str]) – The full name

  • recent_track (Optional[Track]) – User’s most recent scrobble track

property date_registered: datetime.datetime

Return a datetime instance of the user’s registration date.

Return type

datetime.datetime

classmethod from_dict(data)[source]

Construct a BaseModel from a dictionary based on the class fields type annotations. Only primitive types are supported.

Parameters

data (Type[BaseModel]) –

Return type

BaseModel

classmethod find(username)[source]

Get information about a user profile.

Return type

User

get_artists(limit=50, page=1)[source]

Retrieve a paginated list of all the artists in the user’s library, with playcounts and tagcounts.

Parameters
  • page (int) – The page number to fetch.

  • limit (int) – The number of results to fetch per page.

Return type

ListModel of Artist

get_artist_tracks(artist, from_date=None, to_date=None, page=1)[source]

Get a list of tracks by a given artist scrobbled by this user, including scrobble time. Can be limited to specific timeranges, defaults to all time.

Parameters
  • artist (str) – The artist name you are interested in

  • from_date (Optional[str]) – An unix timestamp to start at.

  • to_date (Optional[str]) – An unix timestamp to end at.

  • page (int) – The page number to fetch.

Return type

ListModel of Track

get_friends(recent_tracks, limit=50, page=1)[source]

Get a list of the user’s friends on Last.fm.

Parameters
  • recent_tracks (bool) – Whether or not to include information about friends’ recent listening in the response.

  • page (int) – The page number to fetch.

  • limit (int) – The number of results to fetch per page.

Return type

ListModel of User

get_loved_tracks(limit=50, page=1)[source]

Get the user’s loved tracks list.

Parameters
  • page (int) – The page number to fetch.

  • limit (int) – The number of results to fetch per page.

Return type

ListModel of Track

get_personal_tags(tag, category, limit=50, page=1)[source]

Get the user’s personal tags.

Parameters
  • tag (str) – The tag you’re interested in.

  • category (str) – The type of items which have been tagged

  • page (int) – The page number to fetch.

  • limit (int) – The number of results to fetch per page.

Return type

ListModel of Track or Artist or Album

get_recent_tracks(from_date=None, to_date=None, limit=50, page=1)[source]

Get a list of the recent tracks listened to by this user. Also includes the currently playing track with the nowplaying=”true” attribute if the user is currently listening.

Parameters
  • from_date (Optional[str]) – Beginning timestamp of a range - only display scrobbles after this time, in UNIX timestamp format (integer number of seconds since 00:00:00, January 1st 1970 UTC). This must be in the UTC time zone.

  • to_date (Optional[str]) – End timestamp of a range - only display scrobbles before this time, in UNIX timestamp format (integer number of seconds since 00:00:00, January 1st 1970 UTC). This must be in the UTC time zone.

  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

ListModel of Track

get_top_albums(period, limit=50, page=1)[source]

Get the top albums listened to by a user. You can stipulate a time period.

Parameters
  • period (Period) –

  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

ListModel of Album

Return type

List[Album]

get_top_artists(period, limit=50, page=1)[source]

Get the top artists listened to by a user. You can stipulate a time period.

Parameters
  • period (Period) –

  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

ListModel of Artist

get_top_tags(limit=50)[source]

Get the top tags used by this user.

Parameters

limit (int) – Limit the number of tags returned

Return type

ListModel of Tag

Return type

List[Tag]

get_top_tracks(period, limit=50, page=1)[source]

Get the top tracks listened to by a user. You can stipulate a time period.

Parameters
  • period (Period) –

  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

ListModel of Track

get_weekly_album_chart(from_date=None, to_date=None)[source]
Parameters
  • from_date (Optional[str]) – The date at which the chart should start from.

  • to_date (Optional[str]) – The date at which the chart should end on.

Return type

ListModel of Album

get_weekly_artist_chart(from_date=None, to_date=None)[source]

Get an album chart for a user profile, for a given date range. If no date range is supplied, it will return the most recent album chart for this user.

Parameters
  • from_date (Optional[str]) – The date at which the chart should start from.

  • to_date (Optional[str]) – The date at which the chart should end on.

Return type

ListModel of Artist

get_weekly_chart_list()[source]

Get an artist chart for a user profile, for a given date range. If no date range is supplied, it will return the most recent artist chart for this user.

Return type

ListModel of Chart

get_weekly_track_chart(from_date=None, to_date=None)[source]

Get a list of available charts for this user, expressed as date ranges which can be sent to the chart services.

Parameters
  • from_date (Optional[str]) – The date at which the chart should start from.

  • to_date (Optional[str]) – The date at which the chart should end on.

Return type

ListModel of Track

Tag Class

class pydrag.Tag(name, reach=None, url=None, taggings=None, count=None, total=None, wiki=None)[source]

Bases: pydrag.models.common.BaseModel, pydrag.services.ApiMixin

Last.FM tag, chart and geo api wrapper.

Parameters
classmethod from_dict(data)[source]

Construct a BaseModel from a dictionary based on the class fields type annotations. Only primitive types are supported.

Parameters

data (Type[BaseModel]) –

Return type

BaseModel

classmethod find(name, lang=None)[source]

Get the metadata for a tag.

Parameters
  • name (str) – The tag name

  • lang (Optional[str]) – The language to return the wiki in, ISO-639

Return type

Tag

classmethod get_top_tags(limit=50, page=1)[source]

Fetches the top global tags on Last.fm, sorted by popularity Old school pagination on this endpoint, keep uniformity.

Parameters
  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

pydrag.models.common.ListModel of Tag

classmethod get_top_tags_chart(limit=50, page=1)[source]

Get the top tags chart.

Parameters
  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

pydrag.models.common.ListModel of Tag

get_similar()[source]

Search for tags similar to this one. Returns tags ranked by similarity, based on listening data.

Return type

pydrag.models.common.ListModel of Tag

get_top_albums(limit=50, page=1)[source]

Get the top albums tagged by this tag, ordered by tag count.

Parameters
  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

pydrag.models.common.ListModel of Album

get_top_artists(limit=50, page=1)[source]

Get the top artists tagged by this tag, ordered by tag count.

Parameters
  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

pydrag.models.common.ListModel of Artist

get_top_tracks(limit=50, page=1)[source]

Get the top tracks tagged by this tag, ordered by tag count.

Parameters
  • limit (int) – The number of results to fetch per page.

  • page (int) – The page number to fetch.

Return type

pydrag.models.common.ListModel of Track

get_weekly_chart_list()[source]

Get a list of available charts for this tag, expressed as date ranges which can be sent to the chart services.

Return type

pydrag.models.common.ListModel of Chart

Common Classes

class pydrag.models.common.BaseModel[source]

Bases: object

Pydrag Base Model.

Parameters

params – The params used to fetch the api response data

to_dict()[source]

Convert our object to a traditional dictionary. Filter out None values and dictionary values. The last one is like a validation for the unit tests in case we forgot to properly deserialize an dict to an object.

Return type

Dict

classmethod from_dict(data)[source]

Construct a BaseModel from a dictionary based on the class fields type annotations. Only primitive types are supported.

Parameters

data (Type[BaseModel]) –

Return type

BaseModel

class pydrag.models.common.ListModel(data=<factory>, page=None, limit=None, total=None, tag=None, user=None, artist=None, track=None, album=None, country=None, from_date=None, to_date=None, search_terms=None)[source]

Bases: collections.UserList, Sequence[T], pydrag.models.common.BaseModel

Wrap a list of BaseModel objects with metadata.

Parameters
classmethod from_dict(data)[source]

Construct a BaseModel from a dictionary based on the class fields type annotations. Only primitive types are supported.

Parameters

data (Type[BaseModel]) –

Return type

BaseModel

class pydrag.models.common.RawResponse(data=None)[source]

Bases: pydrag.models.common.BaseModel

Most of the write operations don’t return any response body but still for consistency we need to return a BaseModel with all the metadata params.

Parameters

data (Optional[Dict]) – The raw response dictionary

to_dict()[source]

Convert our object to a traditional dictionary. Filter out None values and dictionary values. The last one is like a validation for the unit tests in case we forgot to properly deserialize an dict to an object.

Return type

Dict

classmethod from_dict(data)[source]

Construct a BaseModel from a dictionary based on the class fields type annotations. Only primitive types are supported.

Parameters

data (Type[BaseModel]) –

Return type

BaseModel

class pydrag.models.common.Config(api_key, api_secret, username, password, session=None)[source]

Bases: object

Pydrag config object for your last.fm api.

Parameters
  • api_key (str) – Your application api key

  • api_secret (Optional[str]) – Your application api secret

  • username (Optional[str]) – The user’ name you want to authenticate

  • password (Optional[str]) – The user’s password you want to authenticate

  • session (Optional[ForwardRef]) – The already authenticated user’s session key

static instance(api_key=None, api_secret=None, username=None, password=None, session=None)[source]

Get/Create a config instance, if no api key is specified it attempt to read the settings from environmental variables.

class pydrag.models.common.Image(size, text)[source]

Bases: pydrag.models.common.BaseModel

class pydrag.models.common.Chart(text, from_date, to_date)[source]

Bases: pydrag.models.common.BaseModel

Bases: pydrag.models.common.BaseModel

class pydrag.models.common.Wiki(content=None, summary=None, published=None, links=None)[source]

Bases: pydrag.models.common.BaseModel

classmethod from_dict(data)[source]

Construct a BaseModel from a dictionary based on the class fields type annotations. Only primitive types are supported.

Parameters

data (Type[BaseModel]) –

Return type

BaseModel

Api Mixin

class pydrag.services.ApiMixin[source]

Bases: object

classmethod get_session()[source]

Return the session from configuration or attempt to authenticate the configuration user.

Return type

AuthSession

classmethod retrieve(bind, flatten=None, params=None)[source]

Perform an api retrieve/get resource action.

Parameters
  • bind (BaseModel) – Class type to construct from the api response.

  • flatten (str) – A dot separated string used to flatten nested list of values

  • params (Dict) – A dictionary of query string params

Return type

BaseModel

classmethod submit(bind, flatten=None, params=None, sign=False, stateful=False, authenticate=False)[source]

Perform an api write/update resource action.

Parameters
  • bind (BaseModel) – Class type to construct from the api response.

  • flatten (str) – A dot separated string used to flatten nested list of values

  • params (Dict) – A dictionary of body params

  • sign (bool) – Sign the request with the api secret

  • stateful (bool) – Requires a session

  • authenticate (bool) – Perform an authentication request

Return type

BaseModel

classmethod prepare_params(params, sign, stateful, authenticate)[source]

Perform common parameter tasks before sending the web request.

  • Filter out None values,

  • Set the preferred api format json

  • Add the api key, session or signature based on the state flags

Parameters
  • params (Dict) – A dictionary of body or query string params

  • sign (bool) – Sign the request with the api secret

  • stateful (bool) – Add the session key to the params

  • authenticate (bool) – Add the username and auth token to the params

Return type

Dict

classmethod bind_data(bind, body, flatten=None)[source]

Construct a BaseModel from the response body and the flatten directive.

Parameters
  • bind (BaseModel) – Class type to construct from the api response.

  • body (Dict) – The api response

  • flatten (str) – A dot separated string used to flatten nested list of values

Return type

BaseModel

static raise_for_error(body)[source]

Parse and raise api errors.

Parameters

body (Dict) – Response body

Raise

ApiError

static sign(params)[source]

Last.fm signing formula for webservice calls. Exclude format, sort params, append the api secret key and hash the params string.

Parameters

params (Dict) –

Return type

str

Indices and tables