API Reference

Main Classes

class pyblu.Player(host: str, port: int = 11000, session: ClientSession | None = None, default_timeout: float = 5.0)
__init__(host: str, port: int = 11000, session: ClientSession | None = None, default_timeout: float = 5.0)

Client for a BluOS player. Uses the HTTP API of the BluOS players to control it.

The passed sessions will not be closed when the player is closed and has to be closed by the caller. If no session is passed, a new session will be created and closed when the player is closed.

Player is an async context manager and can be used with async with.

Parameters:
  • host – The hostname or IP address of the player.

  • port – The port of the player. Default is 11000.

  • session – An optional aiohttp.ClientSession to use for requests.

  • default_timeout – The default timeout in seconds for requests. Can be overridden in each request.

Returns:

A new Player.

async add_follower(ip: str, port: int = 11000, timeout: float | None = None) → list[PairedPlayer]

Add a secondary player to the current player as a follower. If it fails the player won’t be in the returned list.

Parameters:
  • ip – The IP address of the player to add.

  • port – The port of the player to add. Default is 11000.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The list of followers of the player.

async add_followers(followers: list[PairedPlayer], timeout: float | None = None) → list[PairedPlayer]

Add a list of following players to the current player. If it fails the player won’t be in the returned list.

Same as add_follower but with a list of players. Makes only one request to player.

Parameters:
  • followers – The list of players to add.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The list of followers of the player.

async back(timeout: float | None = None) → None

Go back to the previous track.

Parameters:

timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
async browse(key: str | None = None, q: str | None = None, with_context_menu_items: bool = False, timeout: float | None = None) → BrowseResult

Browse media available on the player. Call without parameters to get the top-level menu. Call with key to descend, paginate, or navigate up.

key is an opaque value taken from a previous browse response: browse_key of a BrowseItem, or search_key / next_key / parent_key of a BrowseResult or BrowseCategory. Do not parse or modify it. Use context_menu rather than this method for a context_menu_key.

To search within a service or deeper browse context, pass q together with a key taken from the search_key of a previous BrowseResult. Pass q without key to perform a top-level search. Set with_context_menu_items to include each item’s context-menu actions in the response.

Playable items expose opaque play_action_url and optionally autoplay_action_url values. Invoke either value with execute_action.

Parameters:
  • key – The opaque key to browse. None returns the top-level menu.

  • q – The search term. Without key, performs a top-level search; with key, searches the context identified by a search_key.

  • with_context_menu_items – Include inline context-menu actions for returned items.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The browse result.

async clear(timeout: float | None = None) → PlayQueue

Clear the play queue.

Parameters:

timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The current play queue.

async context_menu(key: str, timeout: float | None = None) → list[ContextMenuAction]

Get the context-menu actions available for a browse item.

key is the opaque context_menu_key from a BrowseItem. Do not parse or modify it. Available actions are service-specific and can change.

Parameters:
  • key – The opaque context-menu key from a browse item.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The context-menu actions available for the item.

async delete_play_queue_track(track_id: int, timeout: float | None = None) → int

Delete a track from the current play queue.

Parameters:
  • track_id – The track id from PlayQueueTrack.id.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The id of the deleted track.

async execute_action(action_url: str, timeout: float | None = None) → None

Invoke an opaque action URI returned by the browse API.

Pass a BrowseItem.play_action_url, BrowseItem.autoplay_action_url, or ContextMenuAction.action_url to this method without parsing, decoding, or otherwise modifying it. Unlike play_url, this method does not construct a /Play request: the complete action URI is sent directly to the player. Actions can start playback, modify the play queue, add a preset, or change a service favorite.

Parameters:
  • action_url – An opaque relative action URI supplied by the player.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
async inputs(timeout: float | None = None) → list[Input]

List all available inputs.

Parameters:

timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The list of inputs of the player.

async load_preset(preset_id: int, timeout: float | None = None) → None

Load a preset by ID.

Parameters:
  • timeout – The timeout in seconds for the request. This overrides the default timeout.

  • preset_id – The ID of the preset to load.

Raises:
async move_play_queue_track(old_position: int, new_position: int, timeout: float | None = None) → None

Move a track within the current play queue.

Parameters:
  • old_position – The current track position from PlayQueueTrack.id.

  • new_position – The destination position.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
async pause(toggle: bool | None = None, timeout: float | None = None) → str

Pause the current track. toggle can be used to toggle between playing and pause.

Parameters:
  • toggle – Toggle between playing and pause.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The playback state after command execution.

async play(seek: int | None = None, timeout: float | None = None) → str

Start playing the current track. Can also be used to seek within the current track. Works only when paused, not when stopped.

Parameters:
  • seek – The position in seconds to seek to.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The playback state after command execution.

async play_queue(start: int | None = None, end: int | None = None, status_only: bool = False, timeout: float | None = None) → PlayQueue

Get the current play queue.

Use start and end to retrieve an inclusive page of tracks. Both positions start at 0 and must be supplied together. Use status_only to retrieve only queue metadata. Calling without pagination or status_only returns every track and may produce a large response.

Parameters:
  • start – The first track position to include, starting from 0.

  • end – The last track position to include, inclusive.

  • status_only – Return queue metadata without track details.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
  • PlayerUnexpectedResponseError – If the response is not as expected. This is probably a bug in the library.

  • PlayerUnreachableError – If the player is not reachable. Player is offline or request timed out.

  • ValueError – If only one pagination position is supplied, or pagination and status_only are combined.

Returns:

The current play queue and the requested tracks.

async play_url(url: str, timeout: float | None = None) → str

Start playing a track from a source URL. Can also be used to select inputs. See inputs for available inputs.

This method constructs a /Play request from a stream URL or BluOS source identifier. Do not pass it an action URI from the browse API; invoke BrowseItem.play_action_url, BrowseItem.autoplay_action_url, and ContextMenuAction.action_url values with execute_action instead.

Parameters:
  • url – The stream URL or BluOS source identifier to play.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The playback state after command execution.

async presets(timeout: float | None = None) → list[Preset]

Get the list of presets of the player.

Parameters:

timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The list of presets of the player.

async remove_follower(ip: str, port: int = 11000, timeout: float | None = None) → SyncStatus

Remove a following player from the group.

Parameters:
  • ip – The IP address of the player to remove.

  • port – The port of the player to remove. Default is 11000.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The SyncStatus of the player.

async remove_followers(followers: list[PairedPlayer], timeout: float | None = None) → SyncStatus

Remove a list of following players from the group.

Same as remove_follower but with a list of players. Makes only one request to player.

Parameters:
  • followers – The list of players to remove.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The SyncStatus of the player.

async save_play_queue(name: str, timeout: float | None = None) → int

Save the current play queue as a named BluOS playlist.

Parameters:
  • name – The name of the saved playlist.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The number of tracks saved.

async shuffle(shuffle: bool, timeout: float | None = None) → PlayQueue

Set shuffle on current play queue.

Parameters:
  • shuffle – Whether to shuffle the playlist.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The current play queue.

async skip(timeout: float | None = None) → None

Skip to the next track.

Parameters:

timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
async sleep_timer(timeout: float | None = None) → int

Set sleep timer. Time steps are 15, 30, 45, 60, 90 minutes. Each call goes to next step. Resets to 0 if called when 90 minutes are set.

Parameters:

timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The current sleep timer in minutes. 0 if no sleep timer is set.

async status(etag: str | None = None, poll_timeout: int = 30, timeout: float | None = None) → Status

Get the current status of the player.

This endpoint supports long polling. If etag is set, the server will wait until the status changes or the timeout is reached. etag has to be the last etag received from the server.

poll_timeout has to be smaller than timeout. The default_timeout and the default value for poll_timeout do not fulfill this requirement. This means that timeout has to be set when using long polling in most cases.

Parameters:
  • etag – The last etag received from the server. Triggers long polling if set.

  • poll_timeout – The timeout in seconds for long polling. Has to be smaller than timeout.

  • timeout – The timeout in seconds for the request. This overrides the default timeout. Has to be larger than poll_timeout.

Raises:
Returns:

The current status of the player. Only selected fields are returned.

