> Fetch the index of every Tonbo docs page as Markdown at https://tonbo.dev/llms.txt

# Python SDK reference

Last updated 3 November 2026

Every export of [sqlite-ursula](https://pypi.org/project/sqlite-ursula/0.11.3.dev0/) 0.11.3.dev0, the Python package that opens a Tonbo database by its URL as a `sqlite3` connection: each function’s parameters, defaults, return value and errors, page by page.

To get started, follow the [Python quickstart](https://tonbo.dev/docs/getting-started/quickstarts/sqlite-python.md) and [Connect from Python](https://tonbo.dev/docs/databases/python.md). Every declaration these pages show is read from the release’s wheel, so it is the release’s own.

## Install

```shell
pip install sqlite-ursula==0.11.3.dev0
```

Or, in a uv project, `uv add sqlite-ursula==0.11.3.dev0`. Pin the exact release, as these commands do: a later release can change the cache format and the server releases it works with, and the exact pin is what lets pip and uv install a pre-release without a flag. For [LangGraph](https://tonbo.dev/docs/reference/python/langgraph.md), install the `langgraph` extra:

```shell
uv pip install 'sqlite-ursula[langgraph]==0.11.3.dev0'
```

## Versions

This reference describes sqlite-ursula 0.11.3.dev0, built from [tonbo-io/ursula 8423f6eb](https://github.com/tonbo-io/ursula/blob/8423f6ebf065b370c9d915ad8b4a31432fa5a2aa/clients/sqlite-ursula-python/README.md). Python uses the pre-release sqlite-ursula 0.11.3.dev0 until 0.11.3 is published to PyPI. It is of the same minor release line as the Node.js package, `@tonbo/sqlite-ursula` 0.11.4 (see the [Node.js SDK reference](https://tonbo.dev/docs/reference/nodejs.md)), and runs the same SQLite extension inside your process. `sqlite_ursula.__version__` is the release, as a string:

```python
import sqlite_ursula

print(sqlite_ursula.__version__)  # "0.11.3.dev0"
```

## Platforms

CPython 3.11 or later (`Requires-Python: >=3.11`), the free-threaded builds included, on one of the platforms the release builds a wheel for. On any other, such as an Intel Mac or Windows, pip installs it without the library that runs inside SQLite, and `open()` raises [host_unsupported](https://tonbo.dev/docs/reference/python/errors.md#setup-host-unsupported).

| Wheel | Platform |
| --- | --- |
| `macosx_11_0_arm64` | macOS 11 or later, Apple silicon |
| `manylinux_2_28_x86_64` | Linux x64, glibc 2.28 or later |
| `manylinux_2_28_aarch64` | Linux arm64, glibc 2.28 or later |
| `musllinux_1_2_x86_64` | Linux x64, musl (Alpine 3.23 or later) |

### Pythons that run it

The package loads its extension into the SQLite of Python’s own `sqlite3` module, so that module must load extensions and run a recent SQLite. On a laptop, a [uv-managed CPython](https://docs.astral.sh/uv/guides/install-python/) is the usual answer.

| Python | Runs the package |
| --- | --- |
| uv-managed CPython (uv python install), Homebrew, conda-forge | Yes |
| The python:3.x-alpine images (Alpine 3.23 or later), on x64 | Yes |
| The python:3.x-slim images, Debian’s and Ubuntu’s apt Python, RHEL and UBI, Amazon Linux, Colab | No: their SQLite is too old |
| The python.org macOS installer, Apple’s /usr/bin/python3, pyenv’s default build | No: built without loadable SQLite extensions |
| Windows | No: run it under WSL |

`python -m sqlite_ursula` checks the Python it runs in: it loads the extension as `open()` would, prints what it found, and exits 0 when this Python can run the package and 1 when it cannot, with the reason and a `fix:` line naming a Python that can. It needs no network and no credential.

```shell
python -m sqlite_ursula
```

```text
sqlite-ursula 0.11.3.dev0
python: <version> (CPython) at <path to python>
sqlite: <version>
extension loading: yes
extension: <path to the library> (bundled)
result: ok: this Python can host sqlite-ursula
```

## Credentials

The package takes a bearer token, a string, which every request of the process carries: a Tonbo API key that acts as you, sent as it is (see [Sending the key directly](https://tonbo.dev/docs/platform/api-keys.md#direct)), or an access token exchanged from a key, which an Agent’s key needs and which lasts 10 minutes (see [The token exchange](https://tonbo.dev/docs/platform/api-keys.md#exchange)). Pass it as `open(..., token=...)`, or replace it with [set_token()](https://tonbo.dev/docs/reference/python/gate-and-import.md#set-token). The process holds one token for every database it opens. This release takes no token provider and never exchanges a key itself.

The token reaches what its key reaches (see [What a key can reach](https://tonbo.dev/docs/platform/api-keys.md#key-scope)): a key narrowed to other databases is refused with `forbidden`, and a read-only key opens a database only with `read_only=True`.

## Conventions

- Every error the package raises is an [UrsulaError](https://tonbo.dev/docs/reference/python/errors.md#ursula-error) with a `kind`, what failed, and an `action`, what to do. Branch on `action`. Any other error, such as a constraint violation, is `sqlite3`’s, unchanged.
- Every timeout is in seconds, as a number. Waits that take `None` wait without a limit, and a value the package cannot take raises `invalid_argument` before any request.
- Statements are local. A commit returns once it is on this machine; call `db.synced()` before anything outside the process acts on it.
- Any thread may use a connection, and the `a`-prefixed calls wait on the asyncio event loop instead of blocking it.
- Open databases after a fork, never before: in a child forked after its parent opened one, the package raises `forked`.
- The package and its extension read a few environment variables, such as `URSULA_VFS_TOKEN_FILE` and `SQLITE_URSULA_VFS`; they are the Node.js package’s too (see [The extension](https://tonbo.dev/docs/reference/nodejs/environment.md#extension)).

## Exports

`sqlite_ursula` exports:

| Name | Kind | What it is |
| --- | --- | --- |
| [`open`](https://tonbo.dev/docs/reference/python/open.md#open) | function | Opens a database by its URL and makes this process its writer. |
| [`aopen`](https://tonbo.dev/docs/reference/python/open.md#aopen) | function | open() for asyncio. |
| [`UrsulaConnection`](https://tonbo.dev/docs/reference/python/connection.md#ursula-connection) | class | The sqlite3.Connection subclass open() returns. |
| [`UrsulaCursor`](https://tonbo.dev/docs/reference/python/connection.md#ursula-cursor) | class | The sqlite3.Cursor subclass its cursor() returns. |
| [`gate`](https://tonbo.dev/docs/reference/python/gate-and-import.md#gate) | function | Holds a block's outcome until synced() returned on every database given. |
| [`agate`](https://tonbo.dev/docs/reference/python/gate-and-import.md#agate) | function | gate() for asyncio. |
| [`import_sqlite`](https://tonbo.dev/docs/reference/python/gate-and-import.md#import-sqlite) | function | Imports a plain SQLite file into a new, empty database. |
| [`Imported`](https://tonbo.dev/docs/reference/python/gate-and-import.md#imported) | class | What import_sqlite() published. |
| [`set_token`](https://tonbo.dev/docs/reference/python/gate-and-import.md#set-token) | function | Replaces the token every request of the process carries. |
| [`UrsulaError`](https://tonbo.dev/docs/reference/python/errors.md#ursula-error) | exception | The base class of every error the package raises. |
| [`UrsulaWriteRefusedError`](https://tonbo.dev/docs/reference/python/errors.md#ursula-write-refused-error) | exception | A write or commit refused, with nothing committed. |
| [`UrsulaResetError`](https://tonbo.dev/docs/reference/python/errors.md#ursula-reset-error) | exception | The database was reset. |
| [`UrsulaUnavailableError`](https://tonbo.dev/docs/reference/python/errors.md#ursula-unavailable-error) | exception | open() met no trusted state in time. |
| [`UrsulaSetupError`](https://tonbo.dev/docs/reference/python/errors.md#ursula-setup-error) | exception | It cannot succeed as asked. |
| [`Action`](https://tonbo.dev/docs/reference/python/errors.md#action) | alias | What to do about a failure: retry, reopen, stop or fix. |
| [`__version__`](https://tonbo.dev/docs/reference/python.md#version) | constant | The release, as a string. |

`sqlite_ursula.langgraph`, which the package never imports itself, exports:

| Name | Kind | What it is |
| --- | --- | --- |
| [`UrsulaSaver`](https://tonbo.dev/docs/reference/python/langgraph.md#ursula-saver) | class | LangGraph's SqliteSaver on a database. |
| [`AsyncUrsulaSaver`](https://tonbo.dev/docs/reference/python/langgraph.md#async-ursula-saver) | class | LangGraph's AsyncSqliteSaver on a database. |
| [`UrsulaStore`](https://tonbo.dev/docs/reference/python/langgraph.md#ursula-store) | class | LangGraph's SqliteStore on a database. |
| [`AsyncUrsulaStore`](https://tonbo.dev/docs/reference/python/langgraph.md#async-ursula-store) | class | LangGraph's AsyncSqliteStore on a database. |
