wxGUI: Support for Jupyter-based workflows#5901
Conversation
be55385 to
817795e
Compare
|
Just set up the discussion page for the notebook working directory topic and workflows topic in general: #5909. |
3a3b7e7 to
55974d3
Compare
968784b to
9d30c42
Compare
65e8ea7 to
08a1f06
Compare
45af740 to
adf7898
Compare
|
Small note: Under Gentoo GNU/Linux distribution I get error message when I hit Start Jupyter Notebook tool button: I have install wxPython 4.x.x version: wxPython x11-libs/wxGTK library USE flags: dev-python/wxpython library USE flags: |
2c2788d to
36fa2c4
Compare
To keep things consistent with the Windows behavior, in 2d7b550 I added a check for wx.html2 as well. When it’s not available, the Jupyter button is disabled and shows a message explaining why. |
|
@tmszi thanks very much for the review! and sorry for the later response. @petrasovaa could you also make the review please so that we can merge it and incorporate this feature to the 8.5 version? |
| python, | ||
| "-m", | ||
| "notebook", |
There was a problem hiding this comment.
This python -m notebook replaced earlier, jupyter notebook. Is that intentional? python -m jupyter notebook would be the equivalent command.
There was a problem hiding this comment.
Yep, it is actually intentional since I had problems with running python -m jupyter notebook for the Standalone installer. For some reason, I still ended up with this output:
C:\Users\karlovskal>"C:\Program Files\GRASS 8.5\extrabin\python3.exe" -m jupyter --version
Selected Jupyter core packages...
IPython : 9.12.0
ipykernel : 7.2.0
ipywidgets : 8.1.8
jupyter_client : 8.8.0
jupyter_core : 5.9.1
jupyter_server : 2.17.0
jupyterlab : 4.5.6
nbclient : 0.10.4
nbconvert : 7.17.1
nbformat : 5.10.4
notebook : 7.5.5
qtconsole : not installed
traitlets : 5.14.3
C:\Users\karlovskal>"C:\Program Files\GRASS 8.5\extrabin\python3.exe" -m jupyter notebook --version
Could not import runpy._run_module_as_main
Traceback (most recent call last):
File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
File "<frozen importlib._bootstrap>", line 1342, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 938, in _load_unlocked
File "<frozen importlib._bootstrap>", line 1179, in exec_module
File "<frozen runpy>", line 14, in <module>
File "C:\Program Files\GRASS 8.5\Python312\Lib\importlib\__init__.py", line 57, in <module>
import warnings
File "C:\Program Files\GRASS [8.5\Python312\Lib\warnings.py"](http://8.0.0.5/Python312/Lib/warnings.py%22), line 591, in <module>
filterwarnings("default", category=DeprecationWarning,
File "C:\Program Files\GRASS [8.5\Python312\Lib\warnings.py"](http://8.0.0.5/Python312/Lib/warnings.py%22), line 155, in filterwarnings
import re
File "C:\Program Files\GRASS 8.5\Python312\Lib\re\__init__.py", line 125, in <module>
from . import _compiler, _parser
File "C:\Program Files\GRASS 8.5\Python312\Lib\re\_compiler.py", line 18, in <module>
assert _sre.MAGIC == MAGIC, "SRE module mismatch"
AssertionError: SRE module mismatch
C:\Users\karlovskal>"C:\Program Files\GRASS 8.5\extrabin\python3.exe" -m notebook --version
7.5.5
I also tried to explicitly install jupyter notebook using C:\Users\karlovskal>"C:\Program Files\GRASS 8.5\extrabin\python3.exe" -m pip install jupyter notebook and the result of above-pasted output was the same. Moreover, after the installation all requirements already satisfied (nothing added), so I have no idea where the problem is (probably some environment problem?)
Anyway, I came to the conclusion that using python -m notebook command is just safer for users.
Interestingly, for the OSGeo4W installer i did not get the same error:
C:\OSGeo4W>python -m jupyter --version
Selected Jupyter core packages...
IPython : 9.11.0
ipykernel : 7.2.0
ipywidgets : 8.1.8
jupyter_client : 8.8.0
jupyter_core : 5.9.1
jupyter_server : 2.17.0
jupyterlab : 4.5.6
nbclient : 0.10.4
nbconvert : 7.17.0
nbformat : 5.10.4
notebook : 7.5.5
qtconsole : not installed
traitlets : 5.14.3
C:\OSGeo4W>python -m jupyter notebook --version
7.5.5
C:\OSGeo4W>python -m notebook --version
7.5.5
See my comment. Is it about which command you are running? Do you need to run that particular command?
You can also install it for the user, e.g. with a dialog/button, if it is that simple. However, here it seems you switch from OSGeo4W packages to pip (even more relevant below for a OSGeo4W install).
Is it
I think it makes more sense to use |
…r.py (replaced by Path writability check)
@wenzeslaus I tested the wxpython pip reinstall also for OSGeo4W instalator and it works as well. So I made two dialogs - the first one installs the notebook if not available and the second one reinstalls wxpython from pip to ensure the webview2 edge runtime support. Tested on standalone as well as OSGeo4W and works great - integrated mode is functional after the restart.
Yep, changed! |
|
@wenzeslaus I created the video how last changes works for the fresh standalone installation (it would look the same for OSGeo4W). cil3.mp4 |
…tall from pip (to make integrated mode available)
8de9431 to
87534c3
Compare
|
I think that it is ready! @petrasovaa, @wenzeslaus, is this PR also ready to merge from your point of view? If yes, please approve it and I will merge it so that it can finally go live! :-) |
| When you choose Integrated mode and WebView2 is not available, GRASS detects | ||
| this and opens a dialog offering to reinstall wxPython using pip. The | ||
| reinstall keeps the currently installed wxPython version, but fetches the pip | ||
| wheel that includes WebView2 support. Clicking **Reinstall** runs: |
There was a problem hiding this comment.
@pesekon2 Thanks for testing! There are two different issues - support for wx.html2 (WebView) (is_wx_html2_available method in utils.py) and presence of Microsoft Edge WebView2 runtime (is_webview2_available method in utilks.py). Your issue is not related to the Microsoft Edge WebView2 runtime support (it is really only the Windows concern); based on the screenshot, it seems like that wx.html2.WebView itself is missing.
This looks like the same problem as @tmszi had during his initial testing #5901 (comment). You are right that currently, I only catch this error - I do not have an environment to reproduce it so unfortunately I do not have a simple fix already in GUI yet, and there is a direct fallback to the browser mode.
Does the reinstalling of wxpython from pip (same as already implemented for Microsoft Edge WebView 2 missing runtime issue) fix it for you? If yes, I can update the code in a same way so that, when this problem occurs, it offers to run the reinstall using this command:
command = "{} -m pip install --force-reinstall wxpython=={}".format(
sys.executable, version
)
If not, do you have a way to get it working in your environment? Were you able to run Integrated mode eventually?
(Btw, these two unrelated issues should be better described in the wx.jupyter.md, now it is a bit confusing.. I will update it).
There was a problem hiding this comment.
I have updated the docs to Microsoft Edge WebView2 runtime issue in d441b60
There was a problem hiding this comment.
My main point with this was that from the docs, it looks like this issue is connected only to Microsoft Edge. As I wun on Debian, I doubt that I have Microsoft Edge installed.
However, I was in the end able to break through today, by installing libwebkit2gtk-4.1-dev (and reinstalling wxPython afterwards).
5054a28 to
5343e33
Compare
…larifying Microsoft Edge WebView2 runtime support in docs + small refinements in docs
5343e33 to
d441b60
Compare
|
Hi @lindakarlovska: I got it working and it looks and behaves nicely. I have just one thing - scrolling through the notebook is very slow for me. How does it work for the others? If it runs smoothly for everybody else, I might just consider it an issue with my laptop (despite the fact that online notebooks scroll just fine) and give it an approval after the docs change mentioned above. |
It works fine for me. |
656a8ac to
98dec92
Compare


This pull request introduces the support for running Jupyter notebooks directly within the GUI.
How it works
There is a new Launch Jupyter Notebook Environment button added to the top menu, right next to the Launch Python Editor button (In this PR, these workflow-related buttons are now grouped together, since all of them serve a similar purpose — working with scripts or automation workflows.)
When you click the Launch Jupyter Notebook button, a new dialog appears — Start Jupyter.
In this dialog, you can:
The working directory is very important because in this directory the Jupyter server will be launched which means that each running Jupyter server is tied to a single directory — meaning that your entire Jupyter session is associated with that directory. If you want to work in a different directory, you simply start another Jupyter session from the GUI.
Besides the selection of a working directory, there’s also an option to create a preconfigured “welcome” notebook (a template). This lets you start working immediately with GRASS and Jupyter already initialized — including automatic imports of GRASS scripting and Jupyter modules, and initialization of the session to match your current GRASS environment.
Once you confirm the dialog:
• A local Jupyter server is started.
• The status bar (bottom left corner) shows information such as the running port and the server PID.
• If you selected the template option, a welcome.ipynb file is created in the chosen working directory, already set up with an initialized GRASS Jupyter session.
Why the Working Directory Matters
A Jupyter server always requires a working directory.
By default, GRASS uses <MAPSET_PATH>/notebooks, since it’s always available and writable. In the first version of this PR, the directory was created automatically inside the mapset.
During the PSC meeting in August 2025 ( https://grasswiki.osgeo.org/wiki/PSC_Meeting_2025-08-08), we decided it would be better to:
That’s why the new Start Jupyter dialog exists — it provides both of these options.
What if Jupyter Isn’t Available?
Two cases are handled:
In both cases, the Launch Jupyter Notebook button will be disabled.
If the user clicks it anyway, an explanatory message will be shown describing the issue.
Windows Support
In version 8.5, the “Launch Jupyter” button will be active only on UNIX systems.
To make it work on Windows (both OSGeo4W and the standalone installer), Jupyter needs to be included in the build process.
That’s not too difficult — Jupyter itself is already included in the standalone installer — but its dependencies (folium and ipyleaflet) are missing from OSGeo4W packages.
I’ve submitted a PR to add them (jef-n/OSGeo4W#36 ) but it’s still awaiting feedback.
Until this is resolved, Jupyter integration won’t be available on Windows in version 8.5.
Implementation Overview
python/grass/workflows/
- directory.py
Contains the JupyterDirectoryManager class, which manages Jupyter notebooks linked to the given working directory.
Responsibilities include mainly: Import/export of .ipynb files and managing notebook templates (welcome.ipynb, new.ipynb).
- server.py
Provides two key classes: JupyterServerInstance which handles the lifecycle of an individual Jupyter server instance—installation check, port management, startup, shutdown, URL generation, etc. Also handles cleanup using atexit and signal handling to ensure servers are terminated when GRASS exits via GUI, exit, CTRL+C, or kill PID. Further, JupyterServerRegistry—a singleton that registers all active Jupyter server instances. It allows the global shutdown of all running servers when GRASS is closed from the GUI.
- enviroment.py
High-level orchestrator JupyterEnvironment integrates a working directory manager (template creation and file discovery), a Jupyter server instance and a registration of running servers in a global server registry
- template_notebooks/
- welcome.ipynb: A welcome notebook created on demand if checked in the Start Jupyter dialog (created only if the working directory is empty – no .ipynb files present)
- new.ipynb: A template used when the user creates a new notebook via GUI
gui/wxpython/jupyter_notebook/
- panel.py - defines the JupyterPanel class, which creates the interactive panel inside the GUI. It includes: A toolbar and an AuiNotebook widget that lists and displays .ipynb files from the working directory
- notebook.py
Class JupyterAuiNotebook—Handles logic for adding AUI notebook tabs with JavaScript injection for hiding the Jupyter File menu and header.
- dialogs.py
Class StartJupyterDialog with Jupyter startup settings.
- toolbars.py
Class JupyterToolbar—Implements the toolbar controls for notebook actions: Create new notebook, Import notebook, Export notebook, Dock/Undock, Quit
Additional Notes
Following steps
For example:
These could become part of a grass.jupyter library.