Skip to main content

NestWatch

Python

License

PyPI

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_state 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_state

{
    "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.

Release files for nestwatch 0.0.11

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nestwatch 0.0.11
File Size Uploaded
nestwatch-0.0.11.tar.gz 9.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nestwatch 0.0.11
File Interpreter ABI Platform
nestwatch-0.0.11-py3-none-any.whl Python 3 none any Details

Total release size: 18.5 kB

Release files / nestwatch-0.0.11.tar.gz

Download URL nestwatch-0.0.11.tar.gz
Size 9.4 kB
Tags Source
SHA-256 checksum
How to use checksums
52616c334c1ec47496a2831a42338e6e25f905832248390694a5859145be5d16
BLAKE2b-256 checksum
How to use checksums
28fe99945ecb8f942b4e3fb527a7fae2be787d6686fdf1fe42ad99a270e2a6c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.14

Release files / nestwatch-0.0.11-py3-none-any.whl

Download URL nestwatch-0.0.11-py3-none-any.whl
Size 9.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
17e28cd795d79bf789deb2d0f0bc570032754933386b755a04f00a812262fd18
BLAKE2b-256 checksum
How to use checksums
9f96f92720f37bc88414b93a1808f0090db2c639f0e2751f65ef48846c1a1235
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.14

Release history Release notifications | RSS feed

This release

0.0.11 This release

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page