Playwright host adapter for musickit-api-mock.
Project description
musickit-api-mock
Apple Music API mock for MusicKit JS. Runs as an in-process request interceptor inside browser-automation tests, so the page hits the mock instead of api.music.apple.com.
Useful for testing web apps that embed MusicKit JS without depending on Apple's servers, a developer token, or a signed-in Apple Music subscription.
Packages
This repository is a uv workspace with a thin core / adapter split:
musickit-api-mock— transport-agnostic mock engine. Routes HTTP requests, composes Apple Music API response bodies, and ships the in-page JS shim that replaces MusicKit JS's browser integrations.musickit-api-mock-playwright— Playwright host adapter. Bridges the engine topage.routefor both sync and async Playwright APIs.
Install
pip install musickit-api-mock-playwright
The Playwright adapter depends on the core package transitively. Install only the core package if you write your own host adapter for a different browser-automation framework.
Quick start
Sync Playwright
from musickit_api_mock import (
MusicKitApiMock,
Song,
Storefront,
StorefrontResponseSuccess,
)
from musickit_api_mock_playwright import intercept
from playwright.sync_api import sync_playwright
mock = MusicKitApiMock()
# Shared resource data: songs keyed by catalog id.
mock.data.songs = {
"1000000001": Song.from_file("tests/fixtures/silence.m4a"),
}
# Endpoint-level response: storefront resolution.
mock.endpoints.storefront = StorefrontResponseSuccess(
storefront=Storefront(
id="us",
name="United States",
default_language_tag="en-US",
supported_language_tags=["en-US"],
explicit_content_policy="allowed",
),
)
with sync_playwright() as pw:
browser = pw.chromium.launch()
page = browser.new_page()
intercept(mock, page)
page.goto("https://your-app.example/")
# ... drive MusicKit JS through your app and assert ...
browser.close()
Async Playwright
from musickit_api_mock_playwright import intercept_async
await intercept_async(mock, page)
intercept and intercept_async accept either a Page (binds to that single page) or a BrowserContext (covers every page in the context, including popups and pages opened later).
Surfaces
A MusicKitApiMock instance exposes three configuration surfaces. The split is load-bearing — each surface has a distinct semantic role:
mock.data.*— shared resource sources (songs, albums, playlists, artists, library items, ...). Read by multiple endpoints when composing responses. Each field accepts adict[str, T]keyed by id, or aCallable[[LookupContext], T]for dynamic resolution.mock.endpoints.*— per-endpoint response overrides (storefront, account, license, web playback, ...). Each field accepts a response value, a dict keyed by id, or a callable returning a response. Use these to shape the HTTP response itself (status, error variants, ...).mock.browser.*— state consumed by the in-page JS shim, e.g. the authorize response delivered when the page callsmusic.authorize(), and the EME key system flavor the shim should expose.
All fields default to None, which is the unset sentinel. Reading an unset field at request time raises ValueError — the mock does not invent fallback values for fields you didn't configure.
Scope
- Target audience: third-party developers using the default MusicKit JS configuration, i.e.
MusicKit.configure(...)without Apple-internal overrides. - Intercepted host:
api.music.apple.com. Apple's own web-player override hosts (e.g.amp-api.music.apple.com) are out of scope. - Intercepted paths: every path the default-config host emits within MusicKit JS's resource set (songs, albums, artists, library-, me/, ...). Within an intercepted path, every form the path can accept is handled — not just the subset MusicKit JS happens to send.
Supported environments
- Python ≥ 3.12
- Playwright (sync and async) on Chromium, Firefox, and WebKit
- Linux, macOS, Windows
License
CC0 1.0 Universal — public domain dedication.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file musickit_api_mock_playwright-0.0.1.tar.gz.
File metadata
- Download URL: musickit_api_mock_playwright-0.0.1.tar.gz
- Upload date:
- Size: 7.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73c69003d5075caec64ec59dd7b644243d3bb366414d4912e33428a3b937d882
|
|
| MD5 |
a4b271a56faf7a7dc7895fd1babd47bb
|
|
| BLAKE2b-256 |
a602d3fcf16bb8fa5f1c2a16506052a820d4eb544f5fd960c68a0ca37c4c4a8e
|
File details
Details for the file musickit_api_mock_playwright-0.0.1-py3-none-any.whl.
File metadata
- Download URL: musickit_api_mock_playwright-0.0.1-py3-none-any.whl
- Upload date:
- Size: 9.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2038fc84643b6962b960f08d9f48b725156e46adebc6ce61ea51f97cb8c0472
|
|
| MD5 |
dc94349db5aa1c8a3641c6cbbf6d19b7
|
|
| BLAKE2b-256 |
c88521d5ca0c4909a13511152bdba26c5a2cdc22bee4636dfde3bf654c015588
|