Skip to content


watchfiles comes with a CLI for running and reloading code, the CLI uses watchfiles.run_process to run the code and like run_process can either run a python function or a shell-like command.

The CLI can be used either via watchfiles ... or python -m watchfiles ....

Running and restarting a python function

Let's say you have (in this case a very simple web server using aiohttp) which gets details about recent file changes from the WATCHFILES_CHANGES environment variable (see run_process docs) and returns them as JSON.
import os, json
from aiohttp import web

async def handle(request):
    # get the most recent file changes and return them
    changes = os.getenv('WATCHFILES_CHANGES')
    changes = json.loads(changes)
    return web.json_response(dict(changes=changes))

app = web.Application()
app.router.add_get('/', handle)

def main():
    web.run_app(app, port=8000)

You could run this and reload it when any file in the current directory changes with:

Running a python function
watchfiles foobar.main

Running and restarting a command

Let's say you want to re-run failing tests whenever files change. You could do this with watchfiles using

Running a command
watchfiles 'pytest --lf'

(pytest's --lf option is a shortcut for --last-failed, see pytest docs)

By default the CLI will watch the current directory and all subdirectories, but the directory/directories watched can be changed.

In this example, we might want to watch only the src and tests directories, and only react to changes in python files:

Watching custom directories and files
watchfiles --filter python 'pytest --lf' src tests


Run watchfiles --help for more options.

watchfiles --help
usage: watchfiles [-h] [--ignore-paths [IGNORE_PATHS]]
                  [--target-type [{command,function,auto}]]
                  [--filter [FILTER]] [--args [ARGS]] [--verbose]
                  [--non-recursive] [--verbosity [{warning,info,debug}]]
                  [--sigint-timeout [SIGINT_TIMEOUT]]
                  [--sigkill-timeout [SIGKILL_TIMEOUT]] [--version]
                  target [paths ...]

Watch one or more directories and execute either a shell command or a python function on file changes.

Example of watching the current directory and calling a python function:

    watchfiles foobar.main

Example of watching python files in two local directories and calling a shell command:

    watchfiles --filter python 'pytest --lf' src tests

See for more information.

positional arguments:
  target                Command or dotted function path to run
  paths                 Filesystem paths to watch, defaults to current directory

  -h, --help            show this help message and exit
  --ignore-paths [IGNORE_PATHS]
                        Specify directories to ignore, to ignore multiple paths use a comma as separator, e.g. "env" or "env,node_modules"
  --target-type [{command,function,auto}]
                        Whether the target should be intercepted as a shell command or a python function, defaults to "auto" which infers the target type from the target string
  --filter [FILTER]     Which files to watch, defaults to "default" which uses the "DefaultFilter", "python" uses the "PythonFilter", "all" uses no filter, any other value is interpreted as a python function/class path which is imported
  --args [ARGS]         Arguments to set on sys.argv before calling target function, used only if the target is a function
  --verbose             Set log level to "debug", wins over `--verbosity`
  --non-recursive       Do not watch for changes in sub-directories recursively
  --verbosity [{warning,info,debug}]
                        Log level, defaults to "info"
  --sigint-timeout [SIGINT_TIMEOUT]
                        How long to wait for the sigint timeout before sending sigkill.
  --sigkill-timeout [SIGKILL_TIMEOUT]
                        How long to wait for the sigkill timeout before issuing a timeout exception.
  --version, -V         show program's version number and exit