Skip to main content

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: history against 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.typed marker — works with mypy / pyright out 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 build is the pip-era invocation and requires the build package installed in the env. With uv, use uv build instead — it uses uv'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

  1. Create the project on PyPI: https://pypi.org/manage/account/publishing/.
  2. Add a pending trusted publisher with:
    • PyPI Project Name: awaredb
    • Owner: djinalab
    • Repository name: awaredb-python
    • Workflow name: release.yml
    • Environment name: pypi
  3. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

awaredb-1.0.1.tar.gz (19.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

awaredb-1.0.1-py3-none-any.whl (15.0 kB view details)

Uploaded Python 3

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

Hashes for awaredb-1.0.1.tar.gz
Algorithm Hash digest
SHA256 ed7163c653a8d73b8f00e611b8e878a612a4467d1a26f12d38a29bd366e95096
MD5 2ca4bef6218c9ee8fd867ab8276e7a07
BLAKE2b-256 dc5116efbc9306d42afb66e357be6804627335267780da308ec3c93fdae3fe5c

See more details on using hashes here.

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

Hashes for awaredb-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8ef8d54b75589dbf7cbd3686b9222a1720cc74550d3655d456ef6974f047e114
MD5 0360e1134704a16db174198d4b05ec8a
BLAKE2b-256 f1b3ad0df05cff9e4c246963790d1663a3b57e8f27ee26722816d780404dcd41

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page