Metadata-Version: 2.1
Name: ypy-websocket
Version: 0.7.0
Summary: WebSocket connector for Ypy
Project-URL: Homepage, https://github.com/y-crdt/ypy-websocket
Author-email: David Brochart <david.brochart@gmail.com>
License-File: LICENSE
Keywords: websocket,yjs
Requires-Python: >=3.7
Requires-Dist: aiofiles<1,>=0.8.0
Requires-Dist: aiosqlite<1,>=0.17.0
Requires-Dist: y-py<0.6.0,>=0.5.3
Provides-Extra: test
Requires-Dist: mypy; extra == 'test'
Requires-Dist: pre-commit; extra == 'test'
Requires-Dist: pytest; extra == 'test'
Requires-Dist: pytest-asyncio; extra == 'test'
Requires-Dist: websockets>=10.0; extra == 'test'
Description-Content-Type: text/markdown

[![Build Status](https://github.com/y-crdt/ypy-websocket/workflows/Tests/badge.svg)](https://github.com/y-crdt/ypy-websocket/actions)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)


# ypy-websocket

ypy-websocket is an async WebSocket connector for Ypy.

## Usage

### Client

Here is a code example:

```py
import asyncio
import y_py as Y
from websockets import connect
from ypy_websocket import WebsocketProvider

async def client():
    ydoc = Y.YDoc()
    async with connect("ws://localhost:1234/my-roomname") as websocket:
        WebsocketProvider(ydoc, websocket)
        ymap = ydoc.get_map("map")
        with ydoc.begin_transaction() as t:
            ymap.set(t, "key", "value")

asyncio.run(client())
```

### Server

Here is a code example:

```py
import asyncio
from websockets import serve
from ypy_websocket import WebsocketServer

async def server():
    websocket_server = WebsocketServer()
    async with serve(websocket_server.serve, "localhost", 1234):
        await asyncio.Future()  # run forever

asyncio.run(server())
```

### WebSocket API

The WebSocket object passed to `WebsocketProvider` and `WebsocketServer.serve` must respect the
following API:

```py
class WebSocket:

    @property
    def path(self) -> str:
        # can be e.g. the URL path
        # or a room identifier
        return "my-roomname"

    def __aiter__(self):
        return self

    async def __anext__(self) -> bytes:
        # async iterator for receiving messages
        # until the connection is closed
        try:
            message = await self.recv()
        except:
            raise StopAsyncIteration()
        return message

    async def send(self, message: bytes):
        # send message
        pass

    async def recv(self) -> bytes:
        # receive message
        return b""
```
