Skip to main content

bothy (Python)

Serverless, local-first sync engine that uses your own Google Drive as the transport.

⚠️ Early release. The API may still change between minor versions.

Bothy lets programs sync structured data between devices without running a server. The devices can be desktops, phones (through the Flutter package) or embedded Linux boards such as a Raspberry Pi. Each device keeps a local SQLite database and works offline; devices exchange immutable files through the user's own Google Drive or a shared folder.

Concurrent edits to different fields merge. Optionally, everything stored on Drive is end-to-end encrypted.

A typical embedded setup: a robot gets missions from a phone app and sends logs back, with no server or MQTT broker in between.

import bothy

db = bothy.Database.open("robot.db", app_id="com.example.robot",
                         remote=bothy.FolderRemote("/mnt/shared/robot"))
db.init_or_join()

missions = db.collection("missions")
missions.put("m1", {"goal": "dock", "speed": 0.5})
missions.patch("m1", {"state": "accepted"})
print(missions.get("m1"))

db.start_auto_sync()                      # or db.sync() when you choose
for change in db.changes(timeout=30):     # local and remote changes
    print(change.collection, change.id, "from another device" if change.remote else "")
db.close()

The API is synchronous and thread-safe, and calls release the GIL. Wheels are abi3, for CPython 3.9 or newer on Linux (x86_64, aarch64, armv7), macOS and Windows.

Google Drive

Bothy never signs in by itself. Use OAuth clients of your own Google Cloud project; every client of one project sees the same Drive files.

import bothy, bothy.auth

# A board without a browser: the device flow (a "TVs and Limited Input devices" client).
grant = bothy.auth.device_login("client_tv.json")   # prints a URL and a code to enter on a phone
grant.save("token.json")                            # readable only by you

tokens = bothy.auth.TokenProvider("client_tv.json", bothy.auth.Grant.load("token.json"))
db = bothy.Database.open("robot.db", app_id="com.example.robot",
                         remote=bothy.DriveRemote.folder("robot", tokens))
  • Remote type: the device flow only grants the drive.file scope, so headless devices use DriveRemote.folder (a visible Bothy/<name> folder).
  • Desktops can use bothy.auth.loopback_login with a "Desktop app" client, and DriveRemote.appdata (the hidden app folder).
  • Your own tokens: any callable (force_refresh: bool) -> str works as tokens.

Encryption

db = bothy.Database.open(..., encrypt=True, password=pw)   # the device that creates it
db = bothy.Database.open(..., password=pw)                 # devices that join
key = db.export_key()                                      # keep it to skip the password
db = bothy.Database.open(..., key=key)
  • Wrong password: raises bothy.WrongPasswordError.
  • Locked database: opened without a secret, an encrypted database is locked. Local reads and writes work; sync() raises bothy.KeyRequiredError until unlock().
  • Embedded boards: keep the key instead of the password. Unlocking with a password costs 64 MiB of memory once; syncing with the key does not. On a 4-core Cortex-A53 board, syncing two days of per-minute telemetry with the key peaked at 28 MiB of resident memory.

A complete example, a robot agent that takes missions from the Flutter demo and reports telemetry (with an optional ROS 2 bridge), is in examples/pi-agent.

Errors

Every engine error is a bothy.BothyError. Each error kind has its own subclass, for example OfflineError, AuthRequiredError, WrongPasswordError, KeyRequiredError and InvalidInputError.

Building from source

pip install maturin
maturin develop            # needs a Rust toolchain
python -m unittest discover -s tests

Metadata

Release files for bothy 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bothy 0.3.0
File Size Uploaded Provenance
bothy-0.3.0.tar.gz 168.2 kB Without provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for bothy 0.3.0
File
bothy-0.3.0-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
bothy-0.3.0-cp39-abi3-manylinux_2_28_armv7l.whl CPython 3.9 abi3 Linux glibc 2.28+ ARMv7l Details
bothy-0.3.0-cp39-abi3-manylinux_2_28_aarch64.whl CPython 3.9 abi3 Linux glibc 2.28+ ARM64 Details
bothy-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
bothy-0.3.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl CPython 3.9 abi3 macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64, macOS 11.0+ ARM64 Details

Total release size: 30.9 MB

Release files / bothy-0.3.0.tar.gz

Download URL bothy-0.3.0.tar.gz
Size 168.2 kB
Tags Source
SHA-256 checksum
How to use checksums
471bcd37ff15708fd1af3f6dd968e2c97b3c250095015233d3505f4153e511b9
BLAKE2b-256 checksum
How to use checksums
fe465997d8088c6ddd3df36acecaa390c1468900f832c554ca44765419662a3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / bothy-0.3.0-cp39-abi3-win_amd64.whl

Download URL bothy-0.3.0-cp39-abi3-win_amd64.whl
Size 4.6 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
393805ceb97f3e490797e99b3059c15976ef9e208a8ce3072850db1644423101
BLAKE2b-256 checksum
How to use checksums
a36754821f2331f593ec67188dedb0eb93363fe9e1571309dd3d9d4bcaf4ff2a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / bothy-0.3.0-cp39-abi3-manylinux_2_28_armv7l.whl

Download URL bothy-0.3.0-cp39-abi3-manylinux_2_28_armv7l.whl
Size 5.6 MB
Tags CPython 3.9 Linux glibc 2.28+ ARMv7l abi3
SHA-256 checksum
How to use checksums
3f86be5a44a06d5f8f9b40d79fd981ed75e22aef54bafbe63d838e90971201fd
BLAKE2b-256 checksum
How to use checksums
eae04c9c7d0b21d723af3ad9cd73a1b61128d2987ac0206ac160065a4b84498d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / bothy-0.3.0-cp39-abi3-manylinux_2_28_aarch64.whl

Download URL bothy-0.3.0-cp39-abi3-manylinux_2_28_aarch64.whl
Size 5.9 MB
Tags CPython 3.9 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
35369b00015de33a7cae6575f0b73d19861c9fb608667cc938ed9c7572a6c726
BLAKE2b-256 checksum
How to use checksums
bd794dc05161e2b4b12a7510dc9c12a3917e42c58b919092d16484fbd928eb26
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / bothy-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL bothy-0.3.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 6.1 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
d38834db5db1ec685daf5d3ddcffbd687b35ecd81a5fb80c2adafd868c739da8
BLAKE2b-256 checksum
How to use checksums
8581b561735f4bc67404718707e84322cf7a0796db837f5eb4651654f88a49a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release files / bothy-0.3.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL bothy-0.3.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 8.5 MB
Tags CPython 3.9 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c89e69e608729a9fa9c22946f8afc0ff1d046c80e41af80165eb262c4b45e7ea
BLAKE2b-256 checksum
How to use checksums
5d0354dec342f765e01fa43289a10ca202c9265e5b09f5d1c738ebbbe1b9f78c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Security for bothy 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page