Quickstart: SQLite/Python

Last updated 2 November 2026In Getting started

View .md

From sign-in to a first replicated commit with Python’s sqlite3.

Run it from your laptop or any machine with Python 3.11 or later and internet access, with nothing to allowlist, on Linux (x64 or arm64) or macOS on Apple silicon. The Python must be one that can load SQLite extensions; the install step below sets one up with uv (see Requirements).

Sign in

Sign in at tonbo.dev with GitHub or Google. A new account asks you to choose a username: it names your personal account, which holds your databases, streams and keys, and appears in the console’s addresses. You can change it once every 90 days.

Create a database

Create a database named notes. It goes to the default region, us-east-1, unless you choose another (see Regions): pick the one nearest where your program runs. With the CLI, name it with --region, as in tonbo database create notes --region ap-southeast-1.

  1. Open Databases in the console.
  2. Choose Create database and name it notes.

The database is creating for a moment, then active. Node.js code opens it by name, and Python code by its URL, which tonbo database show notes and the console show (see Regions and URLs).

Create an API key

Give the program its own key, narrowed to notes: it reads and writes only that database, and may name one that does not exist yet. A key that acts as you and is not narrowed reaches every database and stream you can in its account (see What a key can reach).

  1. In the console, choose API keys in the sidebar.
  2. Choose New API key and narrow it to the database notes.
  3. Copy the key. It starts with tbo_ and is shown once.

On this machine, after tonbo login, a Node.js program can also open its databases with no key at all: open() falls back to your login (see Connect). Python does not, and the narrowed key is what any program uses anywhere else.

Install the package

uv venv --managed-python --python 3.13
source .venv/bin/activate
uv pip install sqlite-ursula==0.11.3.dev0
python -m sqlite_ursula

This uses uv: install it first if you have not. It makes a virtual environment on a Python that uv manages, installs the package into it, and checks that this Python can run the package: the last line prints result: ok. Python uses the pre-release sqlite-ursula 0.11.3.dev0 until 0.11.3 is published to PyPI.

The package runs inside Python’s own sqlite3, so not every Python can run it: the python.org macOS installer, Apple’s /usr/bin/python3 and Debian’s or Ubuntu’s system Python cannot (see Requirements). In a Python that can, install it with pip as pip install sqlite-ursula==0.11.3.dev0, or add it to a uv project with uv add sqlite-ursula==0.11.3.dev0: keep the exact version, which is what lets both install a pre-release.

Open and commit

Python opens a database by its URL. Put the URL of notes in NOTES_URL (the console shows it too, on the database’s page):

export NOTES_URL=$(tonbo database show notes --json | jq -r .url)

Save this as app.py. It sends the API key itself as its token:

app.py
import os

import sqlite_ursula

# Opens notes by its URL with your API key; db is a sqlite3.Connection.
db = sqlite_ursula.open(
    os.environ["NOTES_URL"],
    token=os.environ["TONBO_API_KEY"],
    dir="./notes-cache",
)
db.execute("CREATE TABLE IF NOT EXISTS notes(id INTEGER PRIMARY KEY, body TEXT)")
db.execute("INSERT INTO notes(body) VALUES (?)", ("hello",))
db.commit()  # committed on this machine
db.synced()  # Tonbo now holds every commit made so far
print(db.execute("SELECT count(*) FROM notes").fetchone()[0], db.status()["commits"])
db.close()

Run it with the key from the API key step, in the shell where you activated the environment and set NOTES_URL:

TONBO_API_KEY=tbo_... python app.py

It prints the count, then the commit counters with nothing pending: logged, confirmed and acknowledged are one number, the position of the last commit:

1 {'logged': <n>, 'confirmed': <n>, 'acknowledged': <n>, 'pending': 0, 'pending_bytes': 0}

Call synced() before anything outside the process acts on a commit, such as a response: until then the commit is only on this machine. Python does not fall back to your tonbo login: pass the key as token, as here.

Rebuild it from Tonbo

Delete the local copy and run the program again. The open rebuilds the database from the copy Tonbo keeps, so the first row is still there and the count becomes 2:

rm -r notes-cache
TONBO_API_KEY=tbo_... python app.py

Then copy app.py to another machine, install the package and run it with the same key and the same NOTES_URL. It opens the same database, and the count becomes 3.

Add it to a project

In a project of your own, with the program’s API key in TONBO_API_KEY where the project keeps its secrets, never in its code:

  1. Create the database with tonbo database create notes, signed in with tonbo login, or in the console. tonbo database show notes prints State: active once it is ready.
  2. Install with pip install sqlite-ursula==0.11.3.dev0, or uv add sqlite-ursula==0.11.3.dev0 in a uv project, in a Python that can load SQLite extensions (see Requirements). python -m sqlite_ursula then prints result: ok.
  3. Python opens a database by its URL, which tonbo database show notes --json | jq -r .url prints: put it in NOTES_URL beside the key. Where the program opens SQLite, open it instead with sqlite_ursula.open(os.environ["NOTES_URL"], token=os.environ["TONBO_API_KEY"], dir="./notes-cache"). It is a sqlite3.Connection, so the SQL stays as it is.
  4. Call db.synced() after a commit, before anything outside the process acts on it: until then the commit is only on this machine.

One process writes a database at a time: the last one to open it (see When two instances run).

Next steps