# gamdl's pip package is half Rust, and its config file appears on first run

> gamdl is a command-line downloader for Apple Music songs, music videos and post videos, published on PyPI and built with maturin so that a PyO3 extension compiled from a Cargo manifest travels inside the wheel. The Python side owns the interface and the tagging; a native module owns the media work.

**glomatico/gamdl** — A command-line app for downloading Apple Music songs, music videos and post videos.

- Repository: https://github.com/glomatico/gamdl
- Stars: 2,666 · Forks: 263
- Language: Python
- License: MIT
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/glomatico-gamdl

## The wheel carries a PyO3 module compiled from a Cargo manifest

The build backend is maturin rather than setuptools, and the configuration says exactly what gets compiled. The manifest path points at a Cargo.toml inside the package, at gamdl/downloader/ammuxer, the resulting module is named gamdl._ammuxer with a leading underscore that marks it private, and the extension is built with the pyo3 extension-module feature so it links as a Python extension instead of a standalone binary. Target directories are excluded from the wheel and the licence file is included. There is no pure Python path to this tool: installing it means installing something that was cross-compiled. The split of labour is stated plainly. The native engine handles the wrapper TCP decrypt and reassembly plus MP4 and M4A writing and muxing, while Python keeps the command line interface, the downloads, the metadata tagging and the high-level orchestration.

## Fourteen runtime dependencies, two of them licence clients

The dependency list is short enough to read as an outline of what the tool does. Two entries, pywidevine and pyplayready, are the licence clients, which is what makes the decryption path possible. The default download engine is yt-dlp, pinned to a dated release. The command line itself is click, paired with dataclass-click, which builds the option set from dataclasses rather than from a hand-written parser, and colour handling comes from colorama. The interactive selection prompt is inquirerpy. Networking is httpx with httpx-retries for backoff and async-lru for caching. Playlist parsing is m3u8, tagging is mutagen, pillow is there for images, and structlog covers logging. So the shape is: a click front end, an async HTTP client, a tagging library, and two DRM libraries.

## Config values are overridden by flags, and the file writes itself

Configuration can come from a file or from the command line, and the precedence is stated without ambiguity: command-line arguments override config values. The file lives at ~/.gamdl/config.ini on Linux and under %USERPROFILE% on Windows, and it is created automatically on first run, so there is no setup step and no example file to copy. Two options control the mechanism itself. One moves the file to another path, and the other, with the short form -n, skips config files entirely for a run. The general options are the ones worth knowing: -r reads URLs from text files instead of taking them as arguments, --log-level defaults to INFO and --log-file redirects the log, --no-exceptions suppresses printed tracebacks, --artist-auto-select takes the selection for you on artist URLs, and --database-path points at a SQLite file where downloaded media is registered.

## The wrapper is a separate server reached on two ports

One optional dependency is a whole server: Wrapper v2, run from its own repository, which handles account, playback and decryption requests. It is switched on with a flag or the matching config key, and it is addressed differently depending on the kind of call. Account and playback go over HTTP JSON, pointed at by --wrapper-url with a default of http://127.0.0.1, while decryption uses a batch TCP channel configured by a host and a port pair, defaulting to localhost, with newer wrapper-v2 builds listening on port 10020 for that side. If you have not logged in yet, the wrapper asks you to insert your credentials. The documentation recommends it for the alac song codec and says alac can be attempted without it but probably will not work because of API limitations; other codecs do not require it, and cookies can be skipped entirely when it is in use.

## Wrapper playback fills in the sort fields and gapless flag

There is a second reason to run the wrapper beyond the codec, and it is metadata. For music videos, wrapper playback can return fields that are otherwise missing when Apple supplies them: sort title under the sonm key, sort artist under soar, sort album under soal, composer under the composer tag, a composer identifier under cmID, composer sort under soco, comments under the comment tag, a gapless flag under pgap, and an XID under xid. Those are the fields a tagger needs to write a correctly ordered library rather than an alphabetically shuffled one. So the wrapper is not only a decryption helper in this project, it is also a metadata source, and turning it off costs you both. The same mechanism is what lets cookies be skipped, since the wrapper is authenticating on its own.

## Two download engines, and two executables to locate by hand

