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.
Metadata
Release files for pydatatracker 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pydatatracker-0.1.0.tar.gz | 46.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pydatatracker-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 81.3 kB
Release files / pydatatracker-0.1.0.tar.gz
| Download URL | pydatatracker-0.1.0.tar.gz |
|---|---|
| Size | 46.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ebf8e059f15693f1f9ff5edc1ad314d1f72f8d1f68bf3681a73958dfbe39c2fb
|
|
BLAKE2b-256 checksum How to use checksums |
529a7c21f60dcfe20b5b717e0eb25fbf4debde4f251168c5a6792c90cd1dc53a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 4, 2025.
Transparency logRelease files / pydatatracker-0.1.0-py3-none-any.whl
| Download URL | pydatatracker-0.1.0-py3-none-any.whl |
|---|---|
| Size | 34.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5ed29e11bce08a826eab296fcda8086565316ba1eed81fa4f1601b99146733c8
|
|
BLAKE2b-256 checksum How to use checksums |
f95905c4b3e19fb8d4316d08482a8c28d5797329b247e73a1e9c9176126c6717
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 4, 2025.
Transparency log