Skip to main content

A python implementation of Operational Transformation.

Project description

Python-OTType

A python library for Operational Transformation (OT). Basic idea follows the spec at https://github.com/ottypes/docs.

Supported Python versions : CPython 3.9 - 3.12, PyPy 3.9 - 3.10

Installation

pip install python-ottype

Basic usage:

import ottype

assert ottype.apply('asdf', [3, '123', {'d':'f'}]) == 'asd123'

OT Operations

Skip

Object type : int

Skip n characters from the current position is represented as n

assert apply('asdf', [3]) == 'asdf'

Insert

Object type : str

Insert a string s at the current position is represented as s

assert apply('asdf', ['qwer']) == 'qwerasdf'
assert apply('asdf', [2, 'qwer']) == 'asqwerdf'

Delete

Object type : dict

Delete a string s at the current position is represented as {'d': s}

assert apply('asdf', [{'d': 'as'}]) == 'df'
assert apply('asdf', [1, {'d': 'sd'}]) == 'af'

Supported Functions

OT = int | str | dict[str, str]

check(ots: Sequence[OT], *, check_unoptimized: bool = True) -> bool

Check the sequence if it only contains valid OTs. If check_unoptimized is True, only normalized sequence of OTs is accepted.

assert check(['a', 4, 'b'])
assert not check(['a', 'b'])  # is not normalized
assert not check([3])  # is not normalized

apply(doc: str, ots: Sequence[OT], *, check_unoptimized: bool = True) -> str

Apply a sequence of OTs to a string.

assert apply('abcde', [2, 'qq', {'d': 'c'}, 1, 'w']) == 'abqqdwe'

inverse_apply(doc: str, ots: Sequence[OT], *, check_unoptimized: bool = True) -> str

Inversely apply a sequence of OTs to a string.

assert inverse_apply(apply(doc, ots), ots) == doc

normalize(ots: Sequence[OT]) -> Sequence[OT]

Normalize a sequence of OTs : merge consecutive OTs and trim the last skip operation.

assert normalize([1, 2, 'as', 'df', {'d': 'qw'}, {'d': 'er'}, 3]) \
        == [3, 'asdf', {'d': 'qwer'}]

transform(ots1: Sequence[OT], ots2: Sequence[OT]) -> Sequence[OT]

Transform a sequence of OTs with the property:

assert apply(apply(doc, ots1), transform(ots2, ots1, 'left')) \
        == apply(apply(doc, ots2), transform(ots1, ots2, 'right'))

compose(ots1: Sequence[OT], ots2: Sequence[OT]) -> Sequence[OT]

Compose two sequences of OTs with the property:

assert apply(apply(doc, ots1), ots2) == apply(doc, compose(ots1, ots2))

Benchmark (at CPython 3.12.1)

Benchmark : apply operation

len(doc) len(ots) python (Kops/s) cython (Kops/s)
100 5 289.58 ( 1.00x) 663.47 ( 2.29x)
100 10 206.50 ( 1.00x) 513.00 ( 2.48x)
100 20 114.52 ( 1.00x) 298.82 ( 2.61x)
100 50 48.37 ( 1.00x) 127.90 ( 2.64x)
100 100 26.96 ( 1.00x) 71.84 ( 2.66x)
1000 5 412.41 ( 1.00x) 974.43 ( 2.36x)
1000 10 220.19 ( 1.00x) 493.53 ( 2.24x)
1000 20 128.66 ( 1.00x) 317.18 ( 2.47x)
1000 50 37.56 ( 1.00x) 98.56 ( 2.62x)
1000 100 23.43 ( 1.00x) 64.25 ( 2.74x)
10000 5 203.14 ( 1.00x) 322.31 ( 1.59x)
10000 10 142.25 ( 1.00x) 279.79 ( 1.97x)
10000 20 95.63 ( 1.00x) 202.97 ( 2.12x)
10000 50 48.58 ( 1.00x) 122.09 ( 2.51x)
10000 100 21.17 ( 1.00x) 57.59 ( 2.72x)

Benchmark : inverse_apply operation

