-
Notifications
You must be signed in to change notification settings - Fork 54
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
lukasz-migas
wants to merge
7
commits into
napari:main
Choose a base branch
from
lukasz-migas:add-hot-reload
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Add hot reload #731
Changes from 5 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
ec0a6d5
Create hot_reload.md
lukasz-migas 8a5138d
add videos
lukasz-migas e92e0df
Update _toc.yml
lukasz-migas b2c7ed5
Update hot_reload.md
lukasz-migas 3f9be1a
Update hot_reload.md
lukasz-migas 29606e9
Apply suggestions from code review
willingc b04ddd1
Merge branch 'main' into add-hot-reload
willingc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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. | ||
|
|
||
| ## 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: | ||
|
willingc marked this conversation as resolved.
Outdated
|
||
|
|
||
| * 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 | ||
|
willingc marked this conversation as resolved.
Outdated
|
||
|
|
||
| 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: | ||
|
willingc marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### 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. | ||
|
willingc marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### 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`. | ||
|
willingc marked this conversation as resolved.
Outdated
|
||
|
|
||
| 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) | ||
|
willingc marked this conversation as resolved.
Outdated
|
||
| * new files are not actively watched - you can manually reload the list of files | ||
|
willingc marked this conversation as resolved.
Outdated
|
||
|
|
||
| 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. | ||
|
willingc marked this conversation as resolved.
Outdated
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.