Skip to main content

babeldb para Python

Binding nativo e embarcado do babeldb, no estilo de sqlite3, lmdb, polars ou lancedb: o banco roda dentro do processo Python, sem servidor. Por baixo é a receita da seção "Usar em outro projeto (Rust)" do README principal: fjall + WAL write-through (Db::open_fjall_wal), escritas por um group committer, leituras direto no banco. Módulo nativo babeldb._native (PyO3, abi3), pacote Python babeldb com tipos (py.typed + .pyi).

Instalação

A partir do wheel já construído

pip install babeldb

O wheel é abi3: o mesmo arquivo serve para CPython 3.8 ou mais novo (Windows x64).

Construir o wheel

Requisitos: Rust (o rust-toolchain.toml da raiz fixa a versão; o rustup a instala sozinho), Python 3.8+ e maturin. De dentro de bindings/python:

python -m venv .venv
.venv\Scripts\python -m pip install maturin pytest
.venv\Scripts\maturin build --release -i .venv\Scripts\python.exe
.venv\Scripts\python -m pip install --force-reinstall target\wheels\babeldb-0.1.1-cp38-abi3-win_amd64.whl

O wheel sai em target\wheels\. Para desenvolver, .venv\Scripts\maturin develop --release compila e instala direto no venv.

Exemplo rápido

import babeldb

with babeldb.open("dados/app") as db:              # cria o diretório se não existir
    rev = db.put("usuario:1", b'{"nome": "Ana"}')   # durável quando retorna
    db.get("usuario:1")                              # b'{"nome": "Ana"}'
    db.put("usuario:1", b'{"nome": "Bia"}', if_revision=rev)  # compare-and-set
    db.put("usuario:2", "x", if_absent=True)         # só cria se não existir
    db.scan("usuario:")                              # [(b'usuario:1', ...), (b'usuario:2', b'x')]
    db.keys("usuario:", reverse=True, limit=1)       # [b'usuario:2']
    db.batch([("put", "a", "1"), ("delete", "usuario:2")])  # atômico, um commit
    db.delete("a")                                   # True

    # Chat: chave = canal ‖ id da mensagem (big-endian), mensagens de um canal em ordem.
    canal = 42
    db.put(babeldb.message_key(canal, 1001), "oi")
    ultimas = db.scan(babeldb.channel_prefix(canal), reverse=True, limit=50)
    canal, msg_id = babeldb.parse_message_key(ultimas[0][0])

Referência da API

Chaves e valores aceitam bytes, bytearray, memoryview ou str (str vira UTF-8); valores voltam sempre como bytes. Chave: 1 a 4096 bytes. help(babeldb.Db) mostra a mesma referência.

Chamada Retorno O que faz
babeldb.open(path, durability="immediate") Db Abre (ou cria) o banco no diretório path. babeldb.Db(path, durability=...) é o mesmo.
db.put(key, value, *, if_absent=False, if_revision=None) int Grava; devolve a nova revisão. if_absent=True: só se a chave não existir. if_revision=r: só se a revisão atual for r (compare-and-set). Expectativa falhou: ConflictError.
db.get(key) bytes | None Valor atual, ou None.
db.delete(key, *, if_revision=None) bool Apaga; False se a chave não existia. Com if_revision=r, ConflictError se a revisão atual não for r (inclusive chave inexistente).
db.scan(prefix=None, *, start=None, end=None, reverse=False, limit=0) list[tuple[bytes, bytes]] Registros em ordem de bytes da chave. prefix: chaves que começam com ele. start inclusivo, end exclusivo; prefix não combina com start/end. reverse=True: decrescente. limit=0: sem limite (com reverse, os últimos N).
db.keys(...) list[bytes] Os mesmos argumentos de scan, só as chaves.
db.batch(ops) list[int | None] ops: iterável de ("put", k, v) / ("delete", k). Atômico e durável; ver abaixo.
db.sync() None Espera tudo o que foi confirmado antes ficar durável (modo buffered; no immediate já está).
db.close() None Espera as chamadas em andamento, torna tudo durável e libera o diretório. Idempotente.
db.closed, db.path, db.durability Propriedades só de leitura.
with babeldb.open(p) as db: Fecha ao sair do bloco (também com exceção).
babeldb.message_key(channel, message_id) bytes 16 bytes: channel (u64 big-endian) ‖ message_id (u64 big-endian).
babeldb.parse_message_key(key) tuple[int, int] | None Inverso de message_key; None se a chave não tiver 16 bytes.
babeldb.channel_prefix(channel) bytes Os 8 bytes iniciais das chaves do canal (para scan).

