Backend Architecture
The Ganimede backend is a Python application built on Starlette with asynchronous managers for notebook operations, kernel execution, and real-time synchronization.Application Structure
The backend runs two servers:- Starlette App (port 8000): HTTP routes and WebSocket endpoints
- Ypy WebSocket Server (port 1234): Yjs CRDT synchronization
Main Application (main.py)
The main application coordinates all components:Manager Components
RouteManager
Location:managers/RouteManager.py
Responsibilities:
- Serve frontend static files (index.html, assets)
- Register HTTP and WebSocket routes
- Handle development vs production file paths
/- Serve index.html/config- Return configuration JSON/(WebSocket) - Comms endpoint/assets/{path}- Static assets
ConfigManager
Location:managers/ConfigManager.py
Responsibilities:
- Provide frontend configuration (Monaco settings, grid snap, etc.)
Comms Manager
Location:managers/Comms.py
Responsibilities:
- WebSocket communication for control messages
- Route messages to appropriate channel queues
- Bidirectional message passing
Kernel Manager
Location:managers/Kernel.py
Responsibilities:
- Start and manage Jupyter kernel instances
- Execute code and process outputs
- Handle kernel interrupts and restarts
- Update kernel state in YDoc
Notebook Manager
Location:managers/Notebook.py
Responsibilities:
- Load
.ipynbfiles into YDoc - Manage cell graph structures (np_graph, pc_graph)
- Queue cells for execution
- Handle checkpoint (save) operations
- Coordinate cell lifecycle
.ipynb into YDoc shared types:
- np_graph: Maps cell_id → [next_cell_ids] (sequential flow)
- pc_graph: Maps parent_cell_id → [child_cell_ids] (tissue grouping)
YDoc Integration
The backend usesy_py (Python Yjs) to create shared types:
Async Patterns
The backend uses asyncio throughout:- Task creation:
asyncio.create_task(self.listen_comms()) - Queue-based communication:
asyncio.Queue()for message passing - Concurrent operations:
await asyncio.gather(task1, task2) - Event loops:
asyncio.get_event_loop()
Key Patterns
- Manager-based architecture: Each concern (kernel, notebook, comms) is a separate manager
- YDoc as single source of truth: All state lives in YDoc shared types
- Queue-based messaging: Comms routes messages via asyncio queues
- Transaction-based updates: All YDoc changes use transactions for atomicity
- Async throughout: All I/O operations are async for concurrency
Related
- Frontend Architecture - Svelte component structure
- Yjs Integration - Shared state synchronization