Skip to content

Commit

Permalink
improving the readme and pypi links
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin committed Apr 2, 2022
1 parent 90a149d commit 62994db
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 119 deletions.
151 changes: 34 additions & 117 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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

Expand All @@ -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 ...`.
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)

0 comments on commit 62994db

Please sign in to comment.