async stop(timeout: float | None = None) → str

Stop the current track. Stopped playback cannot be resumed.

Parameters:

timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The playback state after command execution.

async sync_status(etag: str | None = None, poll_timeout: int = 30, timeout: float | None = None) → SyncStatus

Get the SyncStatus of the player.

This endpoint supports long polling. If etag is set, the server will wait until the status changes or the timeout is reached. etag has to be the last etag received from the server.

poll_timeout has to be smaller than timeout. The default_timeout and the default value for poll_timeout do not fulfill this requirement. This means that timeout has to be set when using long polling in most cases.

Parameters:
  • etag – The last etag received from the server. Triggers long polling if set.

  • poll_timeout – The timeout in seconds for long polling. Has to be smaller than timeout.

  • timeout – The timeout in seconds for the request. This overrides the default timeout. Has to be larger than poll_timeout.

Raises:
Returns:

The SyncStatus of the player.

async volume(level: int | None = None, mute: bool | None = None, tell_followers: bool | None = None, timeout: float | None = None) → Volume

Get or set the volume of the player. Call without parameters to get the current volume. Call with parameters to set the volume.

Parameters:
  • level – The volume level to set. Range is 0-100.

  • mute – Whether to mute the player.

  • tell_followers – Whether to tell grouped speakers to change their volume as well.

  • timeout – The timeout in seconds for the request. This overrides the default timeout.

Raises:
Returns:

The current volume of the player.

Audio Settings

Access these through player.settings; do not instantiate them directly. See pyblu.settings.Settings for shared timeout and availability semantics.

Important

listening_mode and subwoofer_mode are legacy exceptions: their get() methods return display labels, but set() requires raw names from values(). Do not round-trip their getters directly into setters. The newer replay_gain and output_mode use raw names for both get() and set(), and expose choices() instead of values(). See Playing sources and browse actions for the full legacy comparison and a save/restore example.

class pyblu.settings.Settings(get: _HttpGet)

Audio settings accessed through player.settings.

Each get(), choices(), range(), values(), or is_available() call fetches a fresh audio settings response. New choice settings return raw names from get() and expose choices(); numeric settings expose range(). ListeningMode and SubwooferMode retain display-name getters and values(). Availability means the player advertises the setting, not that it is currently enabled. Setters send one command and do not validate against advertised choices/ranges or read back the result.

All methods accept an optional timeout in seconds; None uses the player’s default. Transport failures raise PlayerUnreachableError; malformed setting responses raise PlayerUnexpectedResponseError.

class pyblu.settings.ListeningMode(get: _HttpGet)

Listening mode; accessed through player.settings.listening_mode.

Legacy API: get() returns a display label, but set() requires a raw name. Do not pass get() directly to set(); use the active values() entry’s name. Choices use values(), not choices(), and include an icon. Unlike newer choice settings, get() returns None for an unlisted active name, and is_available() requires at least one choice.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → str | None

Return the active display name, or None if absent or no choice matches.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(mode: str, timeout: float | None = None) → None

Set a raw choice name, not the display name returned by get().

Choices are not checked locally.

async values(timeout: float | None = None) → list[ListeningModeValue]

Return choices with raw names for set(), or an empty list if absent.

class pyblu.settings.SubwooferMode(get: _HttpGet)

Subwoofer mode; accessed through player.settings.subwoofer_mode.

Legacy API: get() returns a display label, but set() requires a raw name. Do not pass get() directly to set(); use the active values() entry’s name. Choices use values(), not choices(). Unlike newer choice settings, get() returns None for an unlisted active name, and is_available() requires at least one choice.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → str | None

Return the active display name, or None if absent or no choice matches.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(mode: str, timeout: float | None = None) → None

Set a raw choice name, not the display name returned by get().

Choices are not checked locally.

async values(timeout: float | None = None) → list[SubwooferModeValue]

Return choices with raw names for set(), or an empty list if absent.

class pyblu.settings.ToneControls(get: _HttpGet)

Tone controls; accessed through player.settings.tone_controls.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → bool | None

Return whether enabled, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(enabled: bool, timeout: float | None = None) → None

