Skip to main content

Simple, modern file watching and code reload in python.

Project description

BuildStatus Coverage pypi

Simple, modern file watching and code reload in python.

Usage

To watch for changes in a directory:

from watchgod import watch

for changes in watch('./path/to/dir'):
    print(changes)

To run a function and restart it when code changes:

from watchgod import run_process

def foobar(a, b, c):
    ...

run_process('./path/to/dir', foobar, process_args=(1, 2, 3))

run_process uses PythonWatcher so only changes to python files will prompt a reload, see custom watchers below.

If you need notifications about change events as well as to restart a process you can use the callback argument to pass a function will will be called on every file change with one argument: the set of file changes.

Asynchronous Methods

watchgod comes with an asynchronous equivalents of watch: awatch which uses a ThreadPoolExecutor to iterate over files.

import asyncio
from watchgod import awatch

async def main():
    async for changes in awatch('/path/to/dir'):
        print(changes)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

There’s also an asynchronous equivalents of run_process: arun_process which in turn uses awatch:

import asyncio
from watchgod import arun_process

def foobar(a, b, c):
    ...

async def main():
    await arun_process('./path/to/dir', foobar, process_args=(1, 2, 3))

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

arun_process uses PythonWatcher so only changes to python files will prompt a reload, see custom watchers below.

The signature of arun_process is almost identical to run_process except that the callback argument if provide must be a coroutine, not a function.

Custom Watchers

watchgod comes with the following watcher classes which can be used via the watcher_cls keyword argument to any of the methods above.

For more details, checkout watcher.py, it’s pretty simple.

AllWatcher

The base watcher, all files are checked for changes.

DefaultWatcher

The watcher used by default by watch and awatch, commonly ignored files like *.swp, *.pyc and *~ are ignored along with directories like .git.

PythonWatcher

Specific to python files, only *.py, *.pyx and *.pyd files are watched.

DefaultDirWatcher

Is the base for DefaultWatcher and DefaultDirWatcher and takes care of ignoring some regular directories.

If these classes aren’t sufficient you can define your own watcher, in particular you will want to override should_watch_dir and should_watch_file. Unless you’re doing something very odd you’ll want to inherit from DefaultDirWatcher.

Why no inotify / kqueue / fsevent / winapi support

watchgod (for now) uses file polling rather than the OS’s built in file change notifications.

This is not an oversight, it’s a decision with the following rationale:

  1. Polling is “fast enough”, particularly since PEP 471 introduced fast scandir.

    With a reasonably large project like the TutorCruncher code base with 850 files and 300k lines of code watchdog can scan the entire tree in ~24ms. With a scan interval of 400ms that’s roughly 5% of one CPU - perfectly acceptable load during development.

  2. The clue is in the title, there are at least 4 different file notification systems to integrate with, most of them not trivial. And that’s before we get to changes between different OS versions.

  3. Polling works well when you want to group or “debounce” changes.

    Let’s say you’re running a dev server and you change branch in git, 100 files change. Do you want to reload the dev server 100 times or once? Right.

    Polling periodically will likely group these changes into one event. If you’re receiving a stream of events you need to delay execution of the reload when you receive the first event to see if it’s part of a whole bunch of file changes, this is not completely trivial.

All that said, I might still implement inotify support. I don’t use anything other than Linux so I definitely won’t be working on dedicated support for any other OS.

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

watchgod-0.0.1.tar.gz (6.2 kB view details)

Uploaded Source

Built Distribution

watchgod-0.0.1-py35,py36-none-any.whl (9.4 kB view details)

Uploaded Python 3.5,py36

File details

Details for the file watchgod-0.0.1.tar.gz.

File metadata

  • Download URL: watchgod-0.0.1.tar.gz
  • Upload date:
  • Size: 6.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for watchgod-0.0.1.tar.gz
Algorithm Hash digest
SHA256 a49d846c094a734fc1a4bca46172885ca0b5c1278c0d0f45c54e81ae749cb93d
MD5 66dd288c649aa5c33ba44dc29195003b
BLAKE2b-256 120d69e08a213c0d096c74b57b419511b9e3443b6246caceadc05d8a78364360

See more details on using hashes here.

Provenance

File details

Details for the file watchgod-0.0.1-py35,py36-none-any.whl.

File metadata

File hashes

Hashes for watchgod-0.0.1-py35,py36-none-any.whl
Algorithm Hash digest
SHA256 d1bed30f8a3564cc70a535e52fc3f66420dfb07433d3bc2572bd6ba8d709c7c0
MD5 e6b6f856e181d9cabb4ed66a2598e578
BLAKE2b-256 42a2177d9b564f4df3ccfa764f1e2235af518e0b21f7f028f4346aea60bade50

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page