Change-tracking containers for structured Python data
Project description
PyDataTracker
Utilities for building Python applications that require detailed state tracking. The package exposes tracked dictionary/list/attribute containers plus change-log helpers that make it easy to monitor modifications made while composing complex data payloads.
Why this project?
- State awareness – record every mutation to your domain objects
- Composable types – nest tracked containers or regular Python types
- Observer-friendly – emit structured change logs for audit pipelines
Project layout
.
├── AGENTS.md # Unified contributor instructions
├── docs/ # Design notes & future specs
├── src/pydatatracker # Library code (tracked containers and utilities)
├── tests/ # Pytest suite
├── tmp/ # Scratch directory (ignored, safe for experiments)
├── justfile # Repeatable task runner configured for uv
└── pyproject.toml # Build metadata + tooling config
Installation
pip install pydatatracker
Getting started
- Create and activate a virtual environment managed by
uv:just install - Run the test-suite:
just test
- Keep formatting and linting consistent:
just format just lint
Development workflow
- Use Python 3.12+ with modern type hints and the
@overridedecorator. - Maintain ≥69% test coverage; prefer
uv run pytestorjust coveragewhen validating complex changes. - Formatting and linting are handled by Ruff (line length 100).
- Temporary scratch work should live in
tmp/so the project root stays clean.
Releasing
- Update
CHANGELOG.mdandsrc/pydatatracker/_version.py. - Run
just testandjust publish(requiresPYPI_TOKEN). - See
docs/packaging.mdfor the full checklist.
Resources
- Contribution rules: see
AGENTS.md - Architecture notes:
docs/architecture.md - Debugging cookbook:
docs/debugging.md - Issue tracker: open issues against the upstream GitHub repository referenced in the project URLs.
Tracking actors
Set a temporary actor when mutating tracked objects to avoid stack inspection overhead::
from pydatatracker import TrackedDict, tracking_actor
tracked = TrackedDict()
with tracking_actor('provisioner'):
tracked['status'] = 'ready'
print(tracked.tracking_changes()[0].actor) # => provisioner
Snapshots (tracking_capture_snapshots=True), stack capture (tracking_capture_stack=True), and actors are all opt-in so the fast path stays lightweight. Enable only the knobs you need for debugging or auditing.
Inspecting change history
Each tracked object exposes tracking_changes(), last_change(), and changes_since(...) so callers can safely inspect audit history without dipping into private attributes. For example:
changes = tracked.changes_since(first_change)
print([entry.extra["location"] for entry in changes])
Observers
Register observers to receive every ChangeLogEntry as it happens. The bundled ChangeCollector stores entries in memory:
from pydatatracker import ChangeCollector, TrackedDict
tracked = TrackedDict()
collector = ChangeCollector()
tracked.tracking_add_observer(collector)
tracked["mode"] = "debug"
print(collector.as_list()[-1].extra["location"]) # mode
You can also register async-friendly observers using async_queue_observer to push changes onto an asyncio.Queue. For metrics, wrap a Prometheus (or compatible) counter via telemetry_observer() to increment labels per action.
Benchmarks
Use just benchmark to measure the overhead of observability features. Sample output:
Benchmark results (5000 mutations, 5 runs)
base mean=1.05s stdev=0.03s
actor mean=1.01s stdev=0.04s
snapshot mean=4.52s stdev=0.22s
full mean=4.25s stdev=0.18s
CLI
Run just cli to execute the demo CLI (writes a tracked change to stdout).
Exporters
Use builders in pydatatracker.exporters (e.g., JsonLinesExporter, HttpExporter, S3Exporter, KafkaExporter) to stream serialized change dicts to external systems.
Config-based observers
Define observer lists in JSON and load them with pydatatracker.config.load_observers_from_json.
Benchmarks in CI
GitHub Actions runs scripts/benchmark.py on every push; keep average times within ~5x of the base to avoid regressions.
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 pydatatracker-0.1.0.tar.gz.
File metadata
- Download URL: pydatatracker-0.1.0.tar.gz
- Upload date:
- Size: 46.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebf8e059f15693f1f9ff5edc1ad314d1f72f8d1f68bf3681a73958dfbe39c2fb
|
|
| MD5 |
9aa0f8b6ffe9330c9ee604b862dc38d8
|
|
| BLAKE2b-256 |
529a7c21f60dcfe20b5b717e0eb25fbf4debde4f251168c5a6792c90cd1dc53a
|
Provenance
The following attestation bundles were made for pydatatracker-0.1.0.tar.gz:
Publisher:
release.yml on endavis/pydatatracker
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydatatracker-0.1.0.tar.gz -
Subject digest:
ebf8e059f15693f1f9ff5edc1ad314d1f72f8d1f68bf3681a73958dfbe39c2fb - Sigstore transparency entry: 741755959
- Sigstore integration time:
-
Permalink:
endavis/pydatatracker@1e72b5759367fad4ec187bcf9ef64e97318caa89 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/endavis
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1e72b5759367fad4ec187bcf9ef64e97318caa89 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pydatatracker-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pydatatracker-0.1.0-py3-none-any.whl
- Upload date:
- Size: 34.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ed29e11bce08a826eab296fcda8086565316ba1eed81fa4f1601b99146733c8
|
|
| MD5 |
23e007a028a469df9880f7d425409410
|
|
| BLAKE2b-256 |
f95905c4b3e19fb8d4316d08482a8c28d5797329b247e73a1e9c9176126c6717
|
Provenance
The following attestation bundles were made for pydatatracker-0.1.0-py3-none-any.whl:
Publisher:
release.yml on endavis/pydatatracker
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydatatracker-0.1.0-py3-none-any.whl -
Subject digest:
5ed29e11bce08a826eab296fcda8086565316ba1eed81fa4f1601b99146733c8 - Sigstore transparency entry: 741755965
- Sigstore integration time:
-
Permalink:
endavis/pydatatracker@1e72b5759367fad4ec187bcf9ef64e97318caa89 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/endavis
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1e72b5759367fad4ec187bcf9ef64e97318caa89 -
Trigger Event:
push
-
Statement type: