- Python 100%
|
|
||
|---|---|---|
| pastetidal | ||
| tests | ||
| .env.example | ||
| .gitignore | ||
| mise.toml | ||
| notebook.py | ||
| pyproject.toml | ||
| README.md | ||
| renovate.json5 | ||
| uv.lock | ||
paste-to-tidal
Minimal Marimo web app: paste rich text containing music titles + artists, sign into Tidal, and create (or append to) a playlist in your account with the matched tracks.
Setup
1. Register a Tidal application
Go to https://developer.tidal.com/, login/create an account, and register a new application. You need:
- A Client ID and a Client Secret (both are required by
load_config). - A registered Redirect URI. This must match the URI the app uses for the
OAuth callback. Use a fixed local port like
http://127.0.0.1:8765/callback.
Required scopes: playlists.read, playlists.write, search.read, user.read
(see DEFAULT_SCOPES in pastetidal/tidal/auth.py).
2. Configure environment
Copy .env.example to .env and fill in:
TIDAL_CLIENT_ID=...
TIDAL_CLIENT_SECRET=...
TIDAL_REDIRECT_URI=http://127.0.0.1:8765/callback
The notebook also writes the OAuth token back into .env after sign-in
(TIDAL_ACCESS_TOKEN, TIDAL_REFRESH_TOKEN, TIDAL_TOKEN_EXPIRES_AT,
TIDAL_USER_ID, TIDAL_TOKEN_SCOPE) so the session survives restarts.
3. Run / Install
UV / UVX
If you do not want to clone the whole repo use uv/uvx:
uvx --from git+https://repo-url/... paste-to-tidal
"Full" installation
Clone repository first, then install dependencies etc.:
# if you use mise, which installs python and creates a .venv
mise install # python 3.14 + tools (or use your own python)
# if you use uv
uv venv
source .venv/bin/activate
# install required packages
uv sync
Run
uv run paste-to-tidal
This launches the Marimo notebook in your browser.
How to use
- Click Read clipboard (rich text). The browser-side widget reads
text/htmlandtext/plainfrom your clipboard and shows a preview. - Paste an example Artist element and Title element (e.g.
<span class="artist">,<a class="track-title">) so the parser knows which tags to extract from the HTML. These values are persisted in the page's query parameters. - Review/edit the parsed track list in the editable table.
- Click Sign in to Tidal. A browser window opens for OAuth consent; the app captures the callback automatically. If the local callback server times out, paste the callback URL into the manual fallback field.
- Tracks are searched against Tidal automatically; results are cached in
songs_cache.jsonso re-runs don't repeat API calls. Use Clear cached song matches to invalidate. - Choose Create new playlist or Append to existing playlist. For
append mode, Load my playlists fetches and caches them in
playlists_cache.json; type in the name field to filter, then select a row. - Click the create/append button to push matched tracks to Tidal.
Enable Debugging output at the top to inspect the clipboard widget state and full per-track search payloads.
Tests
uv run pytest -q
uv run ruff check pastetidal/ tests/ notebook.py
Architecture
pastetidal/parser.py— HTML / plain-text →[TrackQuery(title, artist, raw)]pastetidal/tidal/auth.py— OAuth 2.0 Authorization Code + PKCE, local callback server, token refreshpastetidal/tidal/client.py— Tidal v2 REST client (search, get_me, list / create playlist, add items) with 429 / 5xx backoff and JSON:API media typespastetidal/config.py— env-var loading viapython-dotenvnotebook.py— Marimo UI: clipboard → parse → confirm → auth → match → create/append, with on-disk caching of token, song matches, and playlistspastetidal/cli.py—paste-to-tidalentry-point that launches Marimo
Notes
- Auth: PKCE flow against
https://login.tidal.com/authorizeandhttps://auth.tidal.com/v1/oauth2/token. - API base:
https://openapi.tidal.com/v2/. - Single-user, runs locally only. Tokens and caches are written to the project
directory (
.env,songs_cache.json,playlists_cache.json).