Skip to main content

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 to page.route for 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 a dict[str, T] keyed by id, or a Callable[[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 calls music.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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

musickit_api_mock_playwright-0.1.0.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

musickit_api_mock_playwright-0.1.0-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file musickit_api_mock_playwright-0.1.0.tar.gz.

File metadata

File hashes

Hashes for musickit_api_mock_playwright-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2c42ea79bf9603f843913dda0900fcaf820693c0d8c97953b2a7bab57728416d
MD5 be2031e7ca429f440405c28287653c68
BLAKE2b-256 ca35192b6f0da801d83e123becf3a36d87a9b4e01c5527c0bd3ce84dd1d9500f

See more details on using hashes here.

Provenance

The following attestation bundles were made for musickit_api_mock_playwright-0.1.0.tar.gz:

Publisher: release.yml on HotariTobu/musickit-api-mock

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file musickit_api_mock_playwright-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for musickit_api_mock_playwright-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cd40b59362ff7c88822644d3a43ceefc7ff4f09fe6bc4f30e611ccf1f85a1614
MD5 884fd9ba096e9a9e47a04f26eb06d372
BLAKE2b-256 a5037e97833eb7185b5d5fe79a56b352f56525b0a45722fd53bc76abc98d562e

See more details on using hashes here.

Provenance

The following attestation bundles were made for musickit_api_mock_playwright-0.1.0-py3-none-any.whl:

Publisher: release.yml on HotariTobu/musickit-api-mock

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page