Python overview
The Python SDK is the embedded engine with a Python surface over it. There is no
server, no connection string and no pool: stratadb.open() hands you a handle
onto a directory, and the work happens in your process.
import stratadb
with stratadb.open("./mydb") as db:
db.kv.put("greeting", "hello")
print(db.kv.get("greeting"))
b'hello'
If you have not seen the model yet, Python quickstart is the ten-minute version. This section is the reference-grade detail underneath it.
The shape of the API
One handle, then a namespace per thing:
db.kv db.json db.events db.vectors db.graphs
db.branches db.spaces db.ai db.admin db.arrow db.hub
Plus three properties that describe the handle rather than doing work:
db.branch and db.space report the branch and space this view resolves to,
and db.version reports the engine it is running.
Bytes out of key-value, objects out of JSON
This is the first thing that catches people, so it is worth stating before anything else.
Key-value stores bytes. It accepts str or bytes and always hands back
bytes:
db.kv.put("a", "hello") # str accepted
db.kv.put("b", b"\x00\x01") # bytes accepted
db.kv.get("a") # always bytes
b'hello'
Anything else is refused rather than coerced. db.kv.put("n", 42) raises
InvalidArgumentError, because guessing an encoding for you is how data gets
corrupted quietly. Encode it yourself, or use JSON.
JSON stores values. It round-trips the Python types you would expect, and gives them back as themselves:
| you write | you read |
|---|---|
{"a": 1} |
dict |
[1, 2] |
list |
"s" |
str |
7 |
int |
1.5 |
float |
True |
bool |
None |
None |
db.json.set("doc", "$", {"name": "Ada", "age": 36})
db.json.get("doc", "$.name")
'Ada'
So the rule is: reach for kv when the value is opaque to the database, and
json when its shape matters. Working with data
covers the choice across all five models.
Results are typed objects
Reads that return more than a value return objects with attributes, not dictionaries, and enum fields rather than strings:
preview = db.branches.preview("work", "default")
preview.conflicts
preview.branch_point
[c.value for c in preview.capabilities_covered]
[]
4
['kv', 'json', 'vector']
Note the .value on the last one. Capability fields are enums, so compare them
to the enum or read .value for the string.
When the Python name is not the CLI name
The SDK is not a transliteration of the command surface. It reshapes it into
idiomatic Python: nested namespaces flatten, so graph.node.add is
db.graphs.add_node; three fork commands collapse into one method with keyword
arguments; event.count is db.events.len; and arrow.import has to be
import_ because import is a keyword.
Those are improvements, and they are also the reason you cannot guess the Python
spelling from a CLI example. The one that catches people most often is
generation: the CLI verb is strata inference generate, and the method is
db.ai.chat, because it takes messages and returns a ChatCompletion.
Of the 132 commands with a Python method, 16 spell it differently from the CLI verb. Everything not listed here matches, so strata kv put is db.kv.putand needs no table.
| CLI | Python |
|---|---|
strata arrow import | db.arrow.import_ |
strata config get | db.admin.config |
strata config get-key | db.admin.config_value |
strata event count | db.events.len |
strata event range-time | db.events.range_by_time |
strata inference generate | db.ai.chat |
strata ipc status | db.admin.ipc_status |
strata ipc stop | db.admin.ipc_stop |
strata json index create | db.json.create_index |
strata json index drop | db.json.drop_index |
strata json index list | db.json.list_indexes |
strata json list | db.json.keys |
strata kv list | db.kv.keys |
strata vector collection create | db.vectors.create_collection |
strata vector collection delete | db.vectors.delete_collection |
strata vector collection list | db.vectors.list_collections |
A further 17 have no CLI verb at all. They are reachable from Python, and from the CLI only through strata command run:
| Command | Python |
|---|---|
branch.fork_at_timestamp | db.branches.fork |
branch.fork_at_version | db.branches.fork |
event.batch_append | db.events.append_many |
graph.apply_delete_policy | db.graphs.apply_delete_policy |
graph.batch_write | db.graphs.batch_write |
graph.bindings | db.graphs.bindings_for_entity |
json.batch_delete | db.json.delete_many |
json.batch_get | db.json.get_many |
json.batch_set | db.json.set_many |
kv.batch_delete | db.kv.delete_many |
kv.batch_exists | db.kv.exists_many |
kv.batch_get | db.kv.get_many |
kv.batch_put | db.kv.put_many |
vector.batch_delete | db.vectors.delete_many |
vector.batch_get | db.vectors.get_many |
vector.batch_upsert | db.vectors.upsert_many |
vector.index.query | db.vectors.index_query |
Every command page in the reference shows both spellings side by side, generated from the installed wheel, so the per-command answer is always there too.
What the SDK does not do
There is no async support. No coroutine methods, no async with. Calls are
synchronous and block the calling thread. If you need them off the event loop,
put them behind asyncio.to_thread or an executor.
db.state is gone. The state-cell primitive was removed in V1. The
attribute is deliberately still there and raises a UnsupportedError naming its
replacement, so v0.x code fails with an explanation rather than an
AttributeError:
db.state
unsupported.sdk.state_removed: the state-cell primitive (db.state) was removed in V1
hint: use db.kv for keyed values, or db.json for structured documents
Node.js and Rust do not ship. Python is the only SDK at 1.x. Compatibility and versioning has the current set.
Where to look next
Installation, then Opening databases for the lifetime model, which is the part that differs most from a client library.