Enable or disable this setting.

Raises:

ValueError – If enabled is not a bool.

class pyblu.settings.Treble(get: _HttpGet)

Treble level in dB; accessed through player.settings.treble.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → float | None

Return the current numeric value, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async range(timeout: float | None = None) → SettingRange | None

Return advertised bounds, or None if absent; these are not enforced by set().

async set(value: float, timeout: float | None = None) → None

Set a finite numeric value.

Player-advertised bounds and step sizes are not checked locally.

Raises:

ValueError – If value is a bool or is not finite.

class pyblu.settings.Bass(get: _HttpGet)

Bass level in dB; accessed through player.settings.bass.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → float | None

Return the current numeric value, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async range(timeout: float | None = None) → SettingRange | None

Return advertised bounds, or None if absent; these are not enforced by set().

async set(value: float, timeout: float | None = None) → None

Set a finite numeric value.

Player-advertised bounds and step sizes are not checked locally.

Raises:

ValueError – If value is a bool or is not finite.

class pyblu.settings.Balance(get: _HttpGet)

Left/right balance; accessed through player.settings.balance.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → float | None

Return the current numeric value, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async range(timeout: float | None = None) → SettingRange | None

Return advertised bounds, or None if absent; these are not enforced by set().

async set(value: float, timeout: float | None = None) → None

Set a finite numeric value.

Player-advertised bounds and step sizes are not checked locally.

Raises:

ValueError – If value is a bool or is not finite.

class pyblu.settings.CentreChannel(get: _HttpGet)

Centre channel; accessed through player.settings.centre_channel.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → bool | None

Return whether enabled, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(enabled: bool, timeout: float | None = None) → None

Enable or disable this setting.

Raises:

ValueError – If enabled is not a bool.

class pyblu.settings.CentreVolumeTrim(get: _HttpGet)

Centre-channel volume trim; accessed through player.settings.centre_volume_trim.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → float | None

Return the current numeric value, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async range(timeout: float | None = None) → SettingRange | None

Return advertised bounds, or None if absent; these are not enforced by set().

async set(value: float, timeout: float | None = None) → None

Set a finite numeric value.

Player-advertised bounds and step sizes are not checked locally.

Raises:

ValueError – If value is a bool or is not finite.

class pyblu.settings.Crossover(get: _HttpGet)

Subwoofer crossover frequency in Hz; accessed through player.settings.crossover.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → float | None

Return the current numeric value, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async range(timeout: float | None = None) → SettingRange | None

Return advertised bounds, or None if absent; these are not enforced by set().

async set(value: float, timeout: float | None = None) → None

Set a finite numeric value.

Player-advertised bounds and step sizes are not checked locally.

Raises:

ValueError – If value is a bool or is not finite.

class pyblu.settings.ReplayGain(get: _HttpGet)

Replay-gain mode; accessed through player.settings.replay_gain.

See Settings for request and availability semantics.

async choices(timeout: float | None = None) → list[SettingValue]

Return choices with raw names for set(), or an empty list if absent.

async get(timeout: float | None = None) → str | None

Return the raw active name, even if unlisted, or None if absent.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(mode: str, timeout: float | None = None) → None

Set a raw choice name, as returned by get().

Choices are not checked locally.

class pyblu.settings.OutputMode(get: _HttpGet)

Output channel mode; accessed through player.settings.output_mode.

See Settings for request and availability semantics.

async choices(timeout: float | None = None) → list[SettingValue]

Return choices with raw names for set(), or an empty list if absent.

async get(timeout: float | None = None) → str | None

Return the raw active name, even if unlisted, or None if absent.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(mode: str, timeout: float | None = None) → None

Set a raw choice name, as returned by get().

Choices are not checked locally.

class pyblu.settings.StereoSurround(get: _HttpGet)

Stereo surround; accessed through player.settings.stereo_surround.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → bool | None

Return whether enabled, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(enabled: bool, timeout: float | None = None) → None

Enable or disable this setting.

Raises:

ValueError – If enabled is not a bool.

class pyblu.settings.DigitalPassthrough(get: _HttpGet)

