Package: y-py
YpyYpy is a Python binding for Y-CRDT. It provides distributed data types that enable real-time collaboration between devices. Ypy can sync data with any other platform that has a Y-CRDT binding, allowing for seamless cross-domain communication. The library is a thin wrapper around Yrs, taking advantage of the safety and performance of Rust.🧪 Project is still experimental. Expect the API to change before a version 1.0 stable release.Installationpip install y-pyGetting StartedYpy provides many of the same shared data types asYjs. All objects are shared within aYDocand get modified within a transaction block.importy_pyasYd1=Y.YDoc()# Create a new YText object in the YDoctext=d1.get_text('test')# Start a transaction in order to update the textwithd1.begin_transaction()astxn:# Add text contentstext.extend(txn,"hello world!")# Create another documentd2=Y.YDoc()# Share state with the original documentstate_vector=Y.encode_state_vector(d2)diff=Y.encode_state_as_update(d1,state_vector)Y.apply_update(d2,diff)value=str(d2.get_text('test'))assertvalue=="hello world!"Development SetupInstallRustandPythonInstallmaturinin order to build Ypy:pip install maturinCreate a development build of the library:maturin developTestsAll tests are located in/tests. To run the tests, installpytestand run the command line tool from the project root:pip install pytest
pytestUsing HatchIf you are usinghatch, there is atestenvironment matrix defined inpyproject.tomlthat will run commands in virtual environments forpy37throughpy312.hatch run test:maturin develop
hatch run test:pytestBuild YpyBuild the library as a wheel and store them intarget/wheels:maturin buildYpy in WASM (Pyodide)As a Rust-based library, Ypy cannot build "pure Python" wheels. CI processes build and upload a number of wheels to PyPI, but PyPI does not support hostingemscripten/wasm32wheels necessary to import in Pyodide (seehttps://github.com/pypi/warehouse/issues/10416for more info and updates). For now, Ypy will buildemscriptenwheels and attach the binaries as assets in the appropriateReleasesentry. Unfortunately, trying to install directly from the Github download link will result in a CORS error, so you'll need to use a proxy to pull in the binary and write / install from emscripten file system or host the binary somewhere that is CORS accessible for your application.You can try out Ypy in Pyodide using theterminal emulator at pyodide.org:Welcome to the Pyodide terminal emulator 🐍
Python 3.10.2 (main, Sep 15 2022 23:28:12) on WebAssembly/Emscripten
Type "help", "copyright", "credits" or "license" for more information.
>>> wheel_url = 'https://github.com/y-crdt/ypy/releases/download/v0.5.5/y_py-0.5.5-cp310-cp310-emscripten_3_1_14_wasm32.whl'
>>> wheel_name = wheel_url.split('/')[-1]
>>> wheel_name
'y_py-0.5.5-cp310-cp310-emscripten_3_1_14_wasm32.whl'
>>> 
>>> proxy_url = f'https://api.allorigins.win/raw?url={wheel_url}'
>>> proxy_url
'https://api.allorigins.win/raw?url=https://github.com/y-crdt/ypy/releases/download/v0.5.5/y_py-0.5.5-cp310-cp310-emscripten_3_1_14_wasm32.whl'
>>> 
>>> import pyodide
>>> resp = await pyodide.http.pyfetch(proxy_url)
>>> resp.status
200
>>> 
>>> content = await resp.bytes()
>>> len(content)
360133
>>> content[:50]
b'PK\x03\x04\x14\x00\x00\x00\x08\x00\xae\xb2}U\x92l\xa7E\xe6\x04\x00\x00u\t\x00\x00\x1d\x00\x00\x00y_py-0.5.5.dist-info'
>>>
>>> with open(wheel_name, 'wb') as f:
...   f.write(content)
... 
360133
>>> 
>>> import micropip
>>> await micropip.install(f'emfs:./{wheel_name}')
>>> 
>>> import y_py as Y
>>> Y
<module 'y_py' from '/lib/python3.10/site-packages/y_py/__init__.py'>
>>> 
>>> d1 = Y.YDoc()
>>> text = d1.get_text('test')
>>> with d1.begin_transaction() as txn:
    text.extend(txn, "hello world!")
... 
>>> d2 = Y.YDoc()
>>> state_vector = Y.encode_state_vector(d2)
>>> diff = Y.encode_state_as_update(d1, state_vector)
>>> Y.apply_update(d2, diff)
>>> d2.get_text('test')
YText(hello world!)