inillucent
inillucent is an embedded SQL database. It speaks SQLite's dialect on its own storage, and it has
keyword search and vector search built in. One .rdb file holds the tables and the search indexes.
This package gives Python two ways to use it:
- The driver:
Database,ConnectionandRows. It calls the inillucent C library inside your Python process throughctypes. Use the driver in an application. - The command line helpers:
run()andquery(). Each call starts theinillucentprogram and reads the JSON it prints. Use them in scripts, for commands the driver has no method for.
Install
pip install inillucent
The package needs Python 3.9 or later. The wheel for your platform holds the C library and the four programs, so the install needs no compiler, no Rust toolchain and no network access after the download.
| Platform | Wheel tag |
|---|---|
| Windows, x64 | win_amd64 |
| macOS 13 or later, Apple silicon and Intel | macosx_13_0_universal2 |
| Linux, x64 | manylinux_2_28_x86_64 |
| Linux, arm64 | manylinux_2_28_aarch64 |
The driver loads the C library from the wheel's _lib folder. Set INILLUCENT_DRIVER_LIB to the
path of a different library file to load that one. The helpers run the programs in the wheel's
_bin folder. A source install has neither folder. It needs a library you built with
cargo build -p inillucent-driver-capi, named by INILLUCENT_DRIVER_LIB.
A first program
from inillucent import Database
with Database("app.rdb") as database:
connection = database.connect()
connection.execute("CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT)")
connection.execute("INSERT INTO people VALUES (?1, ?2)", [1, "Ada"])
rows = connection.execute("SELECT id, name FROM people", limit=200)
print(rows.rows, rows.total) # [[1, 'Ada']] 1
Database("app.rdb") creates the file when it does not exist. Leaving the with block closes every
connection, writes everything to the file and closes it.
?1, ?2 and so on are bound to the values in the list, in order. Bind values this way instead of
pasting them into the SQL text.
limit caps the rows returned. rows.total still counts every row the statement produced, and
rows.more is True when rows were left out. With no limit, execute() returns every row.
Transactions
with connection.transaction() as transaction:
transaction.execute("INSERT INTO people VALUES (2, 'Grace')")
transaction.execute("UPDATE people SET name = 'Ada Lovelace' WHERE id = 1")
Leaving the block normally commits. Leaving it with an exception rolls back. A statement that fails
inside Transaction.execute() rolls back the whole transaction before it raises.
Statements you run many times
with connection.prepare("INSERT INTO people VALUES (?1, ?2)") as statement:
for key, name in [(3, "Grace"), (4, "Edsger")]:
statement.execute([key, name])
Values
| Python value | Bound as | Read back as |
|---|---|---|
None |
NULL |
None |
bool |
INTEGER 0 or 1 |
int |
int |
INTEGER |
int |
float |
REAL |
float |
str |
TEXT |
str |
bytes, bytearray, memoryview |
BLOB |
bytes |
Any other type raises TypeError.
Threads
The engine is single threaded, and the driver has no lock inside. Use a Database and everything
opened from it on one thread, or serialize every call yourself. Connection.cancel() is the one call
meant to come from another thread.
Errors
from inillucent import DriverError, Unsupported
try:
connection.execute("SELECT * FROM absent")
except Unsupported as why:
print("not built yet:", why.feature)
except DriverError as why:
print(why.status_name, why.message) # not_found no such table: absent
Every refusal raises DriverError, also exported as Error. DriverError has these attributes:
| Attribute | What it holds |
|---|---|
status |
the status as a number |
status_name |
the status as text, such as not_found |
message |
the error text |
feature |
the missing feature, when the status is unsupported |
detail |
more detail, when the engine gives it |
offset |
the byte offset in the SQL where the error is, or None |
The thirteen status names are unsupported, syntax, not_found, constraint, readonly,
busy, interrupted, corrupt, io, full, too_big, invalid_state and internal.
Unsupported is the subclass raised for status unsupported. It means the engine has not built
that feature. The SQL is not wrong, and a different spelling fails the same way. Catch
Unsupported before DriverError so the two cases stay apart. Call capabilities() before you
write an unusual statement.
From the command line
pip install puts four programs on PATH:
| Program | What it is |
|---|---|
inillucent |
the command line: 30 commands, each with --output json |
inillucent-shell |
an interactive shell that works like sqlite3, with 63 of its 65 dot commands |
inillucent-mcp |
an MCP server: 28 of the same commands served to an AI agent |
inillucent-migrate |
builds a database from a legacy retrieval index. inillucent migrate copies a SQLite file or a PostgreSQL or MySQL database |
inillucent create notes.rdb
inillucent --db notes.rdb exec "CREATE TABLE notes (id INTEGER PRIMARY KEY, body TEXT)"
inillucent --db notes.rdb query "SELECT * FROM notes"
inillucent --db notes.rdb describe notes
inillucent-shell notes.rdb
inillucent help
The inillucent program exits with code 0 on success, 1 on a failure, 2 when the command line
cannot be read, and 3 when the engine has not built a feature.
The command line helpers in Python
from inillucent import run, query
print(run("describe", db="notes.rdb", table="notes")["ddl"])
print(query("SELECT * FROM notes WHERE id > ?1", db="notes.rdb", params=[3]))
| Helper | What it does |
|---|---|
run(command, db, **arguments) |
runs one inillucent command with --output json and returns the result as a dict. table="notes" becomes --table notes. A refusal is returned with ok set to False. It raises RuntimeError only when the program could not be run |
query(sql, db, params, limit) |
runs one query and returns its rows as a list of dict keyed by column name. Raises DriverError or Unsupported on a refusal |
binary(program) |
returns the path of one of the four programs in the wheel |
Each helper call starts a process, so use the driver for anything that runs often. query() returns
at most 200 rows, the default of the query command. Pass limit=0 for every row.
For an AI agent
MCP, the Model Context Protocol, is how an AI agent calls tools. Add inillucent-mcp to an MCP
client's configuration:
{
"mcpServers": {
"inillucent": {
"command": "inillucent-mcp",
"args": ["--db", "app.rdb"]
}
}
}
inillucent-mcp serves 28 of the command line's commands as MCP tools. The tools are generated from
the same command table as the command line. --readonly refuses every statement that changes data.
--root DIR refuses every path outside DIR.
The API
These are the driver's classes and functions. cargo test -p inillucent-compat --test tooling documentation::
reads this table and fails if a name in the first column is not declared in the driver source.
| what | one line |
|---|---|
Database(path, create=True, read_only=False, diagnostics=False) |
opens a database file. create=True makes the file when it is missing. |
Database.connect() |
returns a new Connection. Each connection is its own session, and temp. tables and ATTACH belong to one session. |
Database.path |
a property: the path of the database file. |
Database.checkpoint() |
copies everything written so far into the database file. |
Database.integrity_check() |
checks every table and index, and raises on the first problem. |
Database.backup_to(path) |
copies the database to path, then opens and checks the copy. |
Database.close() |
closes every connection, writes everything to the file and closes it. Leaving a with block calls it. |
Connection.execute(sql, params, limit) |
runs one statement and returns Rows. |
Connection.execute_batch(sql) |
runs several statements separated by semicolons, for their effect. |
Connection.prepare(sql) |
compiles a statement and returns a Statement you can run many times. |
Connection.transaction() |
begins a transaction and returns a Transaction. |
Connection.last_insert_rowid |
a property: the rowid the last INSERT assigned. |
Connection.total_changes |
a property: how many rows every statement on this connection has changed. |
Connection.in_transaction |
a property: whether a transaction is open. |
Connection.schema_cookie |
a property: a number that changes whenever the schema changes. |
Connection.cancel() |
asks the running statement to stop, from another thread. It stops at the next check, so the stop is not instant. |
Connection.close() |
closes the connection. |
Statement.execute(params, limit) |
binds the values, runs the statement and returns Rows. |
Statement.close() |
frees the compiled statement. |
Transaction.execute(sql) |
runs one statement inside the transaction and returns the number of rows it changed. |
Transaction.commit() |
commits the transaction. |
Transaction.rollback() |
rolls the transaction back. |
Rows |
one result: columns, column_types, rows, total, more, affected, elapsed_us and tag. Supports len(), iteration and indexing by row number. |
capabilities() |
returns every capability the engine declares, as a list of dict with name, supported and note. |
supports(name) |
returns 1 for yes, 0 for no, -1 for partial, and -2 for a name this build does not know. Treat -2 as no. |
abi_version() |
returns the version of the C library's interface, such as 1.0.0. |
DriverError |
the exception for every refusal. Also exported as Error. |
Unsupported |
the subclass of DriverError for a feature the engine has not built. |
inillucent.__version__ is the package version.
More
MIT licence. Source: https://github.com/Black-Rainbow-Labs/Inillucent
Release files for inillucent 1.0.30
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| inillucent-1.0.30-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| inillucent-1.0.30-py3-none-manylinux_2_28_x86_64.whl | Python 3 | none | Linux glibc 2.28+ x86-64 | Details |
| inillucent-1.0.30-py3-none-manylinux_2_28_aarch64.whl | Python 3 | none | Linux glibc 2.28+ ARM64 | Details |
| inillucent-1.0.30-py3-none-macosx_13_0_universal2.whl | Python 3 | none | macOS 13.0+ universal2 (ARM64, x86-64) | Details |
Total release size: 104.9 MB
Release files / inillucent-1.0.30-py3-none-win_amd64.whl
| Download URL | inillucent-1.0.30-py3-none-win_amd64.whl |
|---|---|
| Size | 20.4 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
11de512390a719ee89ade10c728fcd1129356f99b60cc654eb2b5289d2e9f036
|
|
BLAKE2b-256 checksum How to use checksums |
276f1d54ba9469ad9a45fc12087197676bf2d963c4769dfbf28b56b73a0dc372
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|
Release files / inillucent-1.0.30-py3-none-manylinux_2_28_x86_64.whl
| Download URL | inillucent-1.0.30-py3-none-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 21.5 MB |
| Tags | Linux glibc 2.28+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
a0a2979d82f96e205a04abb42632407657d0c007f5fec227591975d153b19fc4
|
|
BLAKE2b-256 checksum How to use checksums |
77a9d05bdfeb50ab55705637e1dece76d71d27fb8eb29f7c6609bfda7e55243c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|
Release files / inillucent-1.0.30-py3-none-manylinux_2_28_aarch64.whl
| Download URL | inillucent-1.0.30-py3-none-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 19.8 MB |
| Tags | Linux glibc 2.28+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
52f76536a0ad34b35abba019209294bd9ba3f9829a358acacc2425ba0c93206a
|
|
BLAKE2b-256 checksum How to use checksums |
6d5d33d200ac4caf466634c07f7864af5c423bf0144d861798e70392bc42014d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|
Release files / inillucent-1.0.30-py3-none-macosx_13_0_universal2.whl
| Download URL | inillucent-1.0.30-py3-none-macosx_13_0_universal2.whl |
|---|---|
| Size | 43.2 MB |
| Tags | Python 3 macOS 13.0+ universal2 (ARM64, x86-64) |
|
SHA-256 checksum How to use checksums |
3549735ba7b28d4fdbfa49929f443a8a36e77273c0fa02b13e967e7b11c44751
|
|
BLAKE2b-256 checksum How to use checksums |
4df0881b31b274004047708ca3c732da0a5904f3ce5ce38626c934c160fd5ad3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|