Skip to main content

Python bindings for the Y-CRDT built from yrs (Rust)

Project description

PyPI version

Ypy

Ypy 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.

We are looking for a maintainer 👀

Installation

pip install y-py

Getting Started

Ypy provides many of the same shared data types as Yjs. All objects are shared within a YDoc and get modified within a transaction block.

import y_py as Y

d1 = Y.YDoc()
# Create a new YText object in the YDoc
text = d1.get_text('test')
# Start a transaction in order to update the text
with d1.begin_transaction() as txn:
    # Add text contents
    text.extend(txn, "hello world!")

# Create another document
d2 = Y.YDoc()
# Share state with the original document
state_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'))

assert value == "hello world!"

Development Setup

  1. Install Rust and Python
  2. Install maturin in order to build Ypy: pip install maturin
  3. Create a development build of the library: maturin develop

Tests

All tests are located in /tests. To run the tests, install pytest and run the command line tool from the project root:

pip install pytest
pytest

Using Hatch

If you are using hatch, there is a test environment matrix defined in pyproject.toml that will run commands in virtual environments for py37 through py312.

hatch run test:maturin develop
hatch run test:pytest

Build Ypy

Build the library as a wheel and store them in target/wheels:

maturin build

Ypy 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 hosting emscripten / wasm32 wheels necessary to import in Pyodide (see https://github.com/pypi/warehouse/issues/10416 for more info and updates). For now, Ypy will build emscripten wheels and attach the binaries as assets in the appropriate Releases entry. 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 the terminal 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!)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

y_py_dart-0.6.3a21.tar.gz (59.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (885.7 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (937.9 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ s390x

y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (1.0 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ppc64le

y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (887.0 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARMv7l

y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (874.2 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

y_py_dart-0.6.3a21-pp39-pypy39_pp73-macosx_10_12_x86_64.whl (815.5 kB view details)

Uploaded PyPymacOS 10.12+ x86-64

y_py_dart-0.6.3a21-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (1.6 MB view details)

Uploaded PyPymacOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (887.5 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64

y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl (936.4 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ s390x

y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (1.0 MB view details)

Uploaded PyPymanylinux: glibc 2.17+ ppc64le

y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (886.6 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARMv7l

y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (876.5 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ ARM64

y_py_dart-0.6.3a21-pp38-pypy38_pp73-macosx_10_12_x86_64.whl (818.2 kB view details)

Uploaded PyPymacOS 10.12+ x86-64

y_py_dart-0.6.3a21-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (1.6 MB view details)

Uploaded PyPymacOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (886.0 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl (937.7 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ s390x

y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (1.0 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ppc64le

y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (886.7 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARMv7l

y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (874.6 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

y_py_dart-0.6.3a21-cp38-abi3-macosx_10_12_x86_64.whl (817.4 kB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

y_py_dart-0.6.3a21-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (1.6 MB view details)

Uploaded CPython 3.8+macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

File details

Details for the file y_py_dart-0.6.3a21.tar.gz.

File metadata

  • Download URL: y_py_dart-0.6.3a21.tar.gz
  • Upload date:
  • Size: 59.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for y_py_dart-0.6.3a21.tar.gz
Algorithm Hash digest
SHA256 c02d3b4cde50e9a3f25f088b7aeaa5b38196a5e3ee7644c0c93aa962e5b268aa
MD5 4a72b019023811555366d3c9efa03103
BLAKE2b-256 15464b828c7703600f8395915bcfcb3c4f10eba63b5e15387f6750a37517ba1d

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 855827ced44595a35fb5ea56a2a256e089b2708ab426149efa5ddd4b73abb482
MD5 4fc2ad7d43757f94e2c51a7030491889
BLAKE2b-256 d08baec8698df8246e08c8a34ef282ff4b3898abc313c33611703b7a4e4a9de8

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 2f2951d7d938298267eae237e2129403312654146c4bf0fd850a94d25d1db662
MD5 cfb055ebaa969d277134553c02e493d1
BLAKE2b-256 cc43cc4558605e2c413ac31a042c694d502da9f6c33f24f4e807e9c1504eba46

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 82e9e5ad205c54c0e714fdd4a972aa7460e5ed8ef0aefeeb2129ac8709bf9fc1
MD5 57ce5850b253f43a30fc26198e796607
BLAKE2b-256 7fb54e4b431b6b91403b99d2443a46f118385ae94dbc7ae6d00c3358a498a9b6

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 d99207a50cc711be042a7bb58b1ff6d82325c0b73d945ec3bcba1850a008bb42
MD5 836a9cdde9862b27a41de3bfccf2fde2
BLAKE2b-256 c382e24f54f240ca1db3b642a4b0398dd70a2dd769b5381da43811958f1d643b

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a99659e33b26e0b24fa7113c459bf7d3b16210f336c5e6cf9e3e46e41a1463a3
MD5 3387a3bf9ddb812289ff0d645d17a319
BLAKE2b-256 2578ce0fe7e459ffe3551716c37e3c0e17222bcdaf7a36165590417b285741b9

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp39-pypy39_pp73-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp39-pypy39_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 da5c410ffd8fa7bd07e3af03abb5bcb79562540b04daf9a01a8e0bac23d8e923
MD5 12858c36e1504e05d4b9f3f86a0cb173
BLAKE2b-256 591d33a5631472062c41b7f0956c91344c254292ecb9582e83285bf0a62c98f0

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 b12dfecf4873976aec8e01fdb73e571d6170dbb131e5afbd9a046fe728d274bf
MD5 600509911f5212bc31d832c6c5e52298
BLAKE2b-256 8e3f1804130e46ad43a4ffa94c4cde00a6500f0fcce4460d786cec59f26a35bb

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 47d60a00b219f039b366a40b2db7a8df032db35942f56ddb3ea5f0b8075d92bd
MD5 626abd61c36cb52b9c90f8e03a5083d7
BLAKE2b-256 d4a28b49b7717fc4962174499616ac5854ab879bca223806d0ead8ed63724dc4

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 166e657cd02b28fbbc009036957996e6b387d2582fc1dce3cd99e71a65c0d853
MD5 329b728af62eb6ab354d121326322b5e
BLAKE2b-256 1e6f5f083ae5ac938e3ef7aebe61add43c23faa0af0982c32c546ca3e2100914

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 329cf7b9a30d1ee260ec026412c8164f73941eadd0591c78818dd701b36a3147
MD5 2f4042961f75ae355319c63149d47627
BLAKE2b-256 975404dda4e47f510c6a86c34c52d7dfe1a731bb465c44ec70efe50db34cb611

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 758332fb5a9d12b6ba36dfa95397ece2f2e1d7e0f26b7c50787bd6703a2974bf
MD5 fb6d7339ded303a06f7f91298899103a
BLAKE2b-256 f7351c12464192b879a2ffbbaaa22de9056dfc8764bad3d07b72e75c6b5ae84c

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d19448c693deb2f6b1c0350d5d1b99d2b1f9af6e0d1a569e805f194146cef539
MD5 bbf51a96b5358f5f67cdbc07145e05bc
BLAKE2b-256 e4997d3cde5be3bd28adde64c1628412b9a916ba3501af716a822a24c7be0bf0

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp38-pypy38_pp73-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp38-pypy38_pp73-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a2a0edfb96de876c3d7f5334fb6ae3fdbab364cfa31c2693b3c0aacf08ac40f0
MD5 1243b3054b91e86e77a3251f54fd17cb
BLAKE2b-256 86ac755cd9fabf075b6877afbe51eb68dc44923a4a6df6c57dcf9915e3c24b25

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 3349d3173dff6bfcebd22a9b2f636e469b8d7c38b70a65b3d67f9b683235ca62
MD5 a55929c6040f510e31056b331e77f2de
BLAKE2b-256 cb07ca6a02732c4ac567716ce4d39a31d6266b7c44ef4547c7dc6e6087064806

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ef4abbc2c3576676868f1da70f55bb782d4e759fd77e815e19cea07ebaa168a7
MD5 b717b3d61eed87b68d46233805748f4f
BLAKE2b-256 acb24df1cb131f016bde8a2bfb139fad4ffb0a292b78d15c0dc2a3eddf3d2893

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 a7e5721af0eeede9dad41578bf2f6b517070874a614d9a9d66fb85811e3e27bf
MD5 89b15e2a58d92804d075564edf9de847
BLAKE2b-256 642e2924d8b249d3f77e0706ae73e49ec4f53b2efb853e450d639a069e0f0b4d

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 59ffc435dca341c76bb81c413da30b687d0bad6940bc7aefc28d6efc87435646
MD5 5460c4b6c9aba02ac5aa900e44dd4202
BLAKE2b-256 8d6a29e60cc0e1ce1ba4521dca84d116b31f8122feb3a194b5ce2bdbe8d184b1

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 2c9e468253dba1b5086f9ed1cc8e5a74c6ed93057f2fe685dfd883f279ea6b36
MD5 6edef640c5a16f88ff041732d9e3a724
BLAKE2b-256 35e1c4dae32ffefec5e60c7d80a756b2525014c1ffc2ea16b76e44d2bd1f0ec9

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3fdd6f2497b6f7e7bcf7a21a788554cc24ee217ce191b06387c237166411cbee
MD5 30778364c3e14af9d0dda37e5abab0de
BLAKE2b-256 b7ce15e86ba0a82b19ef19ed9e3343ea3f9bdc4a49bed1e18d991195065ef839

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c47c96e34327c135213abb5ed7d8f0d3c19e54356315ab5d43570f130b949603
MD5 0ef094195fa07f231aa126fbea20ddad
BLAKE2b-256 49cc884a51d6488b412f4f6522b44a6c9bdefc9b538efae70f4269686d1b56e8

See more details on using hashes here.

File details

Details for the file y_py_dart-0.6.3a21-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for y_py_dart-0.6.3a21-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 e2781e01c453b9ee24ebe7a8b8340bb7007bcdeb4ad364a3737766ccb0b2780e
MD5 59b06ce838402956a383feb68085638c
BLAKE2b-256 90964b4efb6b96b1342c84e2230447b2fbc236935a43fabe525d6224535760ce

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page