From 62994db2d56d487dab7200278803a584532e4044 Mon Sep 17 00:00:00 2001 From: Samuel Colvin Date: Sat, 2 Apr 2022 10:56:07 +0100 Subject: [PATCH] improving the readme and pypi links --- README.md | 151 ++++++++++++-------------------------------------- docs/index.md | 4 +- setup.py | 6 ++ 3 files changed, 42 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index eb2fe2ed..28881af5 100644 --- a/README.md +++ b/README.md @@ -9,18 +9,17 @@ Simple, modern and high performance file watching and code reload in python. --- -## NOTICE +**Documentation**: [watchfiles.helpmanual.io](https://watchfiles.helpmanual.io) -This package was significantly altered and renamed from `watchgod` to `watchfiles`, this files refers to the -`watchfiles` package. - -Documentation for the old version (`watchgod`) is available [here](/~https://github.com/samuelcolvin/watchfiles/tree/watchgod). -See [issue #102](/~https://github.com/samuelcolvin/watchfiles/issues/102) for details on the migration and its rationale. +**Source Code**: [github.com/samuelcolvin/watchfiles](/~https://github.com/samuelcolvin/watchfiles) --- Underlying file system notifications are handled by the [Notify](/~https://github.com/notify-rs/notify) rust library. +This package was previously named "watchgod", +see [the migration guide](https://watchfiles.helpmanual.io/migrating/) for more information. + ## Installation **watchfiles** requires Python 3.7 - 3.10. @@ -38,44 +37,21 @@ Otherwise, you can install from source which requires Rust stable to be installe ## Usage -To watch for changes in a directory: +Here are some examples of what **watchfiles** can do: -```python +### `watch` Usage + +```py from watchfiles import watch for changes in watch('./path/to/dir'): print(changes) ``` +See [`watch` docs](https://watchfiles.helpmanual.io/api/watch/#watchfiles.watch) for more details. -`watch` (and all other methods described below) can take multiple paths as arguments to watch. - -To run a function and restart it when code changes: - -```python -from watchfiles import run_process - -def foobar(a, b, c): - ... - -if __name__ == '__main__': - run_process('./path/to/dir', target=foobar, args=(1, 2, 3)) -``` - -`run_process` uses `PythonFilter` by default so only changes to python files will prompt a reload, -see **custom event filtering** below. +### `awatch` Usage -If you need notifications about change events as well as to restart a process you can -use the `callback` argument to pass a function which will be called on every file change -with one argument: the set of file changes. - -File changes are also available via the `WATCHFILES_CHANGES` environment variable which contains JSON encoded -details of changes, see the CLI example below. - -### Asynchronous Methods - -*watchfiles* comes with an asynchronous equivalents of `watch`: `awatch`. - -```python +```py import asyncio from watchfiles import awatch @@ -85,105 +61,46 @@ async def main(): asyncio.run(main()) ``` +See [`awatch` docs](https://watchfiles.helpmanual.io/api/watch/#watchfiles.awatch) for more details. -There's also an asynchronous equivalents of `run_process`: `arun_process` which in turn -uses `awatch`: +### `run_process` Usage -```python -import asyncio -from watchfiles import arun_process +```py +from watchfiles import run_process def foobar(a, b, c): ... -async def main(): - await arun_process('./path/to/dir', target=foobar, args=(1, 2, 3)) - if __name__ == '__main__': - asyncio.run(main()) -``` - -The signature of `arun_process` is almost identical to `run_process` except that -the optional `callback` argument may be a coroutine. - -## Custom Filters - -The `watch_filter` argument to the above methods allows you to specify which file system events **watchfiles** should -react to (either yield or reload code). `watch_filter` should just be a callable which takes a change -(either "added", "modified" or "deleted") and a path (as a string) and should return whether or not that change -should be registered. - -*watchfiles* comes with the following classes, instances of which can be with `watch_filter`: - -* **`DefaultFilter`** The watcher used by default by `watch` and `awatch`, commonly ignored files - like `*.swp`, `*.pyc` and `*~` are ignored along with directories like - `.git`. -* **`PythonFilter`** Specific to python files, only `*.py`, `*.pyx` and `*.pyd` files are watched. -* **`BaseFilter`**, used by `DefaultFilter` and `PythonFilter`, useful for defining your own filters which leverage - the same logic - -Here's an example of a custom filter which extends `DefaultFilter` to only notice changes to common web files: - -```python -from watchfiles import Change, DefaultFilter, watch - - -class WebFilter(DefaultFilter): - allowed_extensions = '.html', '.css', '.js' - - def __call__(self, change: Change, path: str) -> bool: - return super().__call__(change, path) and path.endswith(self.allowed_extensions) - -for changes in watch('my/web/project', watch_filter=WebFilter()): - print (changes) + run_process('./path/to/dir', target=foobar, args=(1, 2, 3)) ``` +See [`run_process` docs](https://watchfiles.helpmanual.io/api/run_process/#watchfiles.run_process) for more details. -Here's an example of a customer filter which is a simple callable that ignores changes unless they represent -a new file being created: +### `arun_process` Usage ```py -from watchfiles import Change, watch +import asyncio +from watchfiles import arun_process -def only_added(change: Change, path: str) -> bool: - return change == Change.added +def foobar(a, b, c): + ... -for changes in watch('my/project', watch_filter=only_added): - print (changes) -``` +async def main(): + await arun_process('./path/to/dir', target=foobar, args=(1, 2, 3)) -For more details, checkout -[`filters.py`](/~https://github.com/samuelcolvin/watchfiles/blob/main/watchfiles/filters.py), -it's pretty simple. +if __name__ == '__main__': + asyncio.run(main()) +``` +See [`arun_process` docs](https://watchfiles.helpmanual.io/api/run_process/#watchfiles.arun_process) for more details. ## CLI -*watchfiles* also comes with a CLI for running and reloading python code. +**watchfiles** also comes with a CLI for running and reloading code. -Let's say you have `foobar.py` (this is a very simple web server using -[aiohttp](https://aiohttp.readthedocs.io/en/stable/)) which gets details about recent file changes from the -`WATCHFILES_CHANGES` environment variable and returns them as JSON. +For more information, see [the CLI docs](https://watchfiles.helpmanual.io/cli/). -```python -import os, json -from aiohttp import web +Or run -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) +```bash +watchfiles --help ``` - -You could run this and reload it when any file in the current directory changes with: - - watchfiles foobar.main - -Run `watchfiles --help` for more options. - -The CLI can also be used via `python -m watchfiles ...`. diff --git a/docs/index.md b/docs/index.md index 9bdbd679..25af2a3c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,7 +11,7 @@ Simple, modern and high performance file watching and code reload in python. Underlying file system notifications are handled by the [Notify](/~https://github.com/notify-rs/notify) rust library. -This package used to be called "watchgod", see [Migrating from watchgod](./migrating.md) for more information. +This package was previously named "watchgod", see [Migrating from watchgod](./migrating.md) for more information. ## Usage @@ -85,7 +85,7 @@ Otherwise, you can install from source which requires Rust stable to be installe ## How Watchfiles Works -*watchfiles* is based on the [Notify](/~https://github.com/notify-rs/notify) rust library. +**watchfiles** is based on the [Notify](/~https://github.com/notify-rs/notify) rust library. All the hard work of integrating with the OS's file system events notifications and falling back to polling is palmed off onto the rust library. diff --git a/setup.py b/setup.py index 33711fbf..17cd3411 100644 --- a/setup.py +++ b/setup.py @@ -61,5 +61,11 @@ install_requires=['anyio>=3.0.0,<4'], python_requires='>=3.7', zip_safe=False, + project_urls={ + 'Documentation': 'https://watchfiles.helpmanual.io', + 'Funding': '/~https://github.com/sponsors/samuelcolvin', + 'Source': '/~https://github.com/samuelcolvin/watchfiles', + 'Changelog': '/~https://github.com/samuelcolvin/watchfiles/releases', + }, **extra, )