lastfm-export
Export your Last.fm listening history (scrobbles) and optionally enrich it with Spotify metadata.
Designed for both:
- CLI-first users who want “just get my data”, and
- Python users who want reusable clients and pipelines.
Features
- Export scrobbles from Last.fm with paging + retry/backoff.
- Optional Spotify enrichment (track metadata lookup).
- Streaming-friendly outputs (NDJSON recommended).
- Works with environment variables (no secrets in code).
Install
Using uv:
uv pip install lastfm-export
Or with .env support for local development:
uv pip install "lastfm-export[dotenv]"
Authentication
Last.fm
Set these environment variables:
export LASTFM_API_KEY="..."
export LASTFM_USERNAME="..."
Last.fm privacy setting: Exporting scrobbles requires your recent listening information to be available through the Last.fm API. Make sure “Hide recent listening information” is disabled in your Last.fm privacy settings. This setting controls whether your recent listening information is publicly visible.
Spotify (optional)
Set these environment variables:
export SPOTIFY_CLIENT_ID="..."
export SPOTIFY_CLIENT_SECRET="..."
If you installed lastfm-export[dotenv], you can also put these values in a local .env file.
Quickstart (CLI)
1) Export scrobbles
Recommended output format: NDJSON (one JSON object per line).
lastfm-export scrobbles export \
--out scrobbles.ndjson
Optional filters:
lastfm-export scrobbles export \
--out scrobbles.ndjson \
--from YYYY-MM-DD \
--to YYYY-MM-DD
You can also pass full datetimes:
lastfm-export scrobbles export \
--out scrobbles.ndjson \
--from YYYY-MM-DDTHH:MM:SS \
--to YYYY-MM-DDTHH:MM:SS
Resume (incremental export):
lastfm-export scrobbles export \
--out scrobbles.ndjson \
--resume auto
2) Enrich with Spotify
lastfm-export enrich spotify \
--in scrobbles.ndjson \
--out scrobbles_enriched.ndjson
Notes:
- Spotify enrichment is best-effort: some tracks may not match cleanly.
- Use NDJSON for large exports.
Quickstart (Python)
Export scrobbles
from lastfm_export.clients.lastfm import LastFMClient
from lastfm_export.pipelines.lastfm_export import export_scrobbles
lastfm = LastFMClient(
api_key="...",
username="...",
user_agent="lastfm-export",
)
for scrobble in export_scrobbles(lastfm=lastfm):
print(scrobble.to_record())
Enrich with Spotify
from lastfm_export.clients.spotify import SpotifyClient
from lastfm_export.pipelines.spotify_enrich import enrich_scrobbles_with_spotify
spotify = SpotifyClient(
client_id="...",
client_secret="...",
user_agent="lastfm-export",
)
enriched = enrich_scrobbles_with_spotify(spotify=spotify, scrobbles=export_scrobbles(lastfm=lastfm))
for row in enriched:
print(row.to_record())
Output formats
Supported formats depend on command:
- NDJSON: recommended for streaming and incremental runs.
- JSON array: convenient for small exports.
- CSV: convenient for spreadsheets.
Tip: For large histories, use NDJSON to avoid loading everything into memory.
Raw source payloads
Normalized output remains the default. To also preserve the per-track source payload, use --include-raw:
lastfm-export scrobbles export \
--out scrobbles.ndjson \
--include-raw
lastfm-export enrich spotify \
--in scrobbles.ndjson \
--out scrobbles_enriched.ndjson \
--include-raw
For Python usage, pass include_raw=True to to_record(). Last.fm payloads are stored in raw, while Spotify payloads are stored in spotify.raw. In CSV output, nested payloads are JSON-encoded in cells.
Raw payload shapes are controlled by the upstream APIs and may change independently of the normalized export schema.
Development
Clone the repo and set up the environment with uv:
uv venv
uv sync
Run checks:
uv run ruff check .
uv run pytest -q
Build:
uv build --no-sources
License
See LICENSE.
Metadata
Release files for lastfm-export 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| lastfm_export-0.2.0.tar.gz | 56.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lastfm_export-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 78.8 kB
Release files / lastfm_export-0.2.0.tar.gz
| Download URL | lastfm_export-0.2.0.tar.gz |
|---|---|
| Size | 56.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
075d2f383c47c5800e43874bfdb49a5291a7280126ebbc45f5f0e53879cfddec
|
|
BLAKE2b-256 checksum How to use checksums |
9ccb750066b210fe6cb7be40772537d3c8305d7da5a0bd74cac7151f83aeaa09
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / lastfm_export-0.2.0-py3-none-any.whl
| Download URL | lastfm_export-0.2.0-py3-none-any.whl |
|---|---|
| Size | 22.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2c9083c5a5c7a2aff37272390adbcd1dacc7cb92d0b6543522d5bbb467622abc
|
|
BLAKE2b-256 checksum How to use checksums |
46b342a5e16db5039d63c0b6f0d75d19d3f3ff7eb0b2e7e8e0d4132ec272ec30
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for lastfm-export 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.