Core API¶
This page defines the public top-level exports from sonolink.
Client¶
- class sonolink.Client(client: DpyClientProto, *, node_cls: type[N] = ..., framework: Literal['discord.py'] = ...)[source]¶
- class sonolink.Client(client: PycordClientProto, *, node_cls: type[N] = ..., framework: Literal['pycord'] = ...)
- class sonolink.Client(client: DisnakeClientProto, *, node_cls: type[N] = ..., framework: Literal['disnake'] = ...)
- class sonolink.Client(client: NextcordClientProto, *, node_cls: type[N] = ..., framework: Literal['nextcord'] = ...)
- class sonolink.Client(client: Any, *, node_cls: type[N] = ..., framework: None = ...)
- Methods
- defclear_nodes
- asyncclose
- defcreate_node
- asyncdecode_track
- asyncdecode_tracks
- defget_best_node
- defget_node
- defremove_node
- asyncsearch_track
- asyncstart
Represents a SonoLink client.
A client helps you manage all Node connections and players.
- Parameters:
client (
discord.Client(discord.py) |discord.Client(py-cord) |disnake.Client) – The Discord client this SonoLink client is attached to.node_cls (
type[Node]) – The class to use when creating new nodes. Defaults toNode.framework (
str|None) – The Discord framework to use. Accepted values are"discord.py","pycord","disnake"and"nextcord". WhenNone, the framework is detected automatically from whichever library is installed. If no supported framework is found, aRuntimeErroris raised. If multiple are present, the one already imported is preferred; if that is ambiguous, the first available is used and a warning is logged. Defaults toNone.
- Raises:
RuntimeError – No supported Discord framework meeting the minimum version requirements was found, or a
sonolink.Clientis already attached to the given Discord client.
- async close() None[source]¶
Gracefully closes all
Nodeconnections and cleans up internal resources.This will stop all active players and close the underlying websocket and HTTP sessions.
- create_node(*, host: str, port: int, password: str, id: str | None = None, retries: int | None = None, resume_timeout: float = 60.0, cache_settings: CacheSettings | None = None, inactivity_settings: InactivitySettings | None = None, session: SessionType | None = None) N[source]¶
- create_node(*, uri: str, password: str, id: str | None = None, retries: int | None = None, resume_timeout: float = 60.0, cache_settings: CacheSettings | None = None, inactivity_settings: InactivitySettings | None = None, session: SessionType | None = None) N
Creates a
Nodeattached to this client.- Parameters:
password (
str) – The password of the node.The URI the node will connect to. You should only provide the base URI without any routes, as the library will do it for you. This is mutually exclusive with providing
hostandport.Changed in version 1.1.0: This is optional now to accommodate users who prefer providing host and port separately.
The host of the node. This is mutually exclusive with providing
uri.Added in version 1.1.0.
The port of the node. This is mutually exclusive with providing
uri.Added in version 1.1.0.
id (
str|None) – The ID of this node. This is used internally to identify this node. IfNoneis passed, it is generated automatically.retries (
int|None) – The amount of retries to attempt when connecting or reconnecting this node. Whenever the limit is reached, it closes the node automatically. If this is set toNone, it retries indefinitely. Defaults toNone.resume_timeout (
float) – The maximum amount of seconds a resume can take before closing the node. Defaults to60.0.cache_settings (
CacheSettings|None) – The search result caching configuration. Defaults toCacheSettings.default().inactivity_settings (
InactivitySettings|None) – The inactivity configuration for all players connected to this node. IfNoneis passed, it usesInactivitySettings.default().session (
aiohttp.ClientSession|curl_cffi.AsyncSession|None) – The session this node should use. IfNoneis provided, creates one. Defaults toNone.auto_reconnect (
bool) –Whether the node should attempt to reconnect automatically after an unexpected disconnect. Defaults to
True.versionadded:: 1.2.0
- Raises:
ValueError – Invalid combination of parameters. You must provide either
urior bothhostandport, but not all three.- Returns:
The node that was created.
- Return type:
- async decode_track(encoded: str) Playable[source]¶
Decodes a track from its encoded data using the best Node available, obtained with
Client.get_best_node().When a track is fetched, the encoded data can be found under
sonolink.rest.schemas.Track.encoded.- Parameters:
encoded (
str) – The encoded data to resolve the track from.- Returns:
The decoded resolved track.
- Return type:
- async decode_tracks(*encoded: str) list[Playable][source]¶
Bulk decode encoded tracks using the best Node available, obtained with
Client.get_best_node().- Parameters:
*encoded (
str) – The encoded data for each track to be decoded.- Returns:
The decoded resolved tracks.
- Return type:
list[Playable]
- get_best_node() N[source]¶
Returns the best available
Nodebased on current load and connectivity.- Returns:
The node with the lowest penalty that is currently connected.
- Return type:
- Raises:
RuntimeError – No nodes are currently connected to handle the request.
- remove_node(identifier: str, /) None[source]¶
Removes a Node from this client.
- Parameters:
identifier (
str) – The ID of the node to remove.
- async search_track(query: str, *, source: TrackSourceType | str = TrackSourceType.YOUTUBE) SearchResult[source]¶
Searches for
queryin the best Node available, obtained withClient.get_best_node().- Parameters:
query (
str) – The query to search. This can be a full URL, or headed by hosts specified by any plugin.source (
TrackSourceType|str) – The source to search from. This is, essentially, providing a host toquery. The library provides default source types underTrackSourceType, but custom ones can be passed with a raw string.
- Returns:
The search result.
- Return type:
- async start() None[source]¶
Connects all registered nodes to their respective Lavalink servers.
This method should typically be called after the discord client is logged in, often within the
setup_hook(discord.py) oron_connect(py-cord, disnake and nextcord) event.
Node¶
- class sonolink.Node(*, client: Client[Any], uri: str, password: str, id: str | None = None, retries: int | None = None, resume_timeout: float = 60, cache_settings: CacheSettings | None = None, inactivity_settings: InactivitySettings, session: SessionType | None = None, auto_reconnect: bool = True)[source]¶
- AttributesMethods
- asynccleanup
- asyncclose
- asyncconnect
- defcreate_player
- asyncdecode_track
- asyncdecode_tracks
- asyncdisconnect_player
- asyncfetch_info
- asyncfetch_player
- asyncfetch_players
- defget_player
- asyncreconnect
- asyncsearch_track
- asyncsend
Represents a connectable Node.
- Parameters:
client (
sonolink.Client) – The SonoLink client this node is attached to.uri (
str) – The base URI for the Lavalink node. Do not include REST or websocket routes.password (
str) – The Lavalink server password used for both HTTP and websocket authentication.id (
str|None) – The identifier used to track this node inside the client. IfNoneis passed, a random identifier is generated.retries (
int|None) – How many reconnect attempts should be made before the node gives up. IfNoneis passed, reconnect attempts are unlimited.resume_timeout (
float) – The number of seconds Lavalink should keep a resumable session alive.cache_settings (
sonolink.models.CacheSettings|None) – Settings used for the node’s search-result cache. IfNoneis passed, default cache settings are used.inactivity_settings (
sonolink.models.InactivitySettings) – Default inactivity behavior applied to players managed by this node.session (
aiohttp.ClientSession|curl_cffi.AsyncSession|None) – Optional pre-existing HTTP session to reuse for this node’s REST and websocket transport. IfNoneis passed, the library creates one.auto_reconnect (
bool) – Whether the node should attempt to reconnect automatically after an unexpected disconnect.
- async cleanup() None[source]¶
A function that may be overridden in order to add custom clean-up logic to a node.
This is automatically called by the library.
- async close() None[source]¶
Closes the connection to this node.
All Players connected to it will stop playing.
This also closes all HTTP and WS sessions and connections.
This dispatches a
on_node_closeevent.
- async connect() None[source]¶
Connects this node.
This can only be done when the node has been attached to a pool.
- create_player(*, volume: int | None = None, paused: bool | None = None, filters: Filters | None = None, queue_mode: QueueMode = QueueMode.NORMAL, autoplay_settings: AutoPlaySettings | None = None, history_settings: HistorySettings | None = None) Player[source]¶
Creates a player with extra configuration bound to this node.
- Parameters:
volume (
int|None) – The volume of the player, in percentage from 0 to 1000. Defaults toNone.paused (
bool|None) – Whether the player should start paused. Defaults toNone.filters (
Filters|None) – The filters to apply to the player. Defaults toNone.queue_mode (
QueueMode) – The playback strategy for the queue. Defaults toQueueMode.NORMAL.autoplay_settings (
AutoPlaySettings|None) – The autoplay settings to set to this player. Defaults toNone.history_settings (
HistorySettings|None) – The history settings to set to this player. Defaults toNone.
- Returns:
The player. This can be passed to the
cls=kwarg ondiscord.abc.Connectable.connect()(discord.py)discord.VoiceChannel.connect()(py-cord)disnake.VoiceChannel.connect()(disnake)nextcord.VoiceChannel.connect()(nextcord)
- Return type:
- async decode_track(encoded: str) Playable[source]¶
Decodes a track from its encoded data.
When a track is fetched, the encoded data can be found under
sonolink.rest.schemas.Track.encoded.- Parameters:
encoded (
str) – The encoded data to resolve the track from.- Returns:
The decoded resolved track.
- Return type:
- async decode_tracks(*encoded: str) list[Playable][source]¶
Bulk decodes encoded tracks.
- Parameters:
*encoded (
str) – The encoded data for each track to be decoded.- Returns:
The decoded resolved tracks.
- Return type:
list[Playable]
- async disconnect_player(guild_id: int) None[source]¶
Force disconnects a player from this node connected to the provided guild ID.
- Parameters:
guild_id (
int) – The guild ID to disconnect the player from.
- async fetch_info() ServerInfo[source]¶
Fetches the Lavalink server info this node is connected to.
- Returns:
The server info.
- Return type:
- async fetch_player(guild_id: int) PlayerInfo[source]¶
Fetches a player from this node connected to the provided guild ID.
Usually, you should use
Node.get_playerinstead of this method.- Parameters:
guild_id (
int) – The guild ID the player is connected to.- Returns:
The player connected to the guild ID.
- Return type:
- async fetch_players() list[PlayerInfo][source]¶
Fetches all the players that are connected to this node.
This performs a fresh REST request for the current player states on the node.
- Returns:
The players connected to this node.
- Return type:
list[PlayerInfo]
- get_player(guild_id: int, /) BasePlayer | None[source]¶
Gets a player connected to this node.
- async reconnect() None[source]¶
Reconnects this node.
This can only be done when the node has been attached to a pool.
Added in version 1.2.0.
- async search_track(query: str, *, source: TrackSourceType | str | None = None) SearchResult[source]¶
Searches for
queryin this Node.- Parameters:
query (
str) – The query to search. This can be a full URL, or headed by hosts specified by any plugin.source (
TrackSourceType|str|None) – The source to search from. This is, essentially, providing a host toquery. The library provides default source types underTrackSourceType, but custom ones can be passed with a raw string.
- Returns:
The search result.
- Return type:
- async send(method: Literal['GET', 'POST', 'PATCH', 'PUT', 'DELETE', 'OPTIONS'], path: str, *, headers: Mapping[str, str] | None = None, params: Mapping[str, str] | None = None, json: dict[str, Any] | None = None, data: Any | None = None) dict[str, Any] | list[Any] | str | bytes | None[source]¶
Method for doing manual requests to the Lavalink node.
Warning
Usually you wouldn’t use this method. Please use the built in methods of
Client,NodeandPlayer, unless you need to send specific plugin data to Lavalink.Using this method may have unwanted side effects on your players and/or nodes.
- Parameters:
method (
str|None) – The method to use when making this request. Available methods are “GET”, “POST”, “PATCH”, “PUT”, “DELETE” and “OPTIONS”. Defaults to “GET”.path (
str) – The path to make this request to. E.g. “stats”, which will translate to “/v4/stats”. Do not include the base URI of the node here or the “/v4” prefix.headers (
Mapping|None) – An optional dict of headers to send with this request. This is merged with the default headers used for the node, so you don’t have to include authentication headers here. E.g.{"X-Thing": "Value"}.params (
Mapping|None) – An optional dict of query parameters to send with your request. If you include your query parameters in thepathparameter, do not pass them here as well. E.g.{"thing": 1, "other": 2}would equate to “?thing=1&other=2”.json (
dict|None) – The optional JSON data to send along with your request.data (
Any|None) – The optional data to send along with your request.
- Returns:
The response body returned by Lavalink, if any. This can be a dict (if the response is a JSON object), a list (if the response is a JSON array), a string (if the response is text) or bytes (if the response is binary). If the response has no body or the request is out of lavalink’s control,
Noneis returned.- Return type:
- Raises:
msgspec.DecodeError – The response body could not be decoded.
sonolink.HTTPException – An error occurred while making the request.
- property inactivity_settings: InactivitySettings¶
The inactivity configuration for all players on this node.
- property session_id: str¶
The current session ID for this node.
- Raises:
RuntimeError – The node is not connected or has no active session.
- property stats: StatsResponse | None¶
The latest stats received from the Lavalink node.
Player¶
- class sonolink.Player(client: Any, channel: Any)[source]¶
- class sonolink.Player(*, node: Node | None = None, queue_mode: QueueMode = QueueMode.NORMAL, autoplay_settings: AutoPlaySettings | None = None, history_settings: HistorySettings | None = None, volume: int | None = None, paused: bool | None = None, filters: Filters | None = None, **kwargs: Any)
- AttributesMethods
- defcleanup
- asyncconnect
- asyncdisconnect
- defget_connection_state
- asyncmove_to
- asyncon_voice_server_update
- asyncon_voice_state_update
- asyncpause
- asyncplay
- asyncprevious
- asyncresume
- asyncseek
- asyncset_filters
- asyncset_volume
- asyncskip
- asyncstop
- asyncupdate
A dynamic proxy class for SonoLink players.
Automatically resolves the appropriate
BasePlayerimplementation for the detected or configured Discord library backend (discord.py,py-cord,disnake, ornextcord) at instantiation time.The framework is resolved from the
SONOLINK_FRAMEWORKenvironment variable, or detected automatically from whichever supported library is installed. If no supported framework is found, aRuntimeErroris raised. If multiple are present, the one already imported is preferred; if that is ambiguous, the first available is used and a warning is logged.There are two primary ways to create a player:
Class-pass — pass the class itself to the voice channel’s
connectmethod. The library will instantiate it directly:player = await voice_channel.connect(cls=Player)
Instance-pass — construct a pre-configured instance and pass it instead. The library will call
player(client, channel)which hits the concrete adapter’s__call__():player = Player(node=some_node, volume=80) await voice_channel.connect(cls=player)
- Parameters:
node (
Node| None) – The Lavalink node to associate with this player. IfNone, an available node is resolved from the client’s node pool at connection time.queue_mode (
QueueMode) – The initial queue looping mode. Defaults toQueueMode.NORMAL.autoplay_settings (
AutoPlaySettings| None) – AutoPlay configuration.Noneuses the default configuration. History must be enabled when AutoPlay is active.history_settings (
HistorySettings| None) – History configuration.Noneuses the default configuration.volume (
int| None) – Initial volume in the range0–1000. Defaults to100.paused (
bool| None) – Whether the player should start in a paused state. Defaults toFalse.filters (
Filters| None) – Initial audio filters. Defaults to an emptyFiltersinstance.
- guild¶
The guild this player is attached to. The concrete type depends on the underlying Discord library (e.g.
discord.Guild(discord.py),discord.Guild(py-cord),disnake.Guild(disnake), ornextcord.Guild(nextcord)).
- channel¶
The voice channel this player is currently connected to. The concrete type depends on the underlying Discord library.
- Type:
Any
- client¶
The Discord client instance driving this player. The concrete type depends on the underlying Discord library.
- Type:
Any
- cleanup() None[source]¶
Cleans the internal state of the Player. This is automatically called by the library when failures or disconnects occur.
If this is overridden, it must call the original
cleanup.
- async connect(*, timeout: float = 10.0, reconnect: bool = False, self_deaf: bool = False, self_mute: bool = False) None¶
Connect this player to its assigned voice channel.
Called automatically by libraries after the player is instantiated. Manual invocation is not normally required.
- Parameters:
timeout (
float) – Seconds to wait for the Discord gateway handshake before raising. Defaults to10.0.reconnect (
bool) – Whether to attempt reconnection on failure. Defaults toFalse.self_deaf (
bool) – Whether to join the channel self-deafened. Defaults toFalse.self_mute (
bool) – Whether to join the channel self-muted. Defaults toFalse.
- async disconnect(*, force: bool = False) None¶
Disconnect this player, destroy it on the Lavalink node, and clean up all internal state.
- Parameters:
force (
bool) – IfTrue, proceeds even if the player is not currently connected. Defaults toFalse.
- get_connection_state() PlayerConnectionState¶
Return a
PlayerConnectionStateinstance for this player.Override this method to supply a custom connection state subclass with additional metadata relevant to your application.
- Return type:
PlayerConnectionState
- async move_to(node: Node, /) None¶
Migrate this player to a different Lavalink node without interrupting playback.
- Parameters:
node (
Node) – The destination node.
- async on_voice_server_update(data: Any) None[source]¶
Handle a
VOICE_SERVER_UPDATEpayload from the Discord gateway.This provides the voice server token and endpoint required by the Lavalink node to establish or re-establish the audio stream. This method should be called by the library-specific subclass in response to the corresponding gateway event.
The
datadictionary is passed as a raw mapping so that this base class remains decoupled from any specific library’s type aliases. Subclasses may cast it to the appropriate typed dict for their library (e.g.,discord.types.voice.VoiceServerUpdate,disnake.types.voice.VoiceServerUpdate).- Parameters:
data (
Any) – The rawVOICE_SERVER_UPDATEpayload received from the Discord gateway.
- async on_voice_state_update(data: Any) None[source]¶
Handle a
VOICE_STATE_UPDATEpayload from the Discord gateway.This provides the session ID and channel ID required for the voice connection handshake with the Lavalink node. This method should be called by the library-specific subclass in response to the corresponding gateway event.
The
datadictionary is passed as a raw mapping so that this base class remains decoupled from any specific library’s type aliases. Subclasses may cast it to the appropriate typed dict for their library (e.g.,discord.types.voice.GuildVoiceState,disnake.types.voice.GuildVoiceState).- Parameters:
data (
Any) – The rawVOICE_STATE_UPDATEpayload received from the Discord gateway.
- async pause() None¶
Set the pause state of the player.
- Raises:
RuntimeError – If the player is not connected to a node or an active session.
- async play(track: Playable, /, *, start: int = 0, end: int | None = None, volume: int | None = None, paused: bool | None = None) Playable¶
Begin playback of the specified track.
If a track is already playing, it is stopped and the currently playing track is added to history (if history is enabled) before the new track starts.
- Parameters:
track (
Playable) – The track to play.start (
int) – The position in milliseconds at which to begin playback. Defaults to0.end (
int| None) – The position in milliseconds at which to stop playback. IfNone, the track plays to completion. Defaults toNone.volume (
int| None) – Override the player volume for this track only. IfNone, the current player volume is used. Defaults toNone.paused (
bool| None) – IfTrue, the track begins in a paused state. IfNone, the player’s current pause state is preserved. Defaults toNone.
- Returns:
The track that was dispatched to the Lavalink node for playback.
- Return type:
- async previous() Playable¶
Return to the most recently played track in the history.
The current track is pushed back to the front of the queue so it can be reached again via
skip(). The historical track then begins playing immediately.- Returns:
The historical track that is now playing.
- Return type:
- Raises:
RuntimeError – If the player is not connected to a node or an active session.
HistoryEmpty – If there is no previous track in the history.
- async resume() None¶
Resume playback if the player is currently paused.
- Raises:
RuntimeError – If the player is not connected to a node or an active session.
- async seek(position: int, /) None¶
Seek to an arbitrary position within the current track.
- Parameters:
position (
int) – The target position in milliseconds. Must be within the bounds of the current track’s duration.- Raises:
RuntimeError – If the player is not connected to a node or an active session.
- async set_filters(filters: Filters, /, *, seek: bool = False) None¶
Apply a new set of audio filters to this player.
- Parameters:
- Raises:
RuntimeError – If the player is not connected to a node or an active session.
- async set_volume(value: int, /) None¶
Set the player’s output volume.
- Parameters:
value (
int) – The desired volume level, in the range0–1000.100is the default (unmodified) level.- Raises:
ValueError – If
valueis outside the range0–1000.RuntimeError – If the player is not connected to a node or an active session.
- async skip() Playable | None¶
Skip the currently playing track and advance to the next one in the queue.
If the queue is empty and AutoPlay is enabled, a related track may be fetched automatically. If neither a queued nor an AutoPlay track is available, playback stops and
Noneis returned.- Returns:
The track that began playing after the skip, or
Noneif the player stopped due to an empty queue with no AutoPlay fallback.- Return type:
Playable| None- Raises:
RuntimeError – If the player is not connected to a node or an active session.
QueueEmpty – If the queue is empty and AutoPlay is disabled or yields no results.
- async stop(*, clear_queue: bool = False, clear_history: bool = False) None¶
Stop the currently playing track.
This sends a stop request to the Lavalink node and resets the player’s internal position tracking and current track reference.
- Parameters:
- Raises:
RuntimeError – If the player is not connected to a node or an active session.
- async update(*, queue_mode: QueueMode | None = None, autoplay_settings: AutoPlaySettings | None = None, history_settings: HistorySettings | None = None, volume: int | None = None, filters: Filters | None = None) None¶
Update the player’s configuration in-place.
Added in version 1.1.0.
- Parameters:
queue_mode (
QueueMode| None) – The new queue looping mode. IfNone, the current mode is preserved.autoplay_settings (
AutoPlaySettings| None) – New AutoPlay configuration. IfNone, the current settings are preserved.history_settings (
HistorySettings| None) – New history configuration. IfNone, the current settings are preserved.volume (
int| None) – New volume in the range0–1000. IfNone, the current volume is preserved.filters (
Filters| None) – New audio filters. IfNone, the current filters are preserved.
- property autoplay: AutoPlayMode¶
The current
AutoPlayModefor this player.When AutoPlay is enabled, the player will automatically fetch and enqueue related tracks when the queue is exhausted.
- Raises:
RuntimeError – When setting, if the player’s history is disabled (history is required for AutoPlay to function).
- property autoplay_settings: AutoPlaySettings¶
The current
AutoPlaySettingsfor this player.Can be mutated directly to update individual fields, or replaced entirely.
Added in version 1.1.0.
- Return type:
- channel: Any¶
- client: Any¶
- property current: Playable | None¶
The track that is currently playing, or
Noneif the player is idle.- Return type:
Playable| None
- property filters: Filters¶
The
Filterscurrently applied to this player.To apply new filters, use
set_filters()rather than mutating this object directly, so that the updated state is dispatched to the Lavalink node.- Return type:
- property guild: Any¶
The guild this player is associated with.
The concrete return type is the guild class of the underlying Discord library (e.g.
discord.Guild,disnake.Guild).- Raises:
RuntimeError – If the player has not yet been attached to a guild.
- property history_settings: HistorySettings¶
The current
HistorySettingsfor this player’s queue.Can be mutated directly to update individual fields, or replaced entirely.
Added in version 1.1.0.
- Return type:
- property node: Node¶
The
Nodethis player is currently attached to.- Raises:
RuntimeError – If the player is not currently attached to a node.
- property position: int¶
The estimated current playback position in milliseconds.
When the player is paused or has not yet started, this returns the last known position. Otherwise, it is calculated by interpolating the time elapsed since the last state update received from the Lavalink node.
- Returns:
Position in milliseconds.
- Return type:
- property queue: Queue¶
The
Queueassociated with this player.The queue manages both upcoming tracks and playback history. Tracks can be added with
queue.put()/queue.put_wait()and inspected or manipulated via the queue’s public API.- Return type:
Queue