PixelWeaver v0.5.0 /server.src.pixelweaver.main
On this page

wesktop application for PixelWeaver collaboration server.

#server.src.pixelweaver.main

#server.src.pixelweaver.main

wesktop application for PixelWeaver collaboration server.

Provides REST endpoints for project management and a WebSocket endpoint for the real-time server-authoritative protocol.

#lifespan

python
async def lifespan(scope)

Startup/shutdown lifecycle: load projects from disk, start auto-saver.

#health_check

python
async def health_check(req: Request)

Health check endpoint.

The payload names the application and its version, not just liveness: any HTTP service can answer {"status": "ok"}, so a client that merely finds something listening on the expected port cannot tell a PixelWeaver backend from an unrelated app that happens to hold it. Tooling (the e2e suite) probes here and refuses to drive a server that does not identify itself.

#CreateProjectRequest

#name_must_be_safe

python
def name_must_be_safe(cls, v: str) -> str

Reject names that could escape the project data directory.

#list_all_projects

python
async def list_all_projects(req: Request)

List all projects.

#create_project

python
async def create_project(req: Request)

Create a new project.

#get_project

python
async def get_project(req: Request)

Get project metadata.

#delete_project

python
async def delete_project(req: Request)

Delete a project from memory (does not delete files on disk).

#activate_project

python
async def activate_project(req: Request)

Make the named project active and repaint every connected client.

Switching the active project is navigation, not a content mutation: it goes through the same validate-and-set path as the MCP open_project tool (state.set_active_project), then broadcasts a full-state patch over the live WebSocket path so all clients repaint to the newly-active project (pixels, layers, canvas).

#export_png

python
async def export_png(req: Request)

Export a frame as a composited PNG.

#export_part_manifest

python
async def export_part_manifest(req: Request)

Export the part-manifest document (G8) as JSON.

#export_part_strip

python
async def export_part_strip(req: Request)

Export a single per-part PNG strip (kind = indexed | rgba).

#export_parts_zip

python
async def export_parts_zip(req: Request)

Export part-manifest.json + all strips as a deterministic zip.

#get_full_state

python
async def get_full_state(req: Request)

Return the full serialized server state for MCP sync.

The MCP server calls this before executing a tool so it operates on the latest state held by the collab server.

#sync_state_from_mcp

python
async def sync_state_from_mcp(req: Request)

Accept full state from the MCP server and broadcast changes.

After the MCP server executes a tool, it pushes the modified state here. The collab server overwrites its in-memory state and broadcasts a full-state patch to every connected WebSocket client so the frontend sees the mutation.

#_on_dirty

python
def _on_dirty() -> None

Callback passed to message handler to mark state as dirty.

#websocket_endpoint

python
async def websocket_endpoint(ws: WebSocket)

WebSocket endpoint for the server-authoritative protocol.

#make_app

python
def make_app(*, serve_static: bool=True)

Build the PixelWeaver ASGI app.

Production, desktop, and plain serve mode serve the built SPA from dist/ on the same origin as the API. Dev mode (pixelweaver dev) instead lets Vite serve the sources and wraps this app in fastware's ViteDevProxy, which routes /api and /ws to the backend and proxies everything else (assets, HMR) to Vite. That proxy uses a backend-first strategy: a non-API request only falls through to Vite if the backend returns 404. If static/SPA serving were left on, the app would answer every non-API GET with the stale dist/index.html (a 200), so the fallthrough would never reach Vite and HMR would break. Pass serve_static=False for the dev app to disable static/SPA serving.

Search