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
Verified mode is the default. It gets one UTC day at a time and checks for
problems in Last.fm's response. Use it for exports you want to keep.
If a check finds a problem, it stops by default. --integrity-policy warn
continues and marks the export with warnings. A detailed integrity report is
saved by default for failures and warning exports. Use --integrity-report always to
also save one for clean exports, or --integrity-report never to suppress
reports for successful exports.
For quick exploration or a small sample, you can explicitly choose the faster, unverified sequential paginator:
lastfm-export scrobbles export \
--out sample.ndjson \
--acquisition-mode fast \
--page-limit 10
Fast mode uses Last.fm's normal page-by-page export. It is useful for quick
checks or samples, but Last.fm can repeat or miss tracks. The export warns you
but does not create a report by default. Use --integrity-report always to
save an "unverified" report. Do not use it for backups or a full history
export. It does not accept --integrity-policy.
Long-running commands show compact progress in a normal terminal. Use
--progress off to hide it, or --progress on to keep it when running in a
script or redirected terminal. Verified exports show a live status and one
saved progress line for each completed quarter.
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.3.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.3.0.tar.gz | 64.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lastfm_export-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 93.4 kB
Release files / lastfm_export-0.3.0.tar.gz
| Download URL | lastfm_export-0.3.0.tar.gz |
|---|---|
| Size | 64.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2c496abba185d2ed8139f16b2c96fcba729429a817d05c931540b37f63de4d36
|
|
BLAKE2b-256 checksum How to use checksums |
83e874cf95d94844686a6c36fd47db4f4facb27b2751013afe922f1d2f5269ba
|
| 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.3.0-py3-none-any.whl
| Download URL | lastfm_export-0.3.0-py3-none-any.whl |
|---|---|
| Size | 28.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d33b912d1f652a2ad0d3c84125e205b6b62eef1c820ac65e0f16c136b4601477
|
|
BLAKE2b-256 checksum How to use checksums |
563359b3a0a4cf688decca881d6527850165875700278fcc20a1230cef5413f8
|
| 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.3.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.