You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`arel` can be used to implement development-only hot-reload for non-Python files that are not read from disk on each request. This may include HTML templates, GraphQL schemas, cached rendered Markdown content, etc.
17
-
18
-
**How does it work?**
19
-
20
-
`arel` watches changes over a set of files. When a file changes, `arel` notifies the browser (using WebSocket), and an injected client script triggers a page reload. You can register your own reload hooks for any extra server-side operations, such as reloading cached content or re-initializing other server-side resources.
14
+
*[Installation](#installation)
15
+
*[Quickstart](#quickstart)
16
+
*[Usage](#usage)
17
+
*[How does this work?](#how-does-this-work)
18
+
*[Example](#example)
19
+
*[API Reference](#api-reference)
21
20
22
21
## Installation
23
22
@@ -27,60 +26,158 @@ pip install 'arel==0.2.*'
27
26
28
27
## Quickstart
29
28
30
-
_For a working example using Starlette, see the [Example](#example) section._
Save this file as `main.py`, then start a server, e.g. with [Uvicorn](https://uvicorn.org):
31
60
32
-
Although the exact instructions to set up hot reload with `arel` depend on the specifics of your ASGI framework, there are three general steps to follow:
61
+
```console
62
+
$ uvicorn main:app --reload
63
+
```
33
64
34
-
1. Create an `HotReload` instance, passing one or more directories of files to watch, and optionally a list of callbacks to call before a reload is triggered:
65
+
Open http://localhost:8000. Now change the HTML content in `main.py`, and hit save. The browser should reload the page automatically!
By default, [`HotReloadMiddleware`](#hotreloadmiddleware) only watches for server disconnects, and reloads the page when the server comes back up.
49
72
50
-
2. Mount the hot reload endpoint, and register its startup and shutdown event handlers. If using Starlette, this can be done like this:
73
+
This should play nicely with the server reload features of your ASGI server of choice (Uvicorn, Hypercorn, Daphne...).
74
+
75
+
### Reloading on non-Python files
76
+
77
+
`arel` can watch an arbitrary set of directories and trigger browser reloads when changes are detected. This can be used to reload in case of changes to static files, HTML templates, GraphQL schemas, etc.
78
+
79
+
To do so, use the `paths` option, which expects a list of [`Path`](#path) instances:
You can register extra reload hooks to run extra server-side operations before triggering the browser reload, such as reloading cached content or re-initializing other server side resources.
62
93
63
-
3. Add the JavaScript code to your website HTML. If using [Starlette with Jinja templates](https://www.starlette.io/templates/), you can do this by updating the global environment, then injecting the script into your base template:
94
+
```python
95
+
asyncdefreload_data():
96
+
print("Reloading server data...")
64
97
65
-
```python
66
-
templates.env.globals["DEBUG"] = os.getenv("DEBUG") # Development flag.
`HotReloadMiddleware` provides a few different things:
135
+
136
+
* File watching over the provided `paths=...`.
137
+
* A WebSocket endpoint that notifies the browser when changes are detected.
138
+
* A JavaScript snippet which connects to the WebSocket endpoint and performs page reloads.
139
+
140
+
The JS code is automatically inserted by the middleware into any HTML response returned by the application. This should make `arel` work automatically with both your own HTML endpoints as well as third-party endpoints, such as Swagger UI documentation provided by FastAPI.
141
+
142
+
If the server disconnects, the JavaScript snippet will also refresh the page when reconnecting. This allows integration with ASGI servers that have reload functionality for the Python source code.
143
+
144
+
`HotReloadMiddleware` is a [pure ASGI](https://www.starlette.io/middleware/#pure-asgi-middleware) middleware, so you should be able to use it with any ASGI framework, including Starlette, FastAPI, or Quart.
80
145
81
146
## Example
82
147
83
-
The [`example` directory](https://github.com/florimondmanca/arel/tree/master/example) contains an example Markdown-powered website that uses `arel` to refresh the browser when Markdown content or HTML templates change.
148
+
The [`example` directory](https://github.com/florimondmanca/arel/tree/master/example) contains an example Markdown-powered website. It uses `arel` to refresh the browser when Markdown content or HTML templates change.
149
+
150
+
To spin up this example server, run:
151
+
152
+
```
153
+
make serve
154
+
```
155
+
156
+
Then visit http://localhost:8000. The web console will show you that your browser has connected to `arel`.
157
+
158
+
Now, add, edit or delete one of the Markdown files in `pages/`. The page should refresh automatically.
159
+
160
+
Lastly, try changing one of the Python files in `example/server/`, then hit save to trigger a server reload. Again, the browser should automatically refresh the page.
161
+
162
+
## API Reference
163
+
164
+
### `HotReloadMiddleware`
165
+
166
+
```python
167
+
app = HotReloadMiddleware(app, ...)
168
+
```
169
+
170
+
Parameters:
171
+
172
+
*`app` - The parent ASGI app.
173
+
*`paths` - _(Optional)_`list[Path]` - A list of [`Path`](#path) instances to watch files over.
174
+
175
+
### `Path`
176
+
177
+
Parameters:
178
+
179
+
*`path` - `Union[str, pathlib.Path]` - The path to watch files over. Supports paths relative to the current working directory, such as `"./templates"`. Glob patterns are not supported.
180
+
*`on_reload` - _(Optional)_`Sequence[async () -> None]` - A list of async callbacks to run when changes are detected on this path.
0 commit comments