API Handlers¶
Surface-agnostic orchestration from musicseed-api (musicseed_api.handlers.*). Handlers call
core services, manipulate config, manage job lifecycles, and map errors; routes stay thin.
The HTTP contract itself is the FastAPI OpenAPI schema served at /openapi.json; api/routes/*
is intentionally not documented here.
Recommend¶
musicseed_api.handlers.recommend
¶
Recommendation orchestration — seed parsing, typeahead, and recommendations.
get_recommendation_presets()
¶
Return the authoritative named presets (see RECOMMENDATION_PRESETS).
parse_seed_ids(raw)
¶
Parse a comma-separated seed-id string into a deduplicated int list.
typeahead_search(query, exclude_ids=None)
¶
Search tracks for autocomplete (delegates to the core typeahead service).
run_recommendations(seed_ids, limit=50, year_min=None, year_max=None, max_tracks_per_artist=3, min_score=None, weights=None)
¶
Run the full recommendation pipeline for a set of seed track ids.
Library¶
musicseed_api.handlers.library
¶
Library orchestration — status and import job runnable.
get_library_status()
¶
Return local library statistics and enrichment coverage.
Returns:
| Type | Description |
|---|---|
LibraryStatus
|
The core |
run_import_job(job_id)
¶
Job target: import the Plex library and update job progress.
Discovery¶
musicseed_api.handlers.discovery
¶
Discovery orchestration — wizard readiness, config overrides, database init.
Handlers take plain Python arguments and return Pydantic models. They never import FastAPI, Starlette, or any HTTP framework — the same handler is callable from the CLI, a JSON route, or the web rendering layer.
wizard_ready(result)
¶
True when every prerequisite for database creation is met.
run_discovery(**overrides)
¶
Run local discovery, passing only recognized keys as overrides.
run_plex_discovery(timeout=3.0)
¶
Discover Plex servers: local subnet via GDM/SSDP, plus the Plex account.
Uses the configured Plex token so servers on other subnets (invisible to
multicast) are included when credentials exist. This is a separate, opt-in
probe — it never runs as part of discover().
extract_overrides(**raw)
¶
Split raw form fields into (discovery_overrides, sticky_form_values).
Blank values are dropped. sticky_form_values excludes secret fields
so tokens are never echoed back to the caller.
save_config_overrides(musicseed_db_path='', spotify_client_id='', spotify_client_secret='', listenbrainz_token='', plex_url='', plex_token='', plex_library='', plex_db_path='')
¶
Persist setup overrides to config without any side effects.
Saves credentials and paths only — never creates the database, starts an import, or runs enrichment. When no Plex token is supplied and none is configured, reads one from the local Plex installation (Preferences.xml / .LocalAdminToken) so a same-machine setup needs no manual token. Returns True when anything changed. Blank fields leave the existing config untouched.
apply_config_and_init_db(musicseed_db_path='', spotify_client_id='', spotify_client_secret='', listenbrainz_token='', plex_url='', plex_token='', plex_library='', plex_db_path='')
¶
Persist validated setup overrides to config and create the database.
Carries the Plex settings that passed discovery into config so import
uses the same values the user confirmed. Blank fields leave the existing
config untouched. Raises whatever initialize_database or the config
layer raises; callers are expected to catch and map to their own error
convention.
Enrichment¶
musicseed_api.handlers.enrichment
¶
Enrichment orchestration — credential management and enrichment job runnable.
save_spotify_creds(client_id, client_secret)
¶
Persist Spotify credentials to config. No-op when both are empty.
save_listenbrainz_token(token)
¶
Persist the ListenBrainz user token to config. No-op when empty.
run_enrich_job(job_id, source='spotify')
¶
Job target: enrich tracks via the given source and update job progress.
Dashboard¶
musicseed_api.handlers.dashboard
¶
Dashboard aggregation — combines discovery, library stats, and job state.
get_dashboard_snapshot(check_server=False)
¶
Return the aggregated dashboard snapshot for surfaces.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
check_server
|
bool
|
whether to include the live Plex HTTP probe; defaults to False so frequent dashboard polls never touch Plex. |
False
|
Returns:
| Type | Description |
|---|---|
DashboardSnapshot
|
The combined discovery, library, and job snapshot. |
Jobs¶
musicseed_api.handlers.jobs
¶
Job orchestration — submission, progress, cancellation, and deletion.
submit_job(kind, target, *args, **kwargs)
¶
Submit a new job to the in-process runner. Returns the job id.
Raises JobConflictError when a job of the same kind is already
running or the concurrency pool is full.
get_job_progress(job_id)
¶
Return the current snapshot of a job, or None if not found.
cancel_job(job_id)
¶
Request cancellation of a running job (cooperative).
delete_job(job_id)
¶
Delete a completed job's history entry.
Active jobs cannot be deleted — they must be canceled first and allowed to reach a terminal state.
Playlists¶
musicseed_api.handlers.playlists
¶
Playlist orchestration — list, create, and populate Plex playlists.
get_playlists()
¶
List Plex playlists with track counts.
create_playlist_from_seeds(name, seed_ids, limit=50, weights=None, year_min=None, year_max=None, max_tracks_per_artist=3)
¶
Create a new Plex playlist from seed track recommendations.
preview_populate(playlist_id, limit=10, method='average', weights=None, year_min=None, year_max=None, max_tracks_per_artist=3)
¶
Preview complementary recommendations for an existing playlist.
apply_populate(playlist_id, limit=10, method='average', weights=None, year_min=None, year_max=None, max_tracks_per_artist=3, track_ids=None)
¶
Generate recommendations and add them to an existing Plex playlist.
When track_ids is provided, only those tracks are added and the
recommendation step is skipped.
Sonic¶
musicseed_api.handlers.sonic
¶
Sonic analysis orchestration — coverage inspection and refresh triggering.
get_sonic_coverage(library_name=None, recent_days=7)
¶
Report Plex sonic analysis coverage for a music library.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
library_name
|
str | None
|
Plex music library to inspect; defaults to the configured library. |
None
|
recent_days
|
int
|
size of the "recent additions" window in days. |
7
|
Returns:
| Type | Description |
|---|---|
SonicStatusResult
|
The core |
trigger_sonic_refresh(library_name=None, days=7, wait_seconds=900.0)
¶
Trigger a Plex sonic analysis refresh and reset the cached vectors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
library_name
|
str | None
|
Plex music library to refresh; defaults to the configured library. |
None
|
days
|
int
|
size of the "recent additions" window in days. |
7
|
wait_seconds
|
float
|
maximum time to watch the refresh. |
900.0
|
Returns:
| Type | Description |
|---|---|
SonicRefreshResult
|
The core |