Digital passthrough; accessed through player.settings.digital_passthrough.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → bool | None

Return whether enabled, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(enabled: bool, timeout: float | None = None) → None

Enable or disable this setting.

Raises:

ValueError – If enabled is not a bool.

class pyblu.settings.FixedVolume(get: _HttpGet)

Fixed output level; accessed through player.settings.fixed_volume.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → bool | None

Return whether enabled, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(enabled: bool, timeout: float | None = None) → None

Enable or disable this setting.

Raises:

ValueError – If enabled is not a bool.

class pyblu.settings.VolumeLimits(get: _HttpGet)

Volume limits in dB; accessed through player.settings.volume_limits.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → tuple[float, float] | None

Return (minimum, maximum) in dB, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async range(timeout: float | None = None) → SettingRange | None

Return advertised bounds, or None if absent; these are not enforced by set().

async set(minimum: float, maximum: float, timeout: float | None = None) → None

Set volume limits in dB.

Player-advertised bounds and minimum span are not checked locally.

Raises:

ValueError – If limits are bools, non-finite, or not ascending.

class pyblu.settings.AudioClockTrim(get: _HttpGet)

Audio clock trim; accessed through player.settings.audio_clock_trim.

See Settings for request and availability semantics.

async get(timeout: float | None = None) → bool | None

Return whether enabled, or None if absent from the player.

async is_available(timeout: float | None = None) → bool

Return whether the player advertises this setting.

async set(enabled: bool, timeout: float | None = None) → None

Enable or disable this setting.

Raises:

ValueError – If enabled is not a bool.

Data Classes

class pyblu.SettingValue(name: str, display_name: str, active: bool)

A selectable setting value; pass name (not display_name) to set().

class pyblu.SettingRange(minimum: float, maximum: float, step: float | None = None, units: str | None = None, minimum_range: float | None = None)

Player-advertised limits for a range or dual-range setting.

class pyblu.ListeningModeValue(name: str, display_name: str, icon: str, active: bool)
active: bool

If the mode is currently selected

display_name: str

Formatted name of the current listening mode

icon: str

URL of the mode icon

name: str

Name of the current listening mode

class pyblu.SubwooferModeValue(name: str, display_name: str, active: bool)
active: bool

If the mode is currently selected

display_name: str

Formatted name of the current listening mode

name: str

Name of the current listening mode

class pyblu.Status(etag: str, input_id: str | None, service: str | None, state: str, shuffle: bool, album: str | None, artist: str | None, name: str | None, image: str | None, volume: int, volume_db: float, mute: bool, mute_volume: int | None, mute_volume_db: float | None, seconds: float | None, total_seconds: float | None, can_seek: bool, sleep: int, group_name: str | None, group_volume: int | None, indexing: bool, stream_url: str | None)
album: str | None

Album name

artist: str | None

Artist name

can_seek: bool

True if the current track can be seeked

etag: str

Cursor for long polling requests. Can be passed to next status call.

group_name: str | None

Name of the group the player is in. Only present on leader.

group_volume: int | None

Volume level of the group. Only present on leader. Range is 0-100.

image: str | None

URL of the album art

indexing: bool

True if the player is currently indexing.

input_id: str | None

Unique id of the input. Is not set for radio.

mute: bool

Mute status

mute_volume: int | None

If the player is muted, then this is the unmuted volume level. Absent if the player is not muted.

mute_volume_db: float | None

If the player is muted, then this is the unmuted volume level in dB. Absent if the player is not muted.

name: str | None

Track name

seconds: float | None

Current playback position in seconds

service: str | None

Service id of current input. ‘Capture’ for regular inputs.

shuffle: bool

Shuffle enabled

sleep: int

Sleep timer in minutes. 0 means the sleep timer is off.

state: str

Playback state

stream_url: str | None

The presence of this element should be treated as a flag and its contents as an opaque value. Seems to be present for radio stations and to be the same as the url from the matching preset(for Radio Stations).

total_seconds: float | None

Total track length in seconds

volume: int

Volume level with a range of 0-100

volume_db: float

Volume level in dB

class pyblu.Volume(volume: int, db: float, mute: bool)
db: float

