Object Watchdog
This library allow to monitor changes in a Python object and, when some attribute changes, then launch callbacks.
Support this project
Support this project (to solve issues, new features…) by applying the Github “Sponsor” button.
Install
$ pip install object-watchdog
Callbacks types
There’re 3 types of callbacks:
Async callbacks: launch coroutines as callbacks
Callbacks: launch functions as callbacks
Cache callbacks: Launch methods of class to update caches
Global vs local callbacks
Local callbacks are called only for these classes that have set the callbacks
Global callbacks are called for all classes that uses the Object Watchdog
How to usage
Object Watchdog should be used as metaclass:
from object_watchdog import ObjectWatchdog
class User(metaclass=ObjectWatchdog):
...
Defining local callbacks
Callbacks could be defined in running time and in definition.
Definition mode
At the classes you can put callbacks when any attribute changes, you can define these types of callbacks in these properties:
__async_callbacks__
__callbacks__
__cache_callbacks__
Example:
async def async_callback(instance, klass_name, key, value):
print(f"[!] New change local callback in key '{key}'. New value '{value}'")
async def async_callback2(instance, klass_name, key, value):
print(f"[0] New change local callback in key '{key}'. New value '{value}'")
def callback(instance, klass_name, key, value):
print(f"[!] Sync New change local callback in key '{key}'. New value '{value}'")
class User(metaclass=ObjectWatchdog):
__async_callbacks__ = [async_callback, async_callback2]
__callbacks__ = [callback]
__cache_callbacks__ = ["__build_hash__"]
...
Running time
If you need to add some callback in run time, Metaclass add these methods:
add_callback
add_async_callback
add_cache_callback
import asyncio
from typing import Dict
from dataclasses import dataclass, field
from object_watchdog import ObjectWatchdog
@dataclass
class User(metaclass=ObjectWatchdog):
user: str
password: str
@property
def hash(self):
if not self.__cached_hash:
self.__build_hash__()
return self.__cached_hash
def __build_hash__(self, key: str = None):
if key and key != "user" and key != "password":
return
h = hashlib.sha512()
h.update(
f"{self.user}#{self.password}".encode("UTF-8")
)
self.__cached_hash = h.hexdigest()
async def coro_callback(instance, klass_name, key, value):
print(f"[!] New change in key '{key}'. New value '{value}'")
async def main():
u = User(user="john", password="password")
u.add_async_callback(coro_callback)
u.add_cache_callback("__build_hash__")
print("[*] Modifying property 'value'")
u.password = "new password!"
def main():
asyncio.run(coro_main())
main()
Defining global callbacks
Global callback applies to all classes (or dataclasses) that uses ObjectWatchdog as a metaclass.
If you want to call any function / coroutine when some class have been modified, you also can use this method. ObjectWatchdog metaclass has these methods:
add_global_callback
add_global_async_callback
add_global_cache_callback
import asyncio
from typing import Dict
from dataclasses import dataclass, field
from object_watchdog import ObjectWatchdog
@dataclass
class MyClass(metaclass=ObjectWatchdog):
value: str
my_dict: Dict = field(default_factory=dict)
@dataclass
class MyClass2(metaclass=ObjectWatchdog):
value: str
my_dict: Dict = field(default_factory=dict)
async def coro_local_callback(instance, klass_name, key, value):
print(f"[!] New change local callback in key '{key}'. New value '{value}'")
async def coro_global_callback(instance, klass_name, key, value):
print(f"[!] New change global callback in instance '{repr(instance)}' key '{key}'. New value '{value}'")
async def coro_main():
ObjectWatchdog.add_global_callback(coro_global_callback)
u1 = MyClass(value="class 1", my_dict={"k": "v"})
u2 = MyClass2(value="class 2", my_dict={"k": "v"})
print("[*] Modifying property 'value'")
u1.value = "new value!"
u2.value = "new value!"
def main():
asyncio.run(coro_main())
main()
Metadata
Release files for object-watchdog 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| object-watchdog-0.0.2.tar.gz | 3.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| object_watchdog-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 7.4 kB
Release files / object-watchdog-0.0.2.tar.gz
| Download URL | object-watchdog-0.0.2.tar.gz |
|---|---|
| Size | 3.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e1877af82641fe2ebebb33564887f9be864ce787087dafbc58cf98cf29f8adf0
|
|
BLAKE2b-256 checksum How to use checksums |
0fd888b7a3764c9a7043288d878e987f0bdfeafaea45f89b3cc794f270c9dcb6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.6
|
Release files / object_watchdog-0.0.2-py3-none-any.whl
| Download URL | object_watchdog-0.0.2-py3-none-any.whl |
|---|---|
| Size | 3.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d3cd0a9243b906b974929089d393d314d8e72ebf2a2fdcbefaf3118c4ba80598
|
|
BLAKE2b-256 checksum How to use checksums |
3723e6090683eb97032fa57b89397efdc866265ffa6683b03ce3264d4b71cc3c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.6
|
Security for object-watchdog 0.0.2
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.