pyLast: a Python interface to Last.fm and Libre.fm
A Python interface to Last.fm and Libre.fm
At a glance
- What is it?
- pylast is a small object-oriented Python wrapper around the Last.fm web services, with scrobbling, session key authentication, proxy support and optional caching, and it also works against API-compatible networks such as Libre.fm. It is a mature library with a stable release cadence, not a new project.
- Who is it for?
- Adopt pylast when your Python project needs to read scrobble data, tag artists or push listens to Last.fm or a compatible network, since the interface is small, the object model is complete and the release history shows regular maintenance, with 7.2.0 published on 2026-09-29. Stay away if you need streaming audio or anything beyond the metadata and scrobble endpoints, because the library is a metadata and write client.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 17 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A metadata and scrobble client, not an audio player
pylast is a Python interface to Last.fm and to other API-compatible websites such as Libre.fm. The scope is the web services, not the music: the feature list names access to all the data exposed by the Last.fm web services, scrobbling support, a simple public interface, a full object-oriented design, proxy support, and internal caching support for some web service calls that is disabled by default.
That last detail is worth pausing on. The caching is partial, it is off unless you turn it on, and it exists for some calls rather than all of them. A reader who assumed a general-purpose cache layer would be wrong, and the wording in the README is careful enough to prevent that assumption.
The audience is a developer writing a script or a service that reads listening history, tags, artist metadata and album data, and writes back scrobbles. The library is a long-standing project rather than a new arrival. The package metadata names Amr Hassan as the original author with Hugo van Kemenade as maintainer, the project carries a Zenodo DOI badge, and the classifier is Development Status :: 5 - Production/Stable.
The licence is Apache-2.0, the build backend is hatchling with hatch-vcs deriving the version from the repository tags, and the source lives under a src/ directory with the version written to src/pylast/_version.py at build time. Python 3.11 is the floor, and the classifiers list CPython and PyPy for versions 3.11 through 3.15.
A Network object is the entry point for everything
The design centers on a single object. The README says that to create any object from pyLast you need a Network object, which represents a social music network that is Last.fm or any other API-compatible one. A pre-configured one is available for Last.fm, and the code for it is short:
import pylast
# You have to have your own unique two values for API_KEY and API_SECRET
# Obtain yours from https://www.last.fm/api/account/create for Last.fm
API_KEY = "b25b959554ed76058ac220b7b2e0a026" # this is a sample key
API_SECRET = "425b55975eed76058ac220b7b4e8a054"
# In order to perform a write operation you need to authenticate yourself
username = "your_user_name"
password_hash = pylast.md5("your_password")
network = pylast.LastFMNetwork(
api_key=API_KEY,
api_secret=API_SECRET,
username=username,
password_hash=password_hash,
)Two things stand out. The first is that the key and secret are per-account, obtained from the Last.fm account creation page, and the values in the README are explicitly labelled as a sample key. The second is that a username and a password hash are passed straight in, which is the legacy style of authentication the API still accepts.
Once the network object exists, everything else hangs off it. The README's next example is deliberately tiny:
# Now you can use that object everywhere
track = network.get_track("Iron Maiden", "The Nomad")
track.love()
track.add_tags(("awesome", "favorite"))A track is fetched by artist and title, then it carries write methods of its own. The library is built so that the object you fetch is the object you act on.
Session key authentication avoids putting a password in your code
The second authentication route in the README is the one a new user should prefer. Instead of a username and password hash, you authenticate with a session key, and the code shows the whole browser round trip.
import pylast
SESSION_KEY_FILE = os.path.join(os.path.expanduser("~"), ".session_key")
network = pylast.LastFMNetwork(API_KEY, API_SECRET)
if not os.path.exists(SESSION_KEY_FILE):
skg = pylast.SessionKeyGenerator(network)
url = skg.get_web_auth_url()
print(f"Please authorize this script to access your account: {url}\n")
import time
import webbrowser
webbrowser.open(url)
while True:
try:
session_key = skg.get_web_auth_session_key(url)
with open(SESSION_KEY_FILE, "w") as f:
f.write(session_key)
break
except pylast.WSError:
time.sleep(1)
else:
session_key = open(SESSION_KEY_FILE).read()
network.session_key = session_keyThe mechanism is straightforward. A SessionKeyGenerator produces a web authorization URL, the script opens it in a browser, the user authorizes the application, and the script polls for the session key, catching pylast.WSError and sleeping one second between attempts. The key is written to a .session_key file in the home directory and reused on later runs, with the network object then given the session key directly.
The security argument is simple: the password never touches the source. The cost is a file with a credential in it on disk, in your home directory, in plain text, and the file name in the example makes no attempt to hide that. If you run this in a shared environment, that file needs the same care as any other token.
Installing pylast and running the test suite
Installation is a plain pip call, and the development version is installed straight from the repository:
python3 -m pip install pylastpython3 -m pip install -U git+https://github.com/pylast/pylastThere is also a requirements.txt form in the README, which uses the egg URL syntax for a checkout install:
-e https://github.com/pylast/pylast.git#egg=pylastThe test suite is worth knowing about, because it doubles as the documentation. The tests directory contains integration and unit tests against Last.fm and, the README says, plenty of code examples, and the pydoc utility is the other route into the same information.
Running the tests needs credentials, since the integration tests talk to the real service. You can either copy example_test_pylast.yaml to test_pylast.yaml and fill it in, or export the values as environment variables:
export PYLAST_USERNAME=TODO_ENTER_YOURS_HERE
export PYLAST_PASSWORD_HASH=TODO_ENTER_YOURS_HERE
export PYLAST_API_KEY=TODO_ENTER_YOURS_HERE
export PYLAST_API_SECRET=TODO_ENTER_YOURS_HEREThe README warns that integration tests need a test account that will become cluttered with test data, which is a good reason to keep a separate account rather than pointing the suite at a real profile. The test extras are declared as an optional dependency group with pytest, pytest-cov, pytest-random-order, pytest-recording, flaky and pyyaml, and running the whole suite is a pip install of the tests extra followed by pytest.
Libre.fm works because the API shape is the same
The multi-network support is not a separate adapter layer. The README lists support for other API-compatible networks like Libre.fm alongside the Last.fm features, and the architecture explains why this comes for free: the Network object represents a social music network that is Last.fm or any other API-compatible one, and the pre-configured object exists for Last.fm specifically.
So the same object model, the same scrobble methods and the same session key flow work against a compatible deployment once the network object points at it. The difference between the two services is a base URL and, in practice, an account on the compatible service.
This is a narrower but more honest form of portability than a library that promises to abstract over many providers. A service that implements the same endpoints can be substituted, and one that does not cannot. If you are considering a network whose API is only loosely similar, the compatibility claim will not stretch to cover it.
The alternative worth weighing is calling the HTTP API yourself. The endpoints are documented by the services, the request signatures are a hash, and a modern HTTP client is a dependency you probably already have. What you lose is the object model: with pylast you fetch a track and call methods on it, and with a raw client you are assembling URLs, handling pagination and parsing the XML or JSON payloads yourself. What you gain is full control over caching, retries and request shape, which the library does not expose much of.
Release cadence, typing and the state of the dependencies
The release history is steady. Version 7.0.2 shipped on 2026-01-19, 7.1.0 on 2026-06-30 and 7.2.0 on 2026-09-29, and the last push was on 2026-10-06. The project is not archived, and the 7.x line has moved steadily through the year.
Two details in the packaging are worth a second look. The version is dynamic, taken from the version control system through hatch-vcs with the local_scheme set to no-local-version, so a local checkout gets a clean version rather than a suffixed one. And the project declares itself typed through the Typing :: Typed classifier, with a separate requirements-mypy.txt file at the top of the tree, so type checking is part of the project's own workflow rather than an aspiration.
The runtime dependency list is short, with a single entry, httpx2, and the test extras are separate. The project is built with hatchling, linted with ruff, formatted with Black, and the repository carries tox.ini, a .pre-commit-config.yaml, a .yamlfmt.yaml and a .editorconfig, which is the standard tool belt for a Python library that takes its own hygiene seriously.
For an adopter the upgrade path is a pip upgrade with no configuration migration to plan, since the API is stable across the 7.x line and the authentication model described in the README has not changed.
Editorial conclusion
Adopt pylast when your Python project needs to read scrobble data, tag artists or push listens to Last.fm or a compatible network, since the interface is small, the object model is complete and the release history shows regular maintenance, with 7.2.0 published on 2026-09-29. Stay away if you need streaming audio or anything beyond the metadata and scrobble endpoints, because the library is a metadata and write client. Before you depend on it, note that it requires Python 3.11 or newer and that the runtime dependency list names a single HTTP library, httpx2, which is worth checking against your own environment's lockfile.
Frequently asked questions
What is pylast and what can it do with Last.fm?
It is a Python interface to Last.fm and to API-compatible sites such as Libre.fm, providing access to the data exposed by the Last.fm web services, scrobbling support, proxy support and optional internal caching for some calls. It is a metadata and write client, not an audio player.
How do I install pylast?
Run python3 -m pip install pylast. The README also gives a development install from the repository with python3 -m pip install -U git+https://github.com/pylast/pylast, and a requirements.txt form using -e https://github.com/pylast/pylast.git#egg=pylast.
How do I authenticate to Last.fm from pylast without storing my password?
Use the session key flow. A SessionKeyGenerator produces a web authorization URL, the user approves it in a browser, and the script polls for the session key while catching pylast.WSError. The key is then written to a file in your home directory and reused on later runs.
Does pylast work with Libre.fm as well as Last.fm?
Yes, and the feature list names support for other API-compatible networks like Libre.fm. The Network object represents a social music network that is Last.fm or any other API-compatible one, so pointing it at a compatible service reuses the same object model and scrobble methods.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pylast-pylast)Was this useful?