Pycrdt WebSocket Connector
Pycrdt-websocket provides a WebSocket connector for `pycrdt`, enabling real-time, collaborative document synchronization using Y-CRDTs over a network. It facilitates both server-side handling of Y-CRDT documents and client-side connections. The library is actively maintained with frequent minor releases, typically addressing bug fixes and compatibility updates.
Common errors
-
ModuleNotFoundError: No module named 'pycrdt_websocket'
cause Attempting to import from the old package name `pycrdt_websocket` after upgrading to version 0.16.0 or newer.fixUpdate your import statements to use `from pycrdt.websocket import ...`. -
AttributeError: module 'pycrdt.websocket' has no attribute 'YStore'
cause `YStore` was moved to the `pycrdt-store` package in version 0.16.0, and is no longer directly available from `pycrdt.websocket`.fixInstall `pycrdt-store` (`pip install pycrdt-store`) and change your import to `from pycrdt_store import YStore`. -
TypeError: object Room can't be used in 'await' expression
cause You are attempting to use an `async` function call (like `room.connect()`) without the `await` keyword, or calling it outside an `async` context.fixEnsure that `room.connect()` (and similar `async` methods) are called with `await` inside an `async def` function, and that the top-level call is handled by `asyncio.run()`.
Warnings
- breaking The top-level package name for imports changed from `pycrdt_websocket` to `pycrdt.websocket` starting from version 0.16.0. This requires updating all import statements.
- breaking The `YStore` class, which manages persistence for Y-CRDT documents, was extracted into a separate package `pycrdt-store` starting from version 0.16.0. If you were using or subclassing `YStore` directly, you now need to import it from `pycrdt_store`.
- gotcha Pycrdt-websocket is built on `asyncio` and requires `await` for all network operations (e.g., `server.start()`, `room.connect()`). Forgetting `await` will lead to silent failures or incorrect behavior.
- gotcha Compatibility with `pycrdt` versions is crucial. Always check the release notes for `pycrdt-websocket` to ensure you are using a compatible `pycrdt` version, as internal API changes in `pycrdt` can break `pycrdt-websocket` functionality.
Install
-
pip install pycrdt-websocket
Imports
- WebSocketServer
from pycrdt_websocket import WebSocketServer
from pycrdt.websocket import WebSocketServer
- YDocRoom
from pycrdt_websocket import YDocRoom
from pycrdt.websocket import YDocRoom
- YStore
from pycrdt.websocket import YStore
from pycrdt_store import YStore
Quickstart
import asyncio
from pycrdt import YDoc, YText
from pycrdt.websocket import WebSocketServer, YDocRoom
async def server_main():
# Initialize a Y-CRDT document for the server
ydoc = YDoc()
with ydoc.transaction():
text = ydoc.get_text('my_text')
text += 'Hello from server!'
# Create a WebSocket server that manages rooms
server = WebSocketServer(ydoc, 'ws://127.0.0.1:1234')
print("Server starting on ws://127.0.0.1:1234")
await server.start()
await asyncio.sleep(5) # Keep server running for a bit
await server.stop()
print("Server stopped")
async def client_main():
await asyncio.sleep(1) # Give server a moment to start
print("Client connecting...")
# Connect to the server with a YDocRoom
client_ydoc = YDoc()
room = YDocRoom(client_ydoc, 'ws://127.0.0.1:1234')
await room.connect()
# Access the shared text
shared_text = client_ydoc.get_text('my_text')
print(f"Client received: '{shared_text}'")
with client_ydoc.transaction():
shared_text.append(' And client!')
print(f"Client sent: '{shared_text}'")
await asyncio.sleep(1) # Allow changes to propagate
await room.disconnect()
print("Client disconnected")
async def main():
server_task = asyncio.create_task(server_main())
client_task = asyncio.create_task(client_main())
await asyncio.gather(server_task, client_task)
if __name__ == '__main__':
asyncio.run(main())