Object Observability for Python โ automatically track every attribute change.
Project description
๐ Bijoy
Object Observability for Python
Automatically track every attribute change โ built for debugging & auditing.
โจ What is Bijoy?
Bijoy is a lightweight Python library that gives your objects memory. By inheriting from the Chronicle base class, every attribute change is automatically recorded with:
- ๐ High-precision UTC timestamp
- ๐ Exact source location (file, line number, function name)
- ๐ Thread-safe logging via
threading.Lock - ๐ฆ Zero external dependencies โ uses only the Python Standard Library
Perfect for debugging state mutations, auditing workflows, and understanding when and where your objects changed.
๐ Quick Start
Installation
pip install bijoy
Or install from source:
git clone https://github.com/bijoy/bijoy.git
cd bijoy
pip install -e .
Basic Usage
from bijoy import Chronicle
class Server(Chronicle):
def __init__(self, name: str):
super().__init__(max_history=50)
self.name = name
self.status = "booting"
srv = Server("web-prod-01")
srv.status = "deploying"
srv.status = "running"
# View the full history of an attribute
for entry in srv.get_history("status"):
print(entry)
# Undo the last change
srv.undo("status")
print(srv.status) # "deploying"
# Print a formatted audit report
srv.audit()
Output:
========================================================================
CHRONICLE AUDIT โ Server (id=0x...)
========================================================================
Attribute: 'name'
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
[1] value = 'web-prod-01'
time = 2026-03-21 17:00:00.123456 UTC
where = example.py:8 in __init__()
Attribute: 'status'
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
[1] value = 'booting'
time = 2026-03-21 17:00:00.123457 UTC
where = example.py:9 in __init__()
[2] value = 'deploying'
time = 2026-03-21 17:00:00.123458 UTC
where = example.py:13 in <module>()
========================================================================
๐ API Reference
Chronicle(max_history: int = 100)
Base class. Inherit from it to enable automatic attribute tracking.
| Parameter | Type | Default | Description |
|---|---|---|---|
max_history |
int |
100 |
Maximum entries kept per attribute (FIFO) |
get_history(attr_name: str) โ List[HistoryEntry]
Returns a chronological list of all recorded changes for the given attribute.
entries = obj.get_history("status")
for e in entries:
print(f"{e.value} at {e.timestamp} โ {e.filename}:{e.lineno}")
undo(attr_name: str) โ Any
Reverts an attribute to its previous value and removes the latest history entry.
obj.status = "crashed"
prev = obj.undo("status") # restores previous value
- Returns the restored value, or
Noneif the attribute had only one entry (gets deleted). - Raises
KeyErrorif no history exists.
audit() โ str
Prints and returns a human-readable, formatted report of all recorded attribute changes.
report = obj.audit() # prints to stdout and returns the string
toggle_recording(enable: bool) โ None
Pause or resume history tracking. Useful to skip noisy updates.
obj.toggle_recording(False)
obj.cpu_load = 99.9 # NOT recorded
obj.toggle_recording(True)
obj.cpu_load = 42.0 # recorded
clear_history(attr_name: str | None = None) โ None
Erase recorded history. Pass an attribute name to clear only that attribute, or None to clear everything.
HistoryEntry
Each recorded change is stored as a HistoryEntry with these fields:
| Field | Type | Description |
|---|---|---|
value |
Any |
The new value assigned |
timestamp |
datetime |
UTC time of the change |
filename |
str |
Source file path |
lineno |
int |
Line number in the source file |
function |
str |
Function/method name |
๐งช Running Tests
python -m unittest test_chronicle -v
test_initial_assignment_creates_history ........................ ok
test_subsequent_changes_are_appended ........................... ok
test_history_entry_has_caller_metadata ......................... ok
test_private_attrs_not_logged .................................. ok
test_undo_restores_previous_value .............................. ok
test_undo_removes_latest_entry ................................. ok
test_undo_single_entry_deletes_attribute ....................... ok
test_undo_no_history_raises .................................... ok
test_oldest_entries_discarded .................................. ok
test_max_history_of_one ........................................ ok
test_paused_changes_not_logged ................................. ok
test_resume_recording .......................................... ok
test_concurrent_writes ......................................... ok
----------------------------------------------------------------------
Ran 13 tests in 0.XXXs
OK
๐๏ธ Project Structure
bijoy/
โโโ bijoy/
โ โโโ __init__.py
โ โโโ chronicle.py
โโโ example_chronicle.py
โโโ test_chronicle.py
โโโ pyproject.toml
โโโ LICENSE
โโโ .gitignore
โโโ README.md
๐ฏ Design Highlights
| Feature | How |
|---|---|
| No recursion loops | __init__ writes internals via self.__dict__ directly |
| No meta-logging | Attributes starting with _ are silently skipped |
| O(1) eviction | Uses collections.deque(maxlen=โฆ) for FIFO pruning |
| Thread safety | All history reads/writes are guarded by threading.Lock |
| Zero dependencies | Only inspect, threading, datetime, collections |
๐ License
MIT License โ free for personal and commercial use.
Made with โค๏ธ by Bijoy
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 bijoy-1.0.0.tar.gz.
File metadata
- Download URL: bijoy-1.0.0.tar.gz
- Upload date:
- Size: 6.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34d0cb73102901107196e44c0e121e842eefc943ca0dae74725262a7ea396366
|
|
| MD5 |
50aed953c10519def919234557fafe02
|
|
| BLAKE2b-256 |
8d20161755a37dc8591da876d3e9df99b53ecf334c5ce8c1313f98b417c8697d
|
File details
Details for the file bijoy-1.0.0-py3-none-any.whl.
File metadata
- Download URL: bijoy-1.0.0-py3-none-any.whl
- Upload date:
- Size: 6.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
940ca693177d9245703fdeeb9abbd2284f61a2c08bf875fad5895688a666d1ab
|
|
| MD5 |
c06c52ef4328182f2fe7babcc8069e30
|
|
| BLAKE2b-256 |
60d4186b52afcc04507602f408250b185541f193a65337a71d79a695cbbd9765
|