Skip to main content

Python SDK for Rockbox — async GraphQL client with subscriptions and plugins

Project description

rockbox-sdk

PyPI Python Downloads License AsyncIO Typed Ruff mypy GitHub

Async Python SDK for Rockbox Zig — a typed, batteries-included client for the GraphQL API exposed by rockboxd.

import asyncio
from rockbox_sdk import RockboxClient, PlaybackStatus

async def main():
    async with RockboxClient(host="localhost") as client:
        track = await client.playback.current_track()
        if track:
            print(f"Now: {track.title}{track.artist}")
        if await client.playback.status() == PlaybackStatus.PAUSED:
            await client.playback.resume()

asyncio.run(main())

Highlights

  • Async-first — built on httpx + websockets. Use await everywhere.
  • Domain-namespaced APIclient.playback.*, client.library.*, client.sound.*, …
  • Typed responses — every reply is a Pydantic model with snake_case fields.
  • Real-time eventsconnect() opens a WebSocket and forwards track:changed / status:changed / playlist:changed to listeners.
  • Builder APIRockboxClient.builder().host(...).port(...).build().
  • Plugin system — Jellyfin-style install/uninstall lifecycle.
  • Python-friendly — context manager, decorator listeners, dataclass inputs.

Install

uv add rockbox-sdk
# or
pip install rockbox-sdk

Requires Python 3.10+ and a running rockboxd (default port 6062).

Try it in the REPL

The SDK is async-first. The recommended REPL is IPythonawait works at the top level, and you get tab-completion on models, inline docs with ?, and %timeit for benchmarking:

uv run ipython
In [1]: from rockbox_sdk import RockboxClient, PlaybackStatus
In [2]: client = RockboxClient(host="localhost", port=6062)
In [3]: await client.playback.status()
Out[3]: <PlaybackStatus.PLAYING: 1>
In [4]: track = await client.playback.current_track()
In [5]: track.title, track.artist
Out[5]: ('Money', 'Pink Floyd')
In [6]: await client.sound.get_volume()
Out[6]: VolumeInfo(volume=-12, min=-74, max=6)
In [7]: await client.library.search("daft punk")
In [8]: await client.aclose()

You can also test offline — models, enums, and the builder don't need a server:

In [1]: from rockbox_sdk import RockboxClient, Track, InsertPosition
In [2]: Track.model_validate({"title": "Money", "albumArt": "x.jpg"}).album_art
Out[2]: 'x.jpg'
In [3]: RockboxClient.builder().host("nas.local").build()._config.resolve_http_url()
Out[3]: 'http://nas.local:6062/graphql'

If you prefer the stdlib REPL, python -m asyncio also supports top-level await, or wrap each call in asyncio.run(...) in a plain python session:

uv run python -m asyncio
>>> from rockbox_sdk import RockboxClient
>>> client = RockboxClient()
>>> await client.playback.status()

Subscriptions (await client.connect()) keep firing in the background between prompts in both REPLs.

Configure

from rockbox_sdk import RockboxClient

# Direct kwargs
client = RockboxClient(host="192.168.1.42", port=6062)

# Or fluent builder
client = (
    RockboxClient.builder()
    .host("nas.local")
    .port(6062)
    .timeout(15)
    .build()
)

# Or full URL override
client = RockboxClient(
    http_url="http://nas.local:6062/graphql",
    ws_url="ws://nas.local:6062/graphql",
)

Always call await client.aclose() when you're done — or use it as an async context manager:

async with RockboxClient() as client:
    ...

Domains

Namespace What it does
client.playback Transport (play/pause/seek), play helpers
client.library Albums, artists, tracks, search, likes, scan
client.playlist The active queue (insert/remove/shuffle/start)
client.saved_playlists Persistent playlists & folders
client.smart_playlists Rule-based playlists & listening stats
client.sound Volume control
client.settings Global EQ / replaygain / crossfade / shuffle / …
client.system Version, runtime info
client.browse Filesystem & UPnP browser
client.devices Cast / source device discovery
client.bluetooth Bluetooth pairing & scanning (Linux only)

Real-time events

from rockbox_sdk import RockboxClient, TRACK_CHANGED, STATUS_CHANGED

async with RockboxClient() as client:
    await client.connect()  # opens the WebSocket

    @client.on(TRACK_CHANGED)
    async def on_track(track):
        print(f"▶ {track.title}{track.artist}")

    @client.on(STATUS_CHANGED)
    def on_status(raw_status):
        print(f"◐ status = {raw_status}")

    await asyncio.Event().wait()  # run forever

Convenience wrappers exist (client.on_track_changed(...), client.on_status_changed(...), client.on_playlist_changed(...)).

Plugins

A plugin is anything matching the RockboxPlugin protocol — a name, version, install(context), and optionally uninstall():

from rockbox_sdk import RockboxClient, PlaybackStatus, RockboxPlugin

class SleepTimer:
    name = "sleep-timer"
    version = "1.0.0"
    description = "Stop playback after N minutes"

    def __init__(self, minutes: int) -> None:
        self.minutes = minutes
        self._task: asyncio.Task | None = None

    def install(self, ctx):
        async def fire():
            await asyncio.sleep(self.minutes * 60)
            await ctx.query("mutation { hardStop }")

        self._task = asyncio.create_task(fire())

        @ctx.events.on("status:changed")
        def cancel_on_stop(status: int):
            if status == PlaybackStatus.STOPPED and self._task:
                self._task.cancel()

    def uninstall(self):
        if self._task:
            self._task.cancel()

async with RockboxClient() as client:
    await client.connect()
    await client.use(SleepTimer(30))

Raw GraphQL escape hatch

data = await client.query(
    "query Volume { volume { volume min max } }"
)

Examples

See examples/ for runnable scripts mirroring the TypeScript SDK examples:

  • 01-basic-playback.py
  • 02-now-playing.py
  • 03-library-search.py
  • 04-queue-management.py
  • 05-volume-control.py
  • 06-plugin-sleep-timer.py

Run with:

uv run python examples/01_basic_playback.py

License

MIT License. See LICENSE for details.

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

rockbox_sdk-0.1.0.tar.gz (20.6 kB view details)

Uploaded Source

Built Distribution

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

rockbox_sdk-0.1.0-py3-none-any.whl (29.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: rockbox_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 20.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","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

Hashes for rockbox_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c556cd54cc302f2e66b7a2b1ad3e684464aee1b2c3d7d4c8e2d2acbf1fe808ab
MD5 68c94ab9bb6671c8dfb5277d728b485a
BLAKE2b-256 ad92687288bc82d1e29f5b657aa5a52536c39bae92eff00e1e85192892e218cb

See more details on using hashes here.

File details

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

File metadata

  • Download URL: rockbox_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","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

Hashes for rockbox_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dcbd88f1f429187c76c9508a389deadfff5b86b2b98110e77ec0ec483078ccbf
MD5 37763b970e579ad0911f718bf738b6c6
BLAKE2b-256 e5efeed9d16d3a3d073fbca3f6adb0f3efc62ff00a68ad75f0fbb9a4e171316a

See more details on using hashes here.

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