Revisões: um int (u64) que cresce a cada escrita do banco (não por chave). Guarde a de put para usar em if_revision.

batch (tudo ou nada): as operações são aplicadas em ordem (uma operação vê o efeito das anteriores na mesma chave) num único commit atômico e durável (Db::write_batch do núcleo). Se qualquer operação for malformada ou inválida (por exemplo, chave vazia), nada é escrito e o erro sobe. Retorno por operação: put → nova revisão; delete → revisão do registro apagado, ou None se a chave não existia. As operações do batch não têm condições (último escritor vence) e o batch é durável ao retornar nos dois modos de durabilidade. (O primitivo do group commit, write_batch_each, aplicaria as operações válidas e pularia as inválidas; por isso batch não usa ele.)

Exceções (todas derivam de babeldb.BabelError):

Exceção Quando
ConflictError if_absent=True com a chave existente; if_revision diferente da revisão atual. Nada foi escrito.
ClosedError Qualquer método (exceto close) depois de close(), e with num Db fechado.
InvalidArgumentError Chave vazia ou com mais de 4096 bytes; valor grande demais; durability desconhecida; prefix junto com start/end; limit negativo; if_absent junto com if_revision; operação de batch malformada.
BabelError Erros de E/S e do armazenamento; abrir um diretório que já está aberto neste processo.

Tipos errados de chave/valor levantam TypeError; inteiros fora de u64 (revisões, helpers), OverflowError.

Modos de durabilidade

  • "immediate" (padrão): put, delete e batch são duráveis quando a chamada retorna. Escritas simultâneas de várias threads entram no mesmo commit (group commit): N threads pagam uma escrita no WAL, não N.
  • "buffered": put e delete retornam quando a escrita está commitada e visível (leituras já a veem), mas ainda não durável. Ela fica durável em até ~100 ms, antes de 64 MiB pendentes, em sync() e em close() (WriteDurability::Buffered { flush_interval: 100 ms, max_pending_bytes: 64 MiB }). Num crash (queda de energia, processo morto) podem se perder as escritas confirmadas nos últimos ~100 ms. batch continua durável ao retornar.

O WAL grava em modo write-through (FILE_FLAG_WRITE_THROUGH): a garantia padrão do PostgreSQL no Windows (ver docs/ e o módulo store::wal do núcleo). Ao sair do interpretador, os bancos ainda abertos são fechados (atexit), o que torna durável o que estiver pendente; um processo morto à força não passa por isso.

Threads

  • Um Db pode ser usado por muitas threads ao mesmo tempo: compartilhe a mesma instância.
  • Toda chamada ao banco roda sem o GIL (py.detach, o antigo allow_threads do PyO3): leituras rodam em paralelo e as escritas de threads diferentes compartilham commits.
  • Um Db por diretório por processo: abrir de novo um diretório já aberto no mesmo processo levanta BabelError ("already open") na hora, sem travar. Outro processo que abra o mesmo diretório recebe o erro da trava do fjall.
  • close() espera as chamadas em andamento terminarem; as chamadas seguintes levantam ClosedError. Um Db coletado pelo garbage collector sem close() é fechado ao ser destruído.
  • Com asyncio, as chamadas bloqueiam: use await asyncio.to_thread(db.get, chave).

Limites

  • Testado só no Windows 11 x64 com CPython 3.12. O wheel é abi3 (CPython 3.8+), mas as outras versões não foram testadas; Linux e macOS ainda não foram compilados.
  • Chave de 1 a 4096 bytes. Chaves e valores são copiados a cada chamada: valores enormes custam memória (o limite do núcleo é 4 GiB por valor).
  • scan e keys devolvem a lista inteira (sem cursor): pagine com start/end + limit.
  • Transações: só if_absent/if_revision (por operação) e batch (atômico, sem condições).
  • Configuração fixa: Config::adaptive() + WalConfig::default(). O banco ocupa o diretório path e o WAL é o arquivo <path>.wal ao lado dele (pré-alocado, 16 MiB).
  • PyPy e o Python sem GIL (3.13t) não são suportados.

