Reactive file state management for Python.
Project description
NestWatch
NestWatch is a Python package that allows applications to react to meaningful file changes instead of raw filesystem events.
Rather than repeatedly polling files and risking cache desynchronization, NestWatch instantly notifies your application whenever a file changes and provides both its previous and new state.
Why NestWatch?
Many applications update caches using polling tasks.
@tasks.loop(minutes=1)
async def update_cache():
...
While this works, it introduces a delay between when data changes and when applications become aware of those changes.
This becomes problematic when multiple applications depend on the same data source.
For example:
- Application A updates "config.json"
- Application B continues using outdated cached data
- Application B must wait for its polling task to run
- Both applications become temporarily out of sync
NestWatch solves this by allowing applications to react to changes instantly.
Features
- ⚡ Instant file change detection
- 🧠 Returns both old and new state
- ➕ Detects added keys
- ➖ Detects removed keys
- 🔄 Detects changed values
- 📍 Dot-path support
- 🧩 Extensible architecture
- 📄 JSON support built in
- 🏗️ Create custom watchers for your own file formats
Installation
pip install nestwatch
Quick Start
from nestwatch.watchers import JSONWatcher
class ConfigCache:
def __init__(self):
self.watcher = JSONWatcher("data/config.json")
self.watcher.on_change(
self.update_cache
)
async def update_cache(self, event):
# Affected changes only
print(event.added)
print(event.removed)
print(event.changed)
# Reconstructed views)
print(event.old)
print(event.new)
print(event.updated)
async def startup(self):
await self.watcher.start()
Event Object
NestWatch emits an Event object containing:
| Property | Description |
|---|---|
event.added |
Keys that were added (dot-path → value) |
event.removed |
Keys that were removed (dot-path → old value) |
event.changed |
Keys that were modified (old + new) |
event.old |
Partial reconstruction of only affected old values |
event.new |
Partial reconstruction of only affected new values |
event.updated |
Final state after applying the event to the old data |
Event Examples
Suppose this file:
{
"BOT_STATUS": {
"presence": "online",
"activity": {
"type": "playing",
"name": "Roblox"
}
}
}
becomes:
{
"BOT_STATUS": {
"presence": "idle",
"custom": "Watching NestWatch 👀"
},
"API": {
"enabled": true
}
}
Then:
event.added
{
"BOT_STATUS.custom": "Watching NestWatch 👀",
"API.enabled": True
}
event.removed
{
"BOT_STATUS.activity.type": "playing",
"BOT_STATUS.activity.name": "Roblox"
}
event.changed
{
"BOT_STATUS.presence": {
"old": "online",
"new": "idle"
}
}
event.old
{
"BOT_STATUS": {
"presence": "online",
"activity": {
"type": "playing",
"name": "Roblox"
}
}
}
event.new
{
"BOT_STATUS": {
"presence": "idle",
"custom": "Watching NestWatch 👀"
},
"API": {
"enabled": True
}
}
event.updated
{
"BOT_STATUS": {
"presence": "idle",
"custom": "Watching NestWatch 👀"
},
"API": {
"enabled": True
}
}
IMPORTANT NOTE: “These are partial reconstructions of only affected regions, not full file snapshots.”
Creating Custom Watchers
NestWatch is designed to be extensible.
You can support any file format by subclassing "Watcher".
from nestwatch.watchers import Watcher
class MyCustomWatcher(Watcher):
def _serialize(self):
return my_language.load(
self.file_path
)
The Watcher class supports asynchronous serializers as well.
This allows you to perform asynchronous file reads before NestWatch processes the data.
import aiofiles
from nestwatch.watchers import Watcher
class MyCustomWatcher(Watcher):
async def _serialize(self):
async with aiofiles.open(self.file_path) as f:
content = await f.read()
return my_language.load(content)
That's it.
NestWatch will automatically handle:
- Watching the file
- Detecting changes
- Comparing states
- Generating events
- Calling your listeners
Use Cases
NestWatch works especially well for:
- 🤖 Discord bots
- 🌐 FastAPI applications
- 📦 Shared caches
- ⚙️ Configuration files
- 🔄 Runtime reload systems
- 🧠 Multi-application projects
Philosophy
Traditional file watchers answer:
«"Did the file change?"»
NestWatch answers:
«"What changed inside the file?"»
NestWatch's Dependency
| Package | Version | Usage |
|---|---|---|
watchdog |
>=6.0.0 |
Listens for file changes |
aiofiles |
>=25.1.0 |
For reading files in async for internal asynchronous serializers. |
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
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 nestwatch-0.0.6.tar.gz.
File metadata
- Download URL: nestwatch-0.0.6.tar.gz
- Upload date:
- Size: 9.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40f0aaa9280a8593cc82486876bc2b2279b72c3aad1ee70346436ebd34034945
|
|
| MD5 |
e1fe21d59e825a5ccc74808aa15c7ab5
|
|
| BLAKE2b-256 |
03d28f2d14363187a285c068aac5d3a98dab56602f5a2d5c7cc7c22cdc483eb4
|
File details
Details for the file nestwatch-0.0.6-py3-none-any.whl.
File metadata
- Download URL: nestwatch-0.0.6-py3-none-any.whl
- Upload date:
- Size: 8.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5aa8dc83073e9886236a43c72960c4e4979efff729a4c2d8e2c729e51d85316
|
|
| MD5 |
dd859d249d4d0626dc3196a8a743e054
|
|
| BLAKE2b-256 |
ee71a2d11c36dcf6cd04f50e86eff2600f42bc38e30d5c3717f1dfa00b99edf9
|