muvid.mcp.workspace¶
Per-user output bucket for the muvid music-visualizer MCP genre.
A remote MCP connector is stateless and multi-user, so each caller must be isolated
and address work by project_id (never a path). The visualizer is itself stateless
— a render is a pure function of (audio, cover, visual) — so a “project” here is just a
lightweight bucket where a caller’s renders land, not a full nw/muvid project (no
graph, no asset store). That keeps the music-visualizer genre the cheapest possible
2nd genre (thorwhalen/muvid#3); a richer per-user asset library (content-addressed
uploads shared across genres) is a deliberate follow-up.
Layout (default root ~/.local/share/muvid; override via MUVID_DATA_HOME):
{root}/visualizer/projects/{email}/{project_id}/manifest.json— the bucket{root}/visualizer/projects/{email}/{project_id}/renders/{render_id}/— one render (its.mp4, optionalthumbnail.jpg, and ameta.jsonsidecar)
Every subgenre (lyric-video and anything bridged by muvid.genre_subgenres)
gets the same kind of bucket in a directory that names it (muvid#103), so its project
ids are its own and a listing can label it:
{root}/subgenres/{slug}/projects/{email}/{project_id}/—SubgenreWorkspace
Before muvid#103 subgenre projects were created in the visualizer workspace, sharing its
id space and its visualizer label. Those projects are not moved: every subgenre tool
opens through open_subgenre_project(), which falls back to the visualizer bucket of
the same id, so an old project id keeps working exactly as before.
Per the app-data-lifecycle rule this lives in the user-data dir, never inside the
app/deploy tree (a deploy’s rsync --delete would erase it).
Module Attributes
Env var overriding the muvid data root (where per-user visualizer buckets live). |
|
The path segment under the data root that holds one directory per subgenre (muvid#103). |
Functions
|
What a visualizer-drawer bucket holds: |
The muvid data root: |
|
|
The bucket a subgenre renders into: its own, else a visualizer bucket of that id. |
|
The subgenre a render's |
|
The subgenres that have a directory under the data root, sorted. |
Classes
|
A single caller's area for ONE subgenre: the visualizer's bucket, in its own directory. |
|
One caller's visualizer bucket — a folder its renders land in. |
|
A single caller's private visualizer area, addressed by |
- muvid.mcp.workspace.DATA_HOME_ENV_VAR = 'MUVID_DATA_HOME'¶
Env var overriding the muvid data root (where per-user visualizer buckets live). Re-exported from
muvid.paths, the SSOT — this module used to carry its own verbatim copy of both, beside a second copy inmuvid/footage/workspace.py.
- muvid.mcp.workspace.SUBGENRES_SEGMENT = 'subgenres'¶
The path segment under the data root that holds one directory per subgenre (muvid#103).
- class muvid.mcp.workspace.SubgenreWorkspace(email, root, slug)[source]¶
Bases:
VisualizerWorkspaceA single caller’s area for ONE subgenre: the visualizer’s bucket, in its own directory.
A subgenre is stateless the way the visualizer is (a “project” is where renders land), so the bucket is the same
VisualizerProject; only the directory differs, which gives each subgenre its own project-id space and a path that names it (muvid#103). Built withfor_slug(), neverfor_email().- create_project(project_id, *, title='', force=False)[source]¶
Create a bucket, refusing to fork one this subgenre already made.
Before muvid#103 this subgenre’s projects were made in the visualizer drawer. Creating the same id here would succeed and shadow it: the subgenre’s tools would open the new, empty bucket, and the old renders would drop out of their reach. So an id whose visualizer bucket holds only this subgenre’s renders is refused, as it was before.
- Return type:
- class muvid.mcp.workspace.VisualizerProject(email, project_id, root)[source]¶
Bases:
objectOne caller’s visualizer bucket — a folder its renders land in.
rootis exposed sonw.create_genre_project’s all-or-nothing rollback (nw.genres._rollback_projectremovesproject.root) reverts a half-created bucket. Kept storage-only: no nw graph, no asset library.
- class muvid.mcp.workspace.VisualizerWorkspace(email, root)[source]¶
Bases:
objectA single caller’s private visualizer area, addressed by
email.emailand everyproject_idare validated as single path components, so a caller can never escape their own subtree.- create_project(project_id, *, title='', force=False)[source]¶
Create (and return) a new visualizer bucket under this user.
- Return type:
- muvid.mcp.workspace.bucket_label(proj)[source]¶
What a visualizer-drawer bucket holds:
"visualizer", or the one subgenre whose work is all it holds.Before muvid#103 subgenre projects lived in this drawer, so the drawer cannot label them; their renders can. Evidence is each finished render’s
meta.json(a render folder without one is a render that failed or is still running, and says nothing), plus thelyricvid/folder the lyric tools fetch their inputs into. A bucket with no evidence, or one that mixes visualizer and subgenre work (allowed before and after muvid#103), stays"visualizer". Read-only: nothing is moved or rewritten.- Return type:
- muvid.mcp.workspace.data_root()[source]¶
The muvid data root:
$MUVID_DATA_HOMEor~/.local/share/muvid.Public API (
muvid.mcpre-exports it), so the name stays though the body moved. A forwarder, not an alias, for the introspection reason given on the footage twin.- Return type:
- muvid.mcp.workspace.open_subgenre_project(slug, email, project_id, *, root=None)[source]¶
The bucket a subgenre renders into: its own, else a visualizer bucket of that id.
The fallback is what keeps every project made before muvid#103 (and every visualizer project a caller already rendered a lyric video into) working: those live in the visualizer workspace and are read in place, never moved.
- Return type:
- muvid.mcp.workspace.subgenre_of_render(meta)[source]¶
The subgenre a render’s
meta.jsonsays made it, if it says.render_subgenrerecordssubgenre(checked first, so a choreo or montage render, whose own meta also carriestreatment_source, is named correctly).render_lyric_videorecords nosubgenre; its nested pipeline meta hastreatment_source, which no visualizer render carries.