The default download mode is yt-dlp, and there is a faster alternative: N_m3u8DL-RE, taken from its own releases page. Switching is a single setting, --download-mode nm3u8dlre, or download_mode set to the same value in the config file. That executable is not assumed to be on your PATH, so its location can be set with --nm3u8dlre-path, and the same applies to FFmpeg, which the tool also needs in that mode and which can be pointed at with --ffmpeg-path. In other words the tool assumes two external binaries exist on the system for the faster mode, and the flags exist for the cases where they are somewhere else. The command itself takes options followed by URLs:

```bash
gamdl [OPTIONS] URLS...
```

## Seven kinds of URL and four keys in the selection prompt

The argument is an Apple Music URL, and the tool recognises seven shapes of it: songs, albums, playlists and music videos, each marked as available in either the catalog or your library, plus artist pages, post videos, and Apple Music Classical. Where more than one item matches, an interactive prompt appears, and it is driven by four keys: arrow keys move the selection, space toggles the current entry, Ctrl+A selects everything, and Enter confirms. Two options exist to skip or feed that prompt. --artist-auto-select takes the choice for you on an artist URL, and -r, also spelled --read-urls-as-txt, reads the URLs from text files instead of the command line, which is the shape you want for a list. Installation is a single command, with the cookies file placed in the working directory or pointed at explicitly:

```bash
pip install gamdl
```

## Prerequisites are a subscription, a cookies file and Python 3.10

Three requirements are listed as mandatory. Python 3.10 or higher, an active Apple Music subscription, and a cookies file exported from your browser in Netscape format while logged in to Apple Music. The export step is given per browser: a Firefox extension called Export Cookies, and a Chromium extension called Get cookies.txt LOCALLY, which is named that way to be explicit that the cookies are read on your own machine. The file goes in the working directory as cookies.txt, or the path is set with --cookies-path, short form -c. There is also a Discord server linked from the readme for support. The repository itself is small at the top level: a package directory, the manifest, a lock file, a .python-version file and a licence. Recent releases are 3.8.5 in August 2026, 3.9 on 21 September and 3.9.1 the day after.

## Conclusion

gamdl fits someone with their own Apple Music subscription who wants song, album, playlist, artist, video and post video URLs handled by one tool with tagging applied, and who is willing to keep a local wrapper server running when the alac codec is in play. Three things to check first. Decide whether you need the wrapper before anything else, because it is a separate server on two ports and the documentation says the alac codec probably will not work without it. Read the wrapper metadata notes, since sort fields, composer credits and gapless flags only arrive when wrapper playback supplies them. And expect a native build: there is no pure Python install of this tool, so a toolchain is needed to build from source. Before using it for anything beyond your own playback, check the terms that apply to your subscription and to downloaded media. What this project is not is a library: the entry point is a console script, and the only public surface is the command.

## FAQ

### How do I use gamdl?

Install it with pip install gamdl, put an exported Netscape cookies.txt in the working directory or point at it with --cookies-path, then pass Apple Music URLs to the command in the form gamdl [OPTIONS] URLS.... It handles songs, albums, playlists, music videos, artist pages, post videos and Apple Music Classical URLs.

### What does gamdl need before it will run?

Python 3.10 or higher, an active Apple Music subscription, and a cookies file exported from your browser in Netscape format while logged in. Optional pieces are the Wrapper v2 server, recommended for the alac codec, and N_m3u8DL-RE with FFmpeg as a faster download mode.

### Why does installing gamdl need a Rust toolchain?

The build backend is maturin, and the configuration compiles a Cargo manifest from gamdl/downloader/ammuxer into a private PyO3 module named gamdl._ammuxer. That native engine handles the wrapper TCP decrypt and reassembly plus MP4 and M4A writing and muxing, so there is no pure Python install.

### Where is the gamdl config file and which options override it?

It is at ~/.gamdl/config.ini on Linux and under %USERPROFILE% on Windows, created automatically on first run. Command-line arguments override config values, --config-path moves the file and --no-config-file, short form -n, skips it entirely for a run.

### Can you download Apple Music without a subscription?

The prerequisites require an active Apple Music subscription, and authentication comes either from a cookies file exported from a logged-in browser or from credentials entered into the wrapper server on first use. Cookies can be skipped when the wrapper is running.

## Sources

- [glomatico/gamdl on GitHub](https://github.com/glomatico/gamdl)
- [Issues](https://github.com/glomatico/gamdl/issues)
- [License: MIT](https://github.com/glomatico/gamdl/blob/main/LICENSE)
- [README](https://github.com/glomatico/gamdl/blob/main/README.md)
- [Releases](https://github.com/glomatico/gamdl/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/glomatico-gamdl