Volume level in dB

mute: bool

Mute status

volume: int

Volume level with a range of 0-100

class pyblu.SyncStatus(etag: str, id: str, mac: str, name: str, image: str, initialized: bool, group: str | None, leader: pyblu.entities.PairedPlayer | None, followers: list[pyblu.entities.PairedPlayer] | None, zone: str | None, zone_leader: bool | None, zone_follower: bool | None, brand: str, model: str, model_name: str, mute_volume_db: float | None, mute_volume: int | None, volume_db: float, volume: int)
brand: str

Brand name of the player

etag: str

Cursor for long polling requests. Can be passed to next sync_status call.

followers: list[PairedPlayer] | None

List of following players. Only present if the player is leader of a group

group: str | None

Group name of the player

id: str

Player IP and port

image: str

URL of the player image

initialized: bool

True means the player is already setup, false means the player needs to be setup

leader: PairedPlayer | None

Player leading the group. Only present if the player is grouped and not leader itself

mac: str

MAC address of the player

model: str

Model name of the player

model_name: str

Model name of the player

mute_volume: int | None

If the player is muted, then this is the unmuted volume level. Absent if the player is not muted.

mute_volume_db: float | None

If the player is muted, then this is the unmuted volume level in dB. Absent if the player is not muted.

name: str

Name of the player

volume: int

Volume level with a range of 0-100. -1 means fixed volume.

volume_db: float

Volume level in dB

zone: str | None

Name of the zone the player is in. Zones are fixed groups.

zone_follower: bool | None

True if the player is a follower in the zone, false otherwise

zone_leader: bool | None

True if the player is the leader of the zone, false otherwise

class pyblu.PairedPlayer(ip: str, port: int)
ip: str

IP address of the player

port: int

Port of the player

class pyblu.Preset(name: str, id: int, url: str, image: str | None, volume: int | None)
id: int

Unique id of the preset

image: str | None

URL of the preset image

name: str

Name of the preset

url: str

URL of the preset. Can be used with play_url to play the preset

volume: int | None

Volume level with a range of 0-100. None means the volume is not set.

class pyblu.PlayQueue(id: str, shuffle: bool | None, modified: bool | None, length: int, name: str | None = None, repeat: int | None = None, tracks: list[pyblu.entities.PlayQueueTrack] = <factory>)
id: str

Unique id for the current play queue state. Changes whenever the play queue changes.

length: int

Total number of tracks in the play queue, including tracks not returned by a paginated request.

modified: bool | None

Whether the play queue was modified since it was loaded, or None if the response does not include this state.

name: str | None = None

Name of the current play queue.

repeat: int | None = None

Repeat mode: 0 repeats the queue, 1 repeats the current track, and 2 disables repeat.

shuffle: bool | None

Whether the play queue is shuffled, or None if the response does not include the shuffle state.

tracks: list[PlayQueueTrack]

Tracks returned by the request. Empty for a status-only request or an empty queue.

class pyblu.PlayQueueTrack(id: int, title: str | None = None, artist: str | None = None, album: str | None = None, filename: str | None = None, image: str | None = None, duration: float | None = None, service: str | None = None, song_id: str | None = None, album_id: str | None = None, artist_id: str | None = None)
album: str | None = None

Album name.

album_id: str | None = None

Service-specific album id.

artist: str | None = None

Artist name.

artist_id: str | None = None

Service-specific artist id.

duration: float | None = None

Track duration in seconds.

filename: str | None = None

Service-specific filename. Treat this as an opaque value.

id: int

Position of the track in the play queue, starting from 0.

image: str | None = None

URL of the track artwork.

service: str | None = None

Music service that supplied the track.

song_id: str | None = None

Service-specific song id.

title: str | None = None

Track title.

class pyblu.Input(id: str | None, text: str | None, image: str, url: str)
id: str | None

Unique id of the input

image: str

URL of the input image

text: str | None

User friendly name of the input

url: str

URL to play the input. Can be passed to play_url

class pyblu.BrowseResult(type: str, service_name: str | None, service_icon: str | None, search_key: str | None, next_key: str | None, parent_key: str | None, items: list[pyblu.entities.BrowseItem], categories: list[pyblu.entities.BrowseCategory])
categories: list[BrowseCategory]

