0
# PyLast
1
2
A comprehensive Python interface to Last.fm and Libre.fm APIs that provides full object-oriented access to music data, scrobbling functionality, user profiles, and social music networking features. PyLast offers complete coverage of Last.fm web services including music discovery, recommendations, user statistics, and social interactions with caching and proxy support.
3
4
## Package Information
5
6
- **Package Name**: pylast
7
- **Language**: Python
8
- **Installation**: `pip install pylast`
9
- **Repository**: https://github.com/pylast/pylast
10
- **Documentation**: Use `help(pylast)` or see tests/ for examples
11
12
## Core Imports
13
14
```python
15
import pylast
16
```
17
18
Main entry points:
19
20
```python
21
from pylast import LastFMNetwork, LibreFMNetwork
22
```
23
24
Common objects and utilities:
25
26
```python
27
from pylast import (
28
Artist, Track, Album, User, AuthenticatedUser,
29
SessionKeyGenerator, md5,
30
WSError, PyLastError
31
)
32
```
33
34
## Basic Usage
35
36
```python
37
import pylast
38
39
# Initialize network with API credentials
40
API_KEY = "your_api_key"
41
API_SECRET = "your_api_secret"
42
username = "your_username"
43
password_hash = pylast.md5("your_password")
44
45
network = pylast.LastFMNetwork(
46
api_key=API_KEY,
47
api_secret=API_SECRET,
48
username=username,
49
password_hash=password_hash
50
)
51
52
# Get music objects
53
artist = network.get_artist("Iron Maiden")
54
track = network.get_track("Iron Maiden", "The Nomad")
55
album = network.get_album("Iron Maiden", "Brave New World")
56
57
# Basic music data access
58
print(f"Artist: {artist.get_name()}")
59
print(f"Play count: {artist.get_playcount()}")
60
print(f"Similar artists: {[a.item.get_name() for a in artist.get_similar(limit=5)]}")
61
62
# User interactions
63
track.love() # Love a track
64
track.add_tags(("metal", "progressive")) # Add tags
65
66
# Scrobbling
67
network.scrobble(
68
artist="Iron Maiden",
69
title="The Nomad",
70
timestamp=int(time.time())
71
)
72
73
# User data
74
user = network.get_authenticated_user()
75
recent_tracks = user.get_recent_tracks(limit=10)
76
for played_track in recent_tracks:
77
print(f"{played_track.track.get_artist()} - {played_track.track.get_title()}")
78
```
79
80
## Architecture
81
82
PyLast provides a comprehensive object-oriented interface to Last.fm APIs:
83
84
- **Network Objects**: LastFMNetwork and LibreFMNetwork serve as main entry points and manage API communication, authentication, and rate limiting
85
- **Music Objects**: Artist, Track, and Album represent music entities with rich metadata and social features
86
- **User Objects**: User and AuthenticatedUser provide access to listening history, preferences, and social data
87
- **Search Objects**: Dedicated search classes for discovering music content
88
- **Data Structures**: Named tuples for structured data (TopItem, SimilarItem, PlayedTrack, etc.)
89
- **Authentication**: Session-based authentication with multiple auth methods
90
- **Utilities**: Helper functions, constants, and comprehensive error handling
91
92
This design enables full integration with Last.fm's music database and social networking features while providing caching, proxy support, and rate limiting for production use.
93
94
## Capabilities
95
96
### Network and Authentication
97
98
Core network initialization, authentication methods, session management, and configuration options including proxy and caching support.
99
100
```python { .api }
101
class LastFMNetwork:
102
def __init__(self, api_key="", api_secret="", session_key="", username="", password_hash="", token=""): ...
103
104
class LibreFMNetwork:
105
def __init__(self, api_key="", api_secret="", session_key="", username="", password_hash=""): ...
106
107
class SessionKeyGenerator:
108
def __init__(self, network): ...
109
def get_web_auth_url(self) -> str: ...
110
def get_session_key(self, username: str, password_hash: str) -> str: ...
111
```
112
113
[Network and Authentication](./network-auth.md)
114
115
### Music Objects
116
117
Comprehensive music entity objects (Artist, Track, Album) with metadata access, social features, statistics, and content discovery capabilities.
118
119
```python { .api }
120
class Artist:
121
def __init__(self, name: str, network, username=None, info=None): ...
122
def get_name(self, properly_capitalized=False) -> str: ...
123
def get_similar(self, limit=None) -> list[SimilarItem]: ...
124
def get_top_tracks(self, limit=None, cacheable=True) -> list[TopItem]: ...
125
126
class Track:
127
def __init__(self, artist: str, title: str, network, username=None, info=None): ...
128
def love(self) -> None: ...
129
def get_similar(self, limit=None) -> list[SimilarItem]: ...
130
131
class Album:
132
def __init__(self, artist: str, title: str, network, username=None, info=None): ...
133
def get_tracks(self) -> list[Track]: ...
134
```
135
136
[Music Objects](./music-objects.md)
137
138
### User and Social Features
139
140
User profiles, listening history, social interactions, library access, and community features including friends, tags, and recommendations.
141
142
```python { .api }
143
class User:
144
def __init__(self, user_name: str, network): ...
145
def get_recent_tracks(self, limit=50, cacheable=True, stream=True, from_date=None, to_date=None) -> list[PlayedTrack]: ...
146
def get_loved_tracks(self, limit=50, cacheable=True) -> list[LovedTrack]: ...
147
def get_top_artists(self, period="overall", limit=None, cacheable=True) -> list[TopItem]: ...
148
149
class AuthenticatedUser(User):
150
def __init__(self, network): ...
151
152
class Library:
153
def __init__(self, user, network): ...
154
def get_artists(self, limit=50, cacheable=True, stream=True) -> list[LibraryItem]: ...
155
```
156
157
[User and Social Features](./user-social.md)
158
159
### Search and Discovery
160
161
Music search capabilities, content discovery, geographic data, and tag-based music exploration with pagination support.
162
163
```python { .api }
164
class ArtistSearch:
165
def __init__(self, artist_name: str, network): ...
166
def get_next_page(self) -> list[Artist]: ...
167
def get_total_result_count(self) -> int: ...
168
169
class TrackSearch:
170
def __init__(self, artist_name: str, track_name: str, network): ...
171
def get_next_page(self) -> list[Track]: ...
172
173
class AlbumSearch:
174
def __init__(self, album_name: str, network): ...
175
def get_next_page(self) -> list[Album]: ...
176
177
class Country:
178
def __init__(self, name: str, network): ...
179
def get_top_artists(self, limit=None, cacheable=True) -> list[TopItem]: ...
180
181
class Tag:
182
def __init__(self, name: str, network): ...
183
def get_top_artists(self, limit=None, cacheable=True) -> list[TopItem]: ...
184
```
185
186
[Search and Discovery](./search-discovery.md)
187
188
### Scrobbling and Data Tracking
189
190
Music scrobbling, now playing updates, listening data management, and play count tracking with timestamp support.
191
192
```python { .api }
193
# Network scrobbling methods
194
def scrobble(self, artist: str, title: str, timestamp: int, album=None, track_number=None, mbid=None, duration=None) -> None: ...
195
def scrobble_many(self, tracks: list) -> None: ...
196
def update_now_playing(self, artist: str, title: str, album=None, track_number=None, mbid=None, duration=None) -> None: ...
197
```
198
199
[Scrobbling and Data Tracking](./scrobbling.md)
200
201
## Core Data Types
202
203
```python { .api }
204
from collections import namedtuple
205
206
TopItem = namedtuple('TopItem', ['item', 'weight'])
207
SimilarItem = namedtuple('SimilarItem', ['item', 'match'])
208
LibraryItem = namedtuple('LibraryItem', ['item', 'playcount', 'tagcount'])
209
PlayedTrack = namedtuple('PlayedTrack', ['track', 'album', 'playback_date', 'timestamp'])
210
LovedTrack = namedtuple('LovedTrack', ['track', 'date', 'timestamp'])
211
ImageSizes = namedtuple('ImageSizes', ['original', 'large', 'largesquare', 'medium', 'small', 'extralarge'])
212
Image = namedtuple('Image', ['title', 'url', 'dateadded', 'format', 'owner', 'sizes', 'votes'])
213
```
214
215
## Constants and Utilities
216
217
```python { .api }
218
# Time periods for statistics
219
PERIOD_OVERALL = "overall"
220
PERIOD_7DAYS = "7day"
221
PERIOD_1MONTH = "1month"
222
PERIOD_3MONTHS = "3month"
223
PERIOD_6MONTHS = "6month"
224
PERIOD_12MONTHS = "12month"
225
226
# Image sizes
227
SIZE_SMALL = 0
228
SIZE_MEDIUM = 1
229
SIZE_LARGE = 2
230
SIZE_EXTRA_LARGE = 3
231
SIZE_MEGA = 4
232
233
# Language domains
234
DOMAIN_ENGLISH = 0
235
DOMAIN_GERMAN = 1
236
DOMAIN_SPANISH = 2
237
DOMAIN_FRENCH = 3
238
DOMAIN_ITALIAN = 4
239
DOMAIN_POLISH = 5
240
DOMAIN_PORTUGUESE = 6
241
DOMAIN_SWEDISH = 7
242
DOMAIN_TURKISH = 8
243
DOMAIN_RUSSIAN = 9
244
DOMAIN_JAPANESE = 10
245
DOMAIN_CHINESE = 11
246
247
# Scrobble source constants
248
SCROBBLE_SOURCE_USER = "P"
249
SCROBBLE_SOURCE_NON_PERSONALIZED_BROADCAST = "R"
250
SCROBBLE_SOURCE_PERSONALIZED_BROADCAST = "E"
251
SCROBBLE_SOURCE_LASTFM = "L"
252
SCROBBLE_SOURCE_UNKNOWN = "U"
253
254
# Scrobble mode constants
255
SCROBBLE_MODE_PLAYED = ""
256
SCROBBLE_MODE_LOVED = "L"
257
SCROBBLE_MODE_BANNED = "B"
258
SCROBBLE_MODE_SKIPPED = "S"
259
260
# Image ordering options
261
IMAGES_ORDER_POPULARITY = "popularity"
262
IMAGES_ORDER_DATE = "dateadded"
263
264
# Utility function
265
def md5(text: str) -> str: ...
266
```
267
268
## Exception Handling
269
270
```python { .api }
271
class PyLastError(Exception):
272
"""Base exception for PyLast"""
273
274
class WSError(PyLastError):
275
"""Web service related errors with status codes"""
276
def get_id(self) -> int:
277
"""Returns the error status code"""
278
279
class MalformedResponseError(PyLastError):
280
"""Malformed response from music network"""
281
282
class NetworkError(PyLastError):
283
"""Network connection errors"""
284
285
# Error status constants
286
STATUS_INVALID_SERVICE = 2
287
STATUS_INVALID_METHOD = 3
288
STATUS_AUTH_FAILED = 4
289
STATUS_INVALID_FORMAT = 5
290
STATUS_INVALID_PARAMS = 6
291
STATUS_INVALID_RESOURCE = 7
292
STATUS_OPERATION_FAILED = 8
293
STATUS_INVALID_SK = 9
294
STATUS_INVALID_API_KEY = 10
295
STATUS_OFFLINE = 11
296
STATUS_SUBSCRIBERS_ONLY = 12
297
STATUS_INVALID_SIGNATURE = 13
298
STATUS_TOKEN_UNAUTHORIZED = 14
299
STATUS_TOKEN_EXPIRED = 15
300
STATUS_TEMPORARILY_UNAVAILABLE = 16
301
STATUS_LOGIN_REQUIRED = 17
302
STATUS_TRIAL_EXPIRED = 18
303
STATUS_NOT_ENOUGH_CONTENT = 20
304
STATUS_NOT_ENOUGH_MEMBERS = 21
305
STATUS_NOT_ENOUGH_FANS = 22
306
STATUS_NOT_ENOUGH_NEIGHBOURS = 23
307
STATUS_NO_PEAK_RADIO = 24
308
STATUS_RADIO_NOT_FOUND = 25
309
STATUS_API_KEY_SUSPENDED = 26
310
STATUS_DEPRECATED = 27
311
STATUS_RATE_LIMIT_EXCEEDED = 29
312
```