Python client for AwareDB — a data-modeling and calculation platform with unit-aware formulas, scenarios, optimization, and reversible history.
Project description
awaredb
Python client for AwareDB — a data-modeling and calculation platform with unit-aware formulas, reversible history, and a rich analyses toolbox (scenarios, optimisation, sensitivity, projections, traces).
pip install awaredb
from awaredb import AwareDBClient
with AwareDBClient(db="my_db", token="…") as client:
client.calculate(formula="car.power * 2")
Features
- Connect by token or by username/password.
- Read commands:
get,query,calculate. - Write commands:
update,remove,flush,load(bulk-load JSON from disk). - Analyses:
scenarios,impact,projection,goal_seek,optimize,sensitivity,trace. - History:
historyagainst the reversible audit database. - Typed exceptions:
AwareDBError,TransportError,AuthError,InvalidCommandError,UnexpectedError. - Persistent
httpx-backed transport with built-in retries and connection pooling. - Ships a
py.typedmarker — works withmypy/pyrightout of the box.
Requirements
- Python 3.12+
httpx
Quick start
from awaredb import AwareDBClient
# Token auth
client = AwareDBClient(db="my_db", token="…")
# Username / password — fetches a token at construction time
client = AwareDBClient(db="my_db", user="alice", password="…")
# Custom host + timeout, no upfront connection check
client = AwareDBClient(
db="my_db",
token="…",
host="https://aware.example.com",
timeout=30,
check_connection=False,
)
# Close the underlying HTTP client when finished
client.close()
# Or use the client as a context manager
with AwareDBClient(db="my_db", token="…") as client:
client.flush()
Read commands
get(path, states=None)
Return the value at a path.
client.get(path="car.power")
# "250 hp"
query(nodes=None, conditions=None, properties=None, states=None, show_abstract=False)
Return nodes matching the filters. nodes defaults to ["*"] (all).
client.query(
nodes=["employee"],
conditions=["node.salary.gross > 60000"],
properties=["salary"],
)
calculate(formula, states=None)
Evaluate one or more formulas against the live database.
client.calculate(formula="car.power * 2")
# "500 hp"
Write commands
update(data, partial=False)
Create or update nodes / relations / relation types. data accepts a single item
or a list.
client.update([
{"uid": "fan", "power": "=sum(this.children.power)"},
])
remove(ids)
Delete by id.
client.remove(ids=["7037a8a5-…", "7037a8a5-…"])
flush()
Drop every node and relation in the database.
load(filepath, recursive=False, flush=False)
Push the contents of a JSON file (or folder of JSON files) through update.
client.load("./seed", recursive=True, flush=True)
Analyses
All analyses are read-only — they recalculate the graph against a temporary context and return per-variant results. None mutate the database.
scenarios(edits, states=None)
Apply path/value overrides, recalculate, return per-scenario results.
client.scenarios(edits=[{"path": "motor.power", "value": "30 kW"}])
impact(edit, states=None, **extra)
Sweep an input across N steps and observe outputs.
projection(start_from, unit="day", step=1, points=10, edits=None, states=None)
Walk forward in time. Per-step edits apply between points.
goal_seek(target, decision, states=None, **extra)
Find the input value that drives target to a desired value.
optimize(objectives, decisions, constraints=None, states=None, **extra)
Vary decision variables to minimise / maximise objectives subject to constraints.
sensitivity(target, inputs, states=None, **extra)
Perturb each input by ±delta and report the response per variant.
trace(target, depth=5, states=None)
Walk the upstream dependency tree of a target path.
client.trace(target="car.range", depth=10)
History
history(change_id=None, ids=None, start=None, end=None, from_date=None, to_date=None)
List changes recorded in the reversible history database.
from datetime import datetime
client.history(from_date=datetime(2026, 1, 1))
Errors
Everything funnels through AwareDBError. Subclasses indicate the failure mode:
| Exception | When it fires |
|---|---|
AuthError |
401 / 403, or username/password rejected. |
InvalidCommandError |
400 — bad payload or unknown command. |
TransportError |
Network failure or other non-2xx HTTP status. |
UnexpectedError |
2xx body that isn't JSON. |
AwareDBError |
Base class. Catch this to handle everything above. |
Development
uv drives dependency management. The
lockfile (uv.lock) is committed and pins exact versions.
# One-time: install uv
brew install uv # macOS / Linuxbrew
# or:
curl -LsSf https://astral.sh/uv/install.sh | sh
# Provision the project env (creates .venv from uv.lock — runtime + dev group)
uv sync
# Runtime-only (excludes dev group: pytest, ruff, mypy, …)
uv sync --no-dev
# Tests, lint, format, type check
uv run pytest
uv run ruff check awaredb/ tests/
uv run ruff format --check awaredb/ tests/
uv run mypy awaredb/
# Add / remove deps (auto-updates pyproject.toml + uv.lock)
uv add some-package
uv add --group dev some-package
uv remove some-package
Note:
python -m buildis the pip-era invocation and requires thebuildpackage installed in the env. Withuv, useuv buildinstead — it usesuv's own PEP 517 frontend, no extra dependency needed.
Releasing
Releases are cut by pushing a v* git tag. The .github/workflows/release.yml
workflow builds the sdist + wheel with uv build and uploads them to PyPI via
Trusted Publishing (OIDC, no token
in CI).
One-time PyPI setup
- Create the project on PyPI: https://pypi.org/manage/account/publishing/.
- Add a pending trusted publisher with:
- PyPI Project Name:
awaredb - Owner:
djinalab - Repository name:
awaredb-python - Workflow name:
release.yml - Environment name:
pypi
- PyPI Project Name:
- In GitHub repo settings → Environments, create an environment named
pypi(optionally with required reviewers for an approval gate).
Cutting a release
# 1. Bump version in awaredb/__init__.py (e.g. 0.1.0 → 0.1.1)
# 2. Move the [Unreleased] block in CHANGELOG.md under a new [X.Y.Z] - YYYY-MM-DD heading
# 3. Commit, push to main
git commit -am "Release 0.1.1"
git push
# 4. Tag and push — release.yml fires automatically
git tag v0.1.1
git push origin v0.1.1
Manual publish (fallback)
If you need to publish from a workstation:
uv build # writes sdist + wheel to dist/
uv publish # uses UV_PUBLISH_TOKEN env var
# or:
uv publish --token "$PYPI_API_TOKEN"
The dist/ folder is gitignored — never commit build artifacts.
See CONTRIBUTING.md and CHANGELOG.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file awaredb-1.0.1.tar.gz.
File metadata
- Download URL: awaredb-1.0.1.tar.gz
- Upload date:
- Size: 19.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed7163c653a8d73b8f00e611b8e878a612a4467d1a26f12d38a29bd366e95096
|
|
| MD5 |
2ca4bef6218c9ee8fd867ab8276e7a07
|
|
| BLAKE2b-256 |
dc5116efbc9306d42afb66e357be6804627335267780da308ec3c93fdae3fe5c
|
File details
Details for the file awaredb-1.0.1-py3-none-any.whl.
File metadata
- Download URL: awaredb-1.0.1-py3-none-any.whl
- Upload date:
- Size: 15.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ef8d54b75589dbf7cbd3686b9222a1720cc74550d3655d456ef6974f047e114
|
|
| MD5 |
0360e1134704a16db174198d4b05ec8a
|
|
| BLAKE2b-256 |
f1b3ad0df05cff9e4c246963790d1663a3b57e8f27ee26722816d780404dcd41
|