I think that CRDTs could be used for this problem too. They are basically data structures that live in different places (each one has a copy), that can be modified concurrently and that are efficiently kept in sync.
There is pycrdt that is Python bindings to the Rust implementation Yrs.