len(doc) len(ots) python (Kops/s) cython (Kops/s)
100 5 194.12 ( 1.00x) 408.56 ( 2.10x)
100 10 113.27 ( 1.00x) 269.10 ( 2.38x)
100 20 60.99 ( 1.00x) 150.49 ( 2.47x)
100 50 26.35 ( 1.00x) 64.27 ( 2.44x)
100 100 16.62 ( 1.00x) 42.87 ( 2.58x)
1000 5 309.57 ( 1.00x) 565.47 ( 1.83x)
1000 10 153.62 ( 1.00x) 351.55 ( 2.29x)
1000 20 69.48 ( 1.00x) 162.52 ( 2.34x)
1000 50 37.12 ( 1.00x) 91.88 ( 2.48x)
1000 100 17.06 ( 1.00x) 42.51 ( 2.49x)
10000 5 145.11 ( 1.00x) 257.81 ( 1.78x)
10000 10 96.66 ( 1.00x) 198.97 ( 2.06x)
10000 20 65.18 ( 1.00x) 140.90 ( 2.16x)
10000 50 27.40 ( 1.00x) 67.74 ( 2.47x)
10000 100 13.53 ( 1.00x) 32.23 ( 2.38x)

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

python_ottype-24.6.0.tar.gz (11.3 kB view details)

Uploaded Source

Built Distributions

python_ottype-24.6.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (182.2 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

python_ottype-24.6.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (182.1 kB view details)

Uploaded PyPymanylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

python_ottype-24.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (532.9 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

python_ottype-24.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (541.9 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

python_ottype-24.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (503.8 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

python_ottype-24.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (507.9 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

File details

Details for the file python_ottype-24.6.0.tar.gz.

File metadata

  • Download URL: python_ottype-24.6.0.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.12.1

File hashes

Hashes for python_ottype-24.6.0.tar.gz
Algorithm Hash digest
SHA256 1b785fdef26d7d3ac163a039ba612f0be0e3b8d142da172e0ca20e4a02051355
MD5 dac4f9a3031d281362b0a81d4791729d
BLAKE2b-256 cae08281f066d1af41c98c844100d11d84c43c89aede5bea2cfea51be96fc502

See more details on using hashes here.

File details

Details for the file python_ottype-24.6.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for python_ottype-24.6.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 54112bac3ef09518591c1eb6abb7df23d51977809917ce8635561c0b6ca99fca
MD5 37195f524e056338041f2675a04e363b
BLAKE2b-256 884456e1fa6652e6195aee8778c955012a4c3c0e2266e8eb40118367c2d27ae6

See more details on using hashes here.

File details

Details for the file python_ottype-24.6.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for python_ottype-24.6.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5c16b863cdc6ddbe246f96bcf405579e39454920a8a69f59b0db54e9e0a73b61
MD5 6e8900581eaf6d01562b3d86fa8659f4
BLAKE2b-256 93d0e690fa9290063776c37006bdd431def35f1cd10a9e4c083c752bd0a534f3

See more details on using hashes here.

File details

Details for the file python_ottype-24.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for python_ottype-24.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 54f394b2e27c7add1d23a7a1a719d210af46b6731724fa1b0a2db2f00009fc82
MD5 6d5e7477ef2120ad4041503ced577d1d
BLAKE2b-256 1d298028fc9d4590bf544f9a6a1e824df2f94b4d774b80aaa719dee861e752f1

See more details on using hashes here.

File details

Details for the file python_ottype-24.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for python_ottype-24.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ad1f4b5f06d5f6b887aaf5734b89eaffbad50bef81ff9e8a5acc35346df27b5f
MD5 41200e4ee35692ceabfd5e0fb944a3d5
BLAKE2b-256 83d29d591b6236a3527f764cd0e775734712c4970767a8e40329f928e6ea899a

See more details on using hashes here.

File details

Details for the file python_ottype-24.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for python_ottype-24.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f351bab11ce2cef7e566a0d5c3791840925eddeb2444377a7dfcd2ccad2d4b40
MD5 b5a575f2b5d4c279d5698b24716cf636
BLAKE2b-256 0822e4cdcb2f99abd2551ad281d78fc6b83ea4581a00591ed95b01474da13e67

See more details on using hashes here.

File details

Details for the file python_ottype-24.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for python_ottype-24.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 610b54586153c07c7d56d4c670198939ae94de82e99f93397688f74a3eb8b782
MD5 7f56f500556509c5520eb6e7fee752ec
BLAKE2b-256 627e88c758477db7ad91932bd0b104ce8dbba96daf4382a02f5f898b26f8fca2

See more details on using hashes here.

Supported by

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