or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmusic-objects.mdnetwork-auth.mdscrobbling.mdsearch-discovery.mduser-social.md

index.mddocs/

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

```