# Now Playing Logger Plugin (Python)A Python example plugin that demonstrates the **Scheduler** and **SubsonicAPI** host services by periodically logging what is currently playing in Navidrome.## Features- Uses `scheduler_schedulerecurring` host function to set up a recurring task- Uses `subsonicapi_call` host function to query the `getNowPlaying` API- Configurable cron expression and user via plugin config- Demonstrates Python host function imports using `@extism.import_fn`## Prerequisites- [extism-py](https://github.com/extism/python-pdk) - Python PDK compiler```bashcurl -Ls https://raw.githubusercontent.com/extism/python-pdk/main/install.sh | bash```> **Note:** `extism-py` requires [Binaryen](https://github.com/WebAssembly/binaryen/) (`wasm-merge`, `wasm-opt`) to be installed.## BuildingFrom the `plugins/examples` directory:```bashmake nowplaying-py.ndp```Or directly:```bashextism-py plugin/__init__.py -o plugin.wasmzip -j nowplaying-py.ndp manifest.json plugin.wasm```## Installation1. Copy `nowplaying-py.ndp` to your Navidrome plugins folder2. Enable plugins in `navidrome.toml`:```toml[Plugins]Enabled = trueFolder = "/path/to/plugins"```3. Configure the plugin in the UI (Settings → Plugins → nowplaying-py)## Configuration| Key | Description | Default ||--------|-------------------------------------|---------------|| `cron` | Cron expression for check frequency | `*/1 * * * *` || `user` | Navidrome user for SubsonicAPI | `admin` |## TestingTest the manifest:```bashextism call nowplaying-py.wasm nd_manifest --wasi```## OutputWhen running, the plugin logs messages like:```🎵 john is playing: Pink Floyd - Comfortably Numb (The Wall)🎵 jane is playing: Radiohead - Paranoid Android (OK Computer)```Or when no one is playing:```🎵 No users currently playing music```## How It Works1. **Initialization (`nd_on_init`)**: Reads the cron expression from config and schedules a recurring task using the Scheduler host service.2. **Callback (`nd_scheduler_callback`)**: When the scheduled task fires, calls the SubsonicAPI `getNowPlaying` endpoint and logs the results.## Host Function Usage (Python)This plugin demonstrates how to call Navidrome host functions from Python:```pythonimport extismimport json# Import the host function@extism.import_fn("extism:host/user", "subsonicapi_call")def _subsonicapi_call(offset: int) -> int:"""Raw host function - returns memory offset."""...# Wrapper for JSON marshallingdef subsonicapi_call(uri: str) -> dict:request = {"uri": uri}request_bytes = json.dumps(request).encode('utf-8')request_mem = extism.memory.alloc(request_bytes)response_offset = _subsonicapi_call(request_mem.offset)response_mem = extism.memory.find(response_offset)response = json.loads(extism.memory.string(response_mem))if response.get("error"):raise Exception(response["error"])return json.loads(response.get("responseJSON", "{}"))```