Categories. Empty unless the response groups items under headings.

items: list[BrowseItem]

Top-level items. Empty when the response is grouped into categories.

next_key: str | None

Opaque key for the next page of results. Pass to Player.browse.

parent_key: str | None

Opaque key for navigating up the hierarchy. Pass to Player.browse.

search_key: str | None

Opaque key for searching the current service. Pass to Player.browse together with the q parameter (the search term). None if search is not available here.

service_icon: str | None

URL of an icon for the service.

service_name: str | None

Human-readable service name, suitable for UI.

type: str

Result list type. Common values are “menu”, “items”, “albums”, “tracks”, “playlists”, “sections”, “folders”.

class pyblu.BrowseItem(type: str, text: str | None, text2: str | None, image: str | None, play_action_url: str | None, browse_key: str | None, input_type: str | None, context_menu_key: str | None, context_menu: list[pyblu.entities.ContextMenuAction], autoplay_action_url: str | None = None, duration: int | None = None, is_favourite: bool | None = None, tracks: int | None = None)
autoplay_action_url: str | None = None

Opaque relative URI from the item’s autoplayURL attribute. Pass it unchanged to Player.execute_action. None if the item does not provide an auto-fill play action. Do not pass this value to Player.play_url.

browse_key: str | None

Opaque key. Pass to Player.browse to descend into this item. None if the item is a leaf.

context_menu: list[ContextMenuAction]

Inline context-menu actions. Usually empty because BluOS normally supplies context_menu_key instead.

context_menu_key: str | None

Opaque key for this item’s context menu. Pass it to Player.context_menu.

duration: int | None = None

Duration in seconds for a track or collection.

image: str | None

Icon or artwork URL.

input_type: str | None

Input kind for items that represent a physical input (e.g. “bluetooth”, “arc”, “spdif”). Usually only set on the root menu.

is_favourite: bool | None = None

Whether the item is a favourite.

play_action_url: str | None

Opaque relative URI from the item’s playURL attribute. Pass it unchanged to Player.execute_action. None if the item does not provide a default play action. Do not pass this value to Player.play_url.

text: str | None

Primary display label.

text2: str | None

Secondary display label from the BluOS text2 attribute. The meaning is service-specific: it may be an artist, station slogan, current show, date, or another subtitle.

tracks: int | None = None

Number of tracks in a collection.

type: str

Item type. Common values are “link” (descend with browse_key), “audio” (playable), “album”, “track”, “artist”, “playlist”, “folder”, “section”, “text”. The list is open — treat unknown values as a display hint only.

class pyblu.BrowseCategory(text: str | None, next_key: str | None, parent_key: str | None, items: list[pyblu.entities.BrowseItem])
items: list[BrowseItem]

Items in this category.

next_key: str | None

Opaque key for the next page of items in this category. Pass to Player.browse.

parent_key: str | None

Opaque key for navigating up from this category. Pass to Player.browse.

text: str | None

Category heading.

class pyblu.ContextMenuAction(type: str, text: str | None, action_url: str)
action_url: str

Opaque relative action URI. Pass it unchanged to Player.execute_action.

text: str | None

Human-readable action label.

type: str

Service-specific action type. Treat unknown values as a display hint only.

Exceptions

class pyblu.errors.PlayerError(message: str)

Base class for exceptions in this package.

class pyblu.errors.PlayerUnreachableError(message: str)

Exception raised when the player is not reachable.

This could be due to a timeout or the player being offline.

class pyblu.errors.PlayerUnexpectedResponseError(message: str)

Exception raised when the player returns an unexpected response. This is likely a bug in this library.

class pyblu.errors.PlayerCommandError(message: str)

Exception raised when the player intentionally rejects a command.

class pyblu.errors.PlayerBrowseError(message: str, details: list[str] | None = None)

Exception raised when the /Browse endpoint returns a structured <error> response.

Unlike PlayerUnexpectedResponseError this is an error the player intentionally reported (e.g. invalid key, service unavailable) rather than a parsing failure.