Testes

De dentro de bindings/python, com o wheel instalado no venv (ver "Construir o wheel"):

.venv\Scripts\python -m pytest -q

O pytest roda contra o pacote instalado: o código-fonte fica em python/babeldb, fora do sys.path, então import babeldb carrega o wheel.

Benchmark

.venv\Scripts\python bench.py                        # durability="immediate"
.venv\Scripts\python bench.py --durability buffered

Imprime puts/s e gets/s com valores de 512 B (aleatórios, incompressíveis), 1 e 8 threads.

Medido nesta máquina de desenvolvimento (Windows 11, NVMe; CPython 3.12, wheel --release), 20 000 operações por fase, um banco novo por fase:

durability threads puts/s gets/s
immediate 1 8 472 320 000
immediate 8 34 834 129 870
buffered 1 29 452 299 472
buffered 8 113 013 151 644

Com 8 threads as escritas ganham com o group commit (várias escritas por commit). As leituras com 8 threads rendem menos que com 1: cada get leva poucos microssegundos e o laço do benchmark roda em Python, então a troca do GIL entre as threads (que toda chamada solta) custa mais do que o paralelismo ganha. Leituras paralelas compensam quando cada chamada faz mais trabalho (valores grandes, scan).

Metadata

Release files for babeldb 0.1.1

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

Source distribution (sdist)

Source distribution for babeldb 0.1.1
File Size Uploaded
babeldb-0.1.1.tar.gz 758.1 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for babeldb 0.1.1
File
babeldb-0.1.1-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details
babeldb-0.1.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details
babeldb-0.1.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details
babeldb-0.1.1-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details
babeldb-0.1.1-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details

Total release size: 23.9 MB

Release files / babeldb-0.1.1.tar.gz

Download URL babeldb-0.1.1.tar.gz
Size 758.1 kB
Tags Source
SHA-256 checksum
How to use checksums
8b9bd31f2b1f9a2cd2af544085291c5b3ebeeb73a9475b97767440c2bcaba094
BLAKE2b-256 checksum
How to use checksums
3020d446d38685e47b616b5be5538262b817f00faea05e28abda5c067b887baf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / babeldb-0.1.1-cp38-abi3-win_amd64.whl

Download URL babeldb-0.1.1-cp38-abi3-win_amd64.whl
Size 1.3 MB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
056f5348d4007ed4e80c2c5aabb7528ea27e3fc66d89bd9ce57a1dfefd43fef3
BLAKE2b-256 checksum
How to use checksums
ed948f21782532537b197d43c0e99aab6c4ca274f71a5543ff3515d482375e59
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / babeldb-0.1.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL babeldb-0.1.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 9.8 MB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
59fd8e8fb5269015f71bd42f4e8ca3c3109deb602901789f786ab11566df6810
BLAKE2b-256 checksum
How to use checksums
dd097765c7bc91a0bbbd6972420c15e641e4eb838d2d3fa7b30d6e0c21758cde
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / babeldb-0.1.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL babeldb-0.1.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 9.0 MB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
92c9395de0d2b2dfdd6cbe68f290ae92f300062c07ece5e1149700b698b7086a
BLAKE2b-256 checksum
How to use checksums
53044f325624ade09132d53f9e65c00faa86b50c5a0b4894b146a03ec5fbd9cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / babeldb-0.1.1-cp38-abi3-macosx_11_0_arm64.whl

Download URL babeldb-0.1.1-cp38-abi3-macosx_11_0_arm64.whl
Size 1.5 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
f33b6542553a0aac96c9738f3b12eba83ad64e1932b167d6ba32473a280165c0
BLAKE2b-256 checksum
How to use checksums
0172161d2b259213d9654cbe339ccb29632cd81f7751534b0af452a953835372
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / babeldb-0.1.1-cp38-abi3-macosx_10_12_x86_64.whl

Download URL babeldb-0.1.1-cp38-abi3-macosx_10_12_x86_64.whl
Size 1.6 MB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
dcf209bc617b0715d7aac88b5c01def1f09b7213e633451fe113339e567eef81
BLAKE2b-256 checksum
How to use checksums
9e91902d642f48d7bd8d75cbd6bedf91262c8284ada011767ca865731f03ea29
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

6 release files

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