Metadata-Version: 2.4
Name: playola
Version: 0.2.0
Summary: point playola at an article that lists albums, get back an importable playlist file
Project-URL: Homepage, https://github.com/sulrich/playola
Project-URL: Repository, https://github.com/sulrich/playola
Project-URL: Issues, https://github.com/sulrich/playola/issues
Author-email: Steve Ulrich <sulrich@botwerks.org>
License-Expression: MIT
License-File: LICENSE
Keywords: apple-music,claude,itunes,m3u,music,playlist
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Sound/Audio
Requires-Python: >=3.10
Requires-Dist: anthropic>=0.116
Requires-Dist: beautifulsoup4>=4.12
Requires-Dist: pyjwt[crypto]>=2.8
Requires-Dist: requests>=2.31
Requires-Dist: tomli>=2.0; python_version < '3.11'
Description-Content-Type: text/markdown

# playola

point it at an article that lists albums, get back a playlist file you can import
into your streaming service. claude reads the article and pulls out the
artist/album list, then each album is resolved to its real tracks and written to
a CSV + M3U you can import.

apple music ships first (resolved via the free, public itunes search API - no
apple developer account, no auth). the service layer is pluggable, so other
services can be added without touching the rest of the code.

if you have an apple developer account, playola can also create the playlist
**directly in your apple music library** - `--push` on a build, or `playola push`
on an existing `.m3u8`/`.csv` - so you can skip the converter entirely. see
[pushing straight into apple music](#pushing-straight-into-apple-music).

## install

install it as a standalone command with [uv](https://docs.astral.sh/uv/) (or
`pipx`, or plain `pip`):

```sh
uv tool install playola        # or: pipx install playola  /  pip install playola
```

then point it at an anthropic key. playola uses the standard anthropic sdk, so it
picks up whatever auth the sdk already sees - the simplest is an env var:

```sh
export ANTHROPIC_API_KEY=sk-ant-...
```

## usage

```sh
playola https://example.com/best-albums-article
```

it prompts for a playlist name (the article URL is stored in the playlist
description so you can always trace it back), then writes two files into the
output directory:

- `<name>.csv` - import via a converter such as [soundiiz](https://soundiiz.com)
  or [tunemymusic](https://www.tunemymusic.com) (both have free tiers), which
  push the playlist straight into apple music. columns are `Title, Artist, Album,
  Duration, ISRC, URL`.
- `<name>.m3u8` - an extended M3U with the apple music track URLs, importable by
  the macos music app and most players.

`build` flags (the default subcommand - `playola <url>` is short for `playola build <url>`):

| flag | default | meaning |
|------|---------|---------|
| `url` (positional) | prompted | the article URL |
| `--name` | prompted | playlist name |
| `--service` | `apple` | streaming service to resolve against |
| `--out-dir` | `.` | where to write the files |
| `--model` | `claude-opus-4-8` | claude model for extraction (or set `--model claude-sonnet-4-6` for a cheaper run) |
| `--push` | off | also create the playlist in your apple music library |
| `--config` / `--credentials` | see setup | override the apple music config / secrets file locations |

albums that can't be confidently matched are skipped and listed at the end so you
know what to add by hand.

## pushing straight into apple music

the CSV/M3U files above are portable and need zero setup, but importing them
still means a manual trip through a converter. with an apple developer account
playola can create the playlist directly in your library instead:

```sh
playola auth                              # one-time browser sign-in (see below)
playola <url> --name "My List" --push     # build, then push in one shot
playola push out/my-list.m3u8             # or push a file you already have
```

`push` reads the apple music catalog id that's already embedded in each track's
URL, so no re-resolution happens - it works on any `.m3u8`/`.csv` playola wrote
(even hand-edited). tracks without a catalog id are skipped and reported.

### one-time setup

1. in the [apple developer portal](https://developer.apple.com/account/resources/),
   create a **Media Identifier** and a **MusicKit key**, then download the key's
   `.p8` file. note your **Team ID** and the **Key ID**.
2. write two files (defaults under `~/.config/playola/`):

   `~/.config/playola/config.toml` - non-secret settings:

   ```toml
   credentials_path = "~/.config/playola/credentials.toml"
   storefront = "us"
   # token_path = "~/.config/playola/token.json"   # optional; this is the default
   ```

   `~/.config/playola/credentials.toml` - the secrets:

   ```toml
   team_id = "XXXXXXXXXX"
   key_id = "YYYYYYYYYY"
   private_key_path = "~/.config/playola/AuthKey_YYYYYYYYYY.p8"
   ```
3. run `playola auth` once. a browser opens; sign in with the apple id whose
   library you want to write to. the resulting **Music-User-Token** is cached
   (chmod 600) in `token.json` and reused.

the user token lasts about six months and can't be renewed; when a push returns
"401 ... run `playola auth` again", just re-run `playola auth`.

`--config` and `--credentials` override the file locations (flag > `config.toml`
pointer > default), so you can keep separate profiles or store secrets elsewhere.

## adding another streaming service

1. subclass `MusicService` (`playola/services/base.py`) and implement
   `resolve_album(ref) -> list[Track]`.
2. register it in `playola/services/__init__.py`.

that's the whole contract - extraction and rendering don't care which service
produced the tracks.

## from source

working on playola itself? clone the repo and let uv manage the environment - no
venv to set up by hand:

```sh
git clone https://github.com/sulrich/playola
cd playola
uv run playola https://example.com/best-albums-article    # run it
uv run pytest                                             # run the tests
```

the tests cover the pure logic (CSV/M3U rendering, album match scoring, track
ordering, HTML-to-text, response parsing). the network calls (claude, itunes) are
exercised by running the tool.
