An asynchronous Python wrapper and WebSocket server for controlling the Spotify desktop client via Spicetify and the spicetify-connect-api extension.
✨ Features
- ⚡ Real-time Push Events: Instant updates for song changes, volume, seeking, and playback state.
- 🎮 Full Playback Control: Play, pause, skip, seek, volume, repeat, and shuffle.
- 🛠️ Convenience Decorators: Easy event listening with syntax like
@server.on_song_changed. - 🏷️ Fully Typed: Pydantic V2 models (
TrackInfo,PlayerState,RepeatMode). - 🔄 Async & Non-blocking: Built on
asyncioandwebsocketsfor maximum performance.
⚙️ Installation
Python 3.10 or higher is required.
pip install spicetify-websocket
📋 Prerequisites
To use this library, ensure you have:
- Spotify Desktop Client installed.
- Spicetify CLI installed and configured.
- The spicetify-connect-api extension enabled in Spicetify.
🚀 Example Usage
import asyncio
from spicetify import RepeatMode, SpotifyServer, TrackInfo
async def main():
async with SpotifyServer() as server:
# Wait until Spicetify client connects
await server.wait_for_connection()
# Playback Controls
await server.play_url(url="https://open.spotify.com/intl-de/track/55pBIZO1cqoldeqpp5WR7H?si=57cde33a1bd34ac9")
await server.set_volume(percent=75)
await server.set_repeat(mode=RepeatMode.TRACK)
# Playback State
current_track: TrackInfo = await server.get_current_track()
print(current_track)
# Events
@server.on_song_changed
def callback(track: TrackInfo):
print("New song is playing:", track.title)
print("Artist/s:", ", ".join(artist.name for artist in track.artists))
# Keep the server running to receive events
await asyncio.Event().wait()
if __name__ == "__main__":
asyncio.run(main())
📻 Events Reference
| Event Name | Convenience Decorator | Callback Payload Type | Description |
|---|---|---|---|
InitialState |
@server.on_initial_state |
PlayerState |
Fired immediately when Spicetify connects. |
SongChanged |
@server.on_song_changed |
TrackInfo |
Fired when a new track starts playing. |
PlayPauseChanged |
@server.on_play_pause_changed |
PlayerState |
Fired when playback state changes. |
VolumeChanged |
@server.on_volume_changed |
float (0–100%) |
Fired when volume level changes. |
RepeatChanged |
@server.on_repeat_changed |
RepeatMode |
Fired when repeat mode changes (OFF, CONTEXT, TRACK). |
ShuffleChanged |
@server.on_shuffle_changed |
bool |
Fired when shuffle mode is toggled. |
SeekChanged |
@server.on_seek_changed |
int (ms) |
Fired when timeline position is manually changed. |
Metadata
Release files for spicetify-websocket 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| spicetify_websocket-0.1.0.tar.gz | 17.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| spicetify_websocket-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.9 kB
Release files / spicetify_websocket-0.1.0.tar.gz
| Download URL | spicetify_websocket-0.1.0.tar.gz |
|---|---|
| Size | 17.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e635327f19644c7a5b6112815eb197fc40163d8d7ee4e16fe834f4f43f7e0573
|
|
BLAKE2b-256 checksum How to use checksums |
a2bcc80285b3059689590fc171e158c02f57f86f51aa61f010b5941b8528682e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / spicetify_websocket-0.1.0-py3-none-any.whl
| Download URL | spicetify_websocket-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4708edfc624586fa194d7c1d9715c1052ced3a0c840b8578c2cb019c7ca2379c
|
|
BLAKE2b-256 checksum How to use checksums |
9e6f722e889e7d9c7dd164c01b3585f01c3bbb1155b801ed3a39a28b067f7ced
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|