Skip to content

Add hot reload #731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/_static/images/hot_reload_py.webm
Binary file not shown.
Binary file added docs/_static/images/hot_reload_qss.webm
Binary file not shown.
1 change: 1 addition & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ subtrees:
- entries:
- file: developers/contributing/dev_install
- file: developers/contributing/testing
- file: developers/contributing/hot_reload
- file: developers/contributing/translations
- file: developers/contributing/performance/index
subtrees:
Expand Down
120 changes: 120 additions & 0 deletions docs/developers/contributing/hot_reload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
(napari-hot-reload)=

# Hot reloading in development mode

When working on napari itself or developing plugins, manually restarting the application after every code change can quickly become tedious. To speed up the development cycle, napari supports **hot-reloading**, allowing you to reload code changes on the fly without closing and reopening the app.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When working on napari itself or developing plugins, manually restarting the application after every code change can quickly become tedious. To speed up the development cycle, napari supports **hot-reloading**, allowing you to reload code changes on the fly without closing and reopening the app.
When working on napari or developing plugins, manually restarting the application after every code change can quickly become tedious. To speed up the development cycle, napari supports **hot-reloading** code changes without closing and reopening the app.


## What is hot reloading?

Hot reloading enables napari to automatically reload Python modules during runtime, making development significantly more efficient. With this feature enabled, you can:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Hot reloading enables napari to automatically reload Python modules during runtime, making development significantly more efficient. With this feature enabled, you can:
Hot reloading automatically reloads Python modules during runtime, making napari development significantly more efficient. With this feature enabled, you can:


* Make changes to the napari or napari-builtins source code
* Or make changes to **your** plugin source code (use `--dev_module YOUR_PLUGIN_NAME` to add to list of watched modules)
* Instantly see those changes reflected in the running app
* Avoid repetitive app restarts
Comment on lines +11 to +14
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Make changes to the napari or napari-builtins source code
* Or make changes to **your** plugin source code (use `--dev_module YOUR_PLUGIN_NAME` to add to list of watched modules)
* Instantly see those changes reflected in the running app
* Avoid repetitive app restarts
* Make changes to the napari or napari-builtins source code
* Make changes to **your** plugin source code (use `--dev_module YOUR_PLUGIN_NAME` to add to list of watched modules)
* See changes reflected instantly in the running app
* Avoid repetitive, manual app restarts


Under the hood, this feature uses [qtreload](https://github.com/lukasz-migas/qtreload) a module reloader tailored for Qt-based Python applications.

```{raw} html
<figure>
<video width="100%" controls autoplay loop muted playsinline>
<source src="../../_static/images/hot_reload_qss.webm" type="video/webm" />
<source src="../../_static/images/hot_reload_qss.mp4" type="video/mp4" />
<img src="../../_static/images/hot_reload_qss.png"
title="Your browser does not support the video tag"
alt="PyCharm window and napari viewer side by side. The Pycharm window shows a code editor with a QSS file being edited. Once file is saved, the napari
stylesheet is reloaded and napari viewer is updated with the new style."
>
</video>
</figure>
```

```{raw} html
<figure>
<video width="100%" controls autoplay loop muted playsinline>
<source src="../../_static/images/hot_reload_py.webm" type="video/webm" />
<source src="../../_static/images/hot_reload_py.mp4" type="video/mp4" />
<img src="../../_static/images/hot_reload_py.png"
title="Your browser does not support the video tag"
alt="PyCharm window and napari viewer side by side. The Pycharm window shows a code editor with a Python file being edited. Once file is saved, the user opens a popup window which was updated and the layout has been changed to include a new QLabel. This is repeated again to show that the changes are
applied immediately without restarting napari."
>
</video>
</figure>
```

## How to enable hot reloading

Hot relaoding is enabled when napari is launched in **developer mode**. You can activate developer mode in one of two ways:

Check failure on line 48 in docs/developers/contributing/hot_reload.md

View workflow job for this annotation

GitHub Actions / Check for spelling errors

relaoding ==> reloading
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Hot relaoding is enabled when napari is launched in **developer mode**. You can activate developer mode in one of two ways:
Hot reloading is enabled when napari is launched in **developer mode**. You can activate developer mode in one of two ways:


### Option 1: Command Line Flag

```bash
napari --dev
```

This will set the environment flag so that the `qtreload` widget is activated.

### Option 2: Environment Variable

The `NAPARI_DEV` environment variable can be set to enable developer mode:

```bash
# set environment variable
export NAPARI_DEV=1
# launch napari
napari
```

This is especially useful if you prefer to use your own Python scripts to launch napari.

## Hot reloading your plugin

By default, hot reloading only applies to the napari core libraries (napari and napari-builtins). IF you're working on a plugin and want your changes. to reload as well, you'll need to explicitly include it when launching napari.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
By default, hot reloading only applies to the napari core libraries (napari and napari-builtins). IF you're working on a plugin and want your changes. to reload as well, you'll need to explicitly include it when launching napari.
By default, hot reloading only applies to the napari core libraries (napari and napari-builtins). If you're working on a plugin and want your changes to hot reload as well, you'll need to explicitly include your plugin when launching napari.


### Option 1: Command Line Flag
Use the --dev_module flag to specify additional modules to reload:

```bash
napari --dev --dev_module my_plugin
```

You can add this flag multiple times if you are working on more than one module:

```bash
napari --dev --dev_module my_plugin --dev_module my_other_module
```

### Option 2: Environment Variable

The `NAPARI_DEV_MODULES` environment variable can be used to specify a comma-separated list of modules to watch for changes:

```bash
# set environment variable
export NAPARI_DEV=1
export NAPARI_DEV_MODULES=my_plugin,my_other_module
# launch napari
napari
```

```{admonition} Plugin/module installation
:class: warning

Your plugin/module must already be installed in the environment (e.g. via `pip install -e .` for this to work).
```

## How it works

The `qtreload` system monitors changes to registered modules and reloads them using Python’s import machinery. It watches for changes to the `.py` and `.qss`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The `qtreload` system monitors changes to registered modules and reloads them using Python’s import machinery. It watches for changes to the `.py` and `.qss`.
The `qtreload` system monitors changes to registered modules and reloads them using Python’s import machinery. It watches for changes to `.py` and `.qss` files.


When `.py` file changes, it reloads the file. Here are some useful rules to keep in mind:

* If you've **added** a new function, that function will be added to the class/object.
* If you've **updated** a function, it should just work without issues.
* If you've **added** a new property, that property will be added to the class/object.
* If you've **edited** a property, that change might not be reflected
* If you've **edited** UI, that change will only take effect if you close and reopen the widget that was changed (so main windows will not be changed but if you edit a container for a layer type and then remove and add that layer, the change **will** be reflected)
* code within the `__init__.py` file cannot be reloaded (sorry)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* code within the `__init__.py` file cannot be reloaded (sorry)
* code within the `__init__.py` file cannot be reloaded

* new files are not actively watched - you can manually reload the list of files
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* new files are not actively watched - you can manually reload the list of files
* new files are not actively watched---you can manually reload the list of files


When `.qss` file changes, it emits an event which is handled by the application - in napari's case, it simply reloads the stylesheet and applies it to the entire application.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When `.qss` file changes, it emits an event which is handled by the application - in napari's case, it simply reloads the stylesheet and applies it to the entire application.
When `.qss` file changes, it emits an event which is handled by the application. In the case of napari, it simply reloads the stylesheet and applies it to the entire application.

Loading