Releases: zauberzeug/nicegui
v3.0.4
Bugfixes
- Fix exception handling when emitting or calling events (#5250 by @falkoschindler)
- Fix emitting and calling chained events (#5238 by @falkoschindler)
- Avoid unsubscribing events during reconnect (#5239 by @falkoschindler, @evnchn, @rodja)
- Fix timer exception handlers not being called in UI context (#5218, #5253 by @sopipe, @evnchn, @falkoschindler)
Documentation
- Add a demo for placing buttons in
ui.table
rows (#5150 by @Mogit21, @evnchn, @falkoschindler)
Infrastructure
- Upload screenshots of failed tests in CI pipeline (#5234, #5251 by @evnchn, @falkoschindler, @rodja)
- Add CPython 3.14 to the CI pipeline (#5243 by @evnchn)
- Move vbuild into our repository (#5255 by @falkoschindler)
v3.0.3
Bugfixes
- Fix bugs related to the new
Event
system (#5216, #5221 by @v479038280, @python-and-novella, @falkoschindler)- fix event subscription in script mode
- fix event subscription outside of page functions
- fix memory leak
- provide more meaningful demos
- Fix support for Redis Unix-Domainsocket-connections (#5214 by @senfomat, @falkoschindler, @evnchn)
Documentation
Infrastructure
v3.0.2
This release fixes the Docker image which failed to build for version 3.0.1.
v3.0.1
Bugfixes
- Respect
show_404=False
inui.sub_pages
navigation (#5199 by @rodja, @falkoschindler) - Fix docker builds by not excluding dist/ directories from the build context (#5200, #5202 by @Yuerchu, @rodja, @falkoschindler)
Testing
- Check disabled state before clicking or clearing via user simulated interaction (#5191, #5209 by @igro-marczak, @rodja)
- Make
user.should_see
work with icon and chat message names (#5183, #5184 by @phifuh, @rodja)
Documentation
- Fix menu by disabling the deselection of tree elements (#5207, #5208 by @python-and-novella, @rodja)
- Fix custom toggle button demo (#5203 by @rodja)
Infrastructure
v3.0.0
This major release introduces several new features and enhancements, as well as breaking changes. We always try to keep breaking changes to a minimum, guide you through the migration process using deprecation warnings, and provide migration instructions. Please read the following release notes carefully to understand the changes and adapt your code accordingly before upgrading.
New features and enhancements
- Introduce NiceGUI script mode to replace the awkward auto-index page (#5005 by @rodja, @falkoschindler)
- Introduce
root
page parameter forui.run
to simplify single-page applications (#4964, #5005 by @rodja, @falkoschindler) - Introduce an
Event
system to communicate between UI and long-living objects (#5107 by @falkoschindler, @denniswittich) - Simplify pytests by loading a main file with runpy (#5102 by @rodja, @falkoschindler)
- Make props, classes and style observable to send updates automatically (#4978 by @lawrenceakka, @falkoschindler, @rodja)
- Improve node package management, including a new
esm
Parameter for custom elements (#4163, #5021 by @simontaurus, @evnchn, @falkoschindler) - Upgrade to Tailwind 4 (#5057 by @falkoschindler)
- Drop support for Python 3.8 (#4329 by @Solipsistmonkey, @falkoschindler)
- Introduce
ValueChangeEventArguments.previous_value
(#4410, #4456 by @me21, @falkoschindler, @evnchn) - Introduce a
strict
option for binding methods (#5040 by @denniswittich, @codingpaula, @falkoschindler) - Introduce a
sanitize
argument forui.html
andui.chat_message
(#5187 by @oxqnd, @falkoschindler, @rodja, @evnchn) - Improve support for languages with right-to-left text direction (#5045, #5058 by @M6stafa, @falkoschindler)
- Use
q-scroll_area
forui.log
to preserve a fixed height (#4925, #4935 by @e-nesse, @falkoschindler) - Let
ui.clipboard.read()
returnNone
if the clipboard API isn't available (#4236, #4237 by @weinibuliu, @falkoschindler, @evnchn) - Call lifecycle event handlers more consistently (#5173 by @falkoschindler, @evnchn, @rodja)
- Improve
UploadEventArguments
andMultiUploadEventArguments
to avoid unclosed resources (#5178 by @rodja, @evnchn, @falkoschindler) - Re-initialize the process pool if it was broken by a bad
run.cpu_bound
(#4980, #5129 by @jammerhund, @evnchn, @rodja, @falkoschindler) - Remove deprecated code and APIs (#5037 by @falkoschindler)
- Treat pytest warnings as errors (#5182, #5186 by @evnchn, @rodja, @falkoschindler)
⚠️ Breaking changes and migration guide
-
Shared auto-index pages (not using
@ui.page
)UI elements defined in global scope have been added to a static shared "auto-index client" served at "/". This caused a multitude of problems throughout the code base, so we decided to remove this shared client.
In version 3.0 you have the following options:
-
Keep putting (all) UI elements in global scope. We call such apps without page functions "NiceGUI scripts". They will automatically re-evaluated inside an implicit page function when visiting "/". This is almost a drop-in replacement for the auto-index client, but:
- NiceGUI scripts can't contain page functions.
- The UI isn't shared but re-created on every page visit.
-
Wrap all UI in a singe function and pass it to the new positional
root
parameter inui.run
. This is especially handy in combination withui.sub_pages
. This way you can create rich single-page applications without worrying about defining the correct routes with@page
decorators. -
Use page functions for all your pages, including the index page at "/".
Note that we are introducing a new
Event
class. Together with the binding module this helps to synchronize long-living objects with short-living UI without relying on a long-living shared client. -
-
Calling
.props()
,.classes()
or.style()
with subsequent.update()
A subsequent
.update()
is not necessary anymore because props, classes and style are now observable collections that trigger updates automatically.When overwriting the
update
method in custom elements, infinite recursions can occur. If, e.g., theupdate
methods uses.prop()
before callingsuper().update()
, the.prop()
call will cause an infinite cycle. Wrap it withwith self._props.suspend_updates():
(and similar for classes and style) to pause automatic updates in such cases. -
Modifying the content of
ui.table
,ui.aggrid
,ui.echart
,ui.highchart
, andui.json_editor
Before NiceGUI 3.0 it was possible create tables or AG Grids like
ui.table(columns=columns, rows=rows, ...)
orui.aggrid({'columnDefs': columns, 'rowData': rows, ...)
and update it later by modifying the originalcolumns
orrows
. This is not possible anymore.In NiceGUI 3.0 you need to modify
table.rows
,table.columns
oraggrid.options
instead. A subsequenttable.update()
oraggrid.update
is not necessary anymore.Same holds for
ui.echart
,ui.highchart
andui.json_editor
. -
Upgrade to Tailwind 4; dropping the
ui.element.tailwind
APIAlthough very similar, Tailwind 4 comes with some breaking changes. Check your layout carefully after upgrading. We noticed differences especially with line spacing and borders.
Custom style definitions of Quasar elements might need to be adjusted. Because all Tailwind and Quasar CSS has moved into layers, custom overrides need to move as well. See #5240 for more information.
For technical reasons updating and maintaining our
ui.element.tailwind
API became unfeasible. So we decided to remove it. For auto-completing Tailwind classes, we recommend the NiceGUI extension for Visual Studio Code by @DaelonSuzuka. -
Dropping support for Python 3.8
Almost one year after Python 3.8 reached its end-of-life, it was time to drop support. This allowed us to update the code to a newer standard and resolve some issues with Python dependencies that already dropped 3.8 a while ago.
-
ValueChangeEventArguments
got a newprevious_value
attributeIn some situations it might be helpful to have access to both, the current and the previous value. Therefore we added
previous_value
to theValueChangeEventArguments
.Custom elements that emit
ValueChangeEventArguments
need to provide the previous value. -
Binding from and to non-existing object properties
Binding used to fail silently if one of the attributes doesn't exist. In case of dictionaries this was intended, because they are often used to bind to persistent storage which is empty by default. But for object properties this can lead to very subtle bugs, e.g. after renaming properties and not updating the attribue names in binding functions.
In 3.0 object properties will be checked for existence by default. Missing dictionaries will continue to be ignored.
You can fine-tune this behavior using the
strict: bool | None = None
parameter (None
: check object properties and ignore dictionaries). -
Sanitize content for
ui.html
andui.chat_message
To prevent NiceGUI apps from accidentally displaying unsafe user input as HTML,
ui.html
andui.chat_message
now have asanitize
argument. It can be set to a function likeSanitizer().sanitize
from the html-sanitizer module, orFalse
to disable sanitization. Whileui.html
requires the new argument to be specified,ui.chat_message
only requires it iftext_html=True
.Note that the html-sanitizer module is not included in NiceGUI and needs to be installed separately is needed.
-
ui.log
with unspecified width can collapse inside containers with unspecified widthWe noticed that the height of
ui.log
could be affected by its content, which is unexpected. Therefore we decided to use a scroll area for a more robust layout.Now the width of
ui.log
can collapse when placed inside a container with an unspecified width. Either give the container some width or specify the width ofui.log
. -
ui.clipboard.read()
returnsNone
if the clipboard API isn't availableThe
read()
function used to return an empty string if the clipboard API is not available. This was indistinguishable from an empty clipboard.Now the
read()
function returnsNone
if the clipboard API is not available. -
Lifecycle events are called more consistently
Handlers registered with
on_disconnect
used to be called only after the client fails to reconnect and is deleted.Now disconnect handlers are immediatelly called when a connection is lost, even if the client reconnects after a short while.
A new
on_delete
function can be used to register callbacks for the deletion of a client. -
UploadEventArguments
andMultiUploadEventArguments
have changedInstead of
content: BinaryIO
,name: str
andtype: str
the event arguments now contain a single fieldfile: FileUpload
, which contains- properties
name: str
andcontent_type: str
as well as - methods `...
- properties
v2.24.2
Bugfixes
- Avoid JavaScript error when creating
ui.aggrid
without custom grid-ready handler (#5141, #5143 by @ZiyadBastaili, @evnchn, @falkoschindler) - Properly close
ui.sub_pages
render coroutine on cancellation (#5142, #5145 by @platinops, @evnchn, @python-and-novella, @rodja)
Dependencies
- Bump actions/setup-python from 5 to 6 (#5121 by @dependabot)
v2.24.1
v3.0.0rc1
New features and enhancements
- Introduce NiceGUI script mode to replace the awkward auto-index page (#5005 by @rodja, @falkoschindler)
- Introduce
root
page parameter forui.run
to simplify single-page applications (#4964, #5005 by @rodja, @falkoschindler) - Introduce an
Event
system to communicate between UI and long-living objects (#5107 by @falkoschindler, @denniswittich) - Simplify pytests by loading a main file with runpy (#5102 by @rodja, @falkoschindler)
- Make props, classes and style observable to send updates automatically (#4978 by @lawrenceakka, @falkoschindler, @rodja)
- Upgrade to Tailwind 4 (#5057 by @falkoschindler)
- Drop support for Python 3.8 (#4329 by @Solipsistmonkey, @falkoschindler)
- Introduce
ValueChangeEventArguments.previous_value
(#4410, #4456 by @me21, @falkoschindler, @evnchn) - Introduce a
strict
option for binding methods (#5040 by @denniswittich, @codingpaula, @falkoschindler) - Improve support for languages with right-to-left text direction (#5045, #5058 by @M6stafa, @falkoschindler)
- Use
q-scroll_area
forui.log
to preserve a fixed height (#4925, #4935 by @e-nesse, @falkoschindler) - Let
ui.clipboard.read()
returnNone
if the clipboard API isn't available (#4236, #4237 by @weinibuliu, @falkoschindler, @evnchn) - Remove deprecated code and APIs (#5037 by @falkoschindler)
⚠️ Breaking changes and migration guide
We always try to keep breaking changes to a minimum, guide you through the migration process using deprecation warnings, and provide migration instructions. Please read the following release notes carefully to understand the changes and adapt your code accordingly before upgrading.
-
Shared auto-index pages (not using
@ui.page
)UI elements defined in global scope have been added to a static shared "auto-index client" served at "/". This caused a multitude of problems throughout the code base, so we decided to remove this shared client.
In version 3.0 you have the following options:
-
Keep putting (all) UI elements in global scope. We call such apps without page functions "NiceGUI scripts". They will automatically re-evaluated inside an implicit page function when visiting "/". This is almost a drop-in replacement for the auto-index client, but:
- NiceGUI scripts can't contain page functions.
- The UI isn't shared but re-created on every page visit.
-
Wrap all UI in a singe function and pass it to the new positional
root
parameter inui.run
. This is especially handy in combination withui.sub_pages
. This way you can create rich single-page applications without worrying about defining the correct routes with@page
decorators. -
Use page functions for all your pages, including the index page at "/".
Note that we are introducing a new
Event
class (see below). Together with the binding module this helps to synchronize long-living objects with short-living UI without relying on a long-living shared client. -
-
Calling
.props()
,.classes()
or.style()
with subsequent.update()
A subsequent
.update()
is not necessary anymore because props, classes and style are now observable collections that trigger updates automatically.When overwriting the
update
method in custom elements, infinite recursions can occur. If, e.g., theupdate
methods uses.prop()
before callingsuper().update()
, the.prop()
call will cause an infinite cycle. Wrap it withwith self._props.suspend_updates():
(and similar for classes and style) to pause automatic updates in such cases. -
Upgrade to Tailwind 4; dropping the
ui.element.tailwind
APIAlthough very similar, Tailwind 4 comes with some breaking changes. Check your layout carefully after upgrading. We noticed differences especially with line spacing and borders.
For technical reasons updating and maintaining our
ui.element.tailwind
API became unfeasible. So we decided to remove it. For auto-completing Tailwind classes, we recommend the NiceGUI extension for Visual Studio Code by @DaelonSuzuka. -
Dropping support for Python 3.8
Almost one year after Python 3.8 reached its end-of-life, it was time to drop support. This allowed us to update the code to a newer standard and resolve some issues with Python dependencies that already dropped 3.8 a while ago.
-
ValueChangeEventArguments
got a newprevious_value
attributeIn some situations it might be helpful to have access to both, the current and the previous value. Therefore we added
previous_value
to theValueChangeEventArguments
.Custom elements that emit
ValueChangeEventArguments
need to provide the previous value. -
Binding from and to non-existing object properties
Binding used to fail silently if one of the attributes doesn't exist. In case of dictionaries this was intended, because they are often used to bind to persistent storage which is empty by default. But for object properties this can lead to very subtle bugs, e.g. after renaming properties and not updating the attribue names in binding functions.
In 3.0 object properties will be checked for existence by default. Missing dictionaries will continue to be ignored.
You can fine-tune this behavior using the
strict: bool | None = None
parameter (None
: check object properties and ignore dictionaries). -
ui.log
with unspecified width can collapse inside containers with unspecified widthWe noticed that the height of
ui.log
could be affected by its content, which is unexpected. Therefore we decided to use a scroll area for a more robust layout.Now the width of
ui.log
can collapse when placed inside a container with an unspecified width. Either give the container some width or specify the width ofui.log
. -
ui.clipboard.read()
returnsNone
if the clipboard API isn't availableThe
read()
function used to return an empty string if the clipboard API is not available. This was indistinguishable from an empty clipboard.Now the
read()
function returnsNone
if the clipboard API is not available. -
Remove deprecated code and APIs (#5037 by @falkoschindler)
app.add_static_file
andapp.add_media_file
raisesFileNotFoundError
instead ofValueError
in case of non-existing files. SinceFileNotFoundError
is NOT a subclass ofValueError
, existing code whichexcept ValueError
will fail to catch the newFileNotFoundError
.ui.aggrid
:run_column_method
is gone. Userun_grid_method
instead.ui.table
callingadd_rows()
/remove_rows()
with variable-length arguments no longer works. Pass a list instead or useadd_row()
/remove_row()
for a single row.ui.open
is gone. Useui.navigate.to
.nicegui.testing.conftest
is gone and you can no longer import it. Usepytest_plugins = ["nicegui.testing.plugin"]
instead.element.on
parameterjs_handler
now has typestr
instead ofstr | None
. You can pass aNone
and it still works, but your type checker won't be happy, and we can't promise it will work for much longer afterwards.
JavaScript Dependencies
The infrastructure for managing node packages has been improved significantly (#4163, #5021 by @simontaurus, @evnchn, @falkoschindler).
The following JavaScript dependencies have been updated to the latest versions (#5034 by @falkoschindler):
- @tailwindcss/browser: 3.4.10 → 4.1.11 (#5057 by @falkoschindler)
- es-module-shims: 1.10.0 → 2.6.2
- quasar: 2.16.9 → 2.18.2 (resolves #4892 by @eddie3ruff, @evnchn, @xaptronic, @falkoschindler)
- socket.io: 4.7.5 → 4.8.1
- vue: 3.4.28 → 3.5.18
- ag-grid-community: 32.1.0 → 34.1.1 (resolves #3854 by @python-and-novella, @mockey, @falkoschindler)
- codemirror: 6.0.1 → 6.0.2
- @codemirror/language-data: 6.5.1 (new)
- @codemirror/theme-one-dark: 6.1.3 (new)
- @uiw/codemirror-themes-all: 4.24.2 (new)
- @babel/runtime: 7.28.2 (new)
- echarts: 5.5.1 → 6.0.0
- echarts-gl: 2.0.9 (unchanged)
- nipplejs: 0.10.2 (unchanged)
- vanilla-jsoneditor: 0.23.8 → 3.8.0
- leaflet: 1.9.4 (unchanged)
- leaflet-draw: 1.0.4 (unchanged)
- mermaid: 11.0.2 → 11.9.0
- plotly.js: 2.35.0 → 3.1.0
- three: 0.168.0 → 0.179.1
- @tweenjs/tween.js: 25.0.0 (unchanged)
v2.24.0
New features and enhancements
- Improve performance using
str.translate
instead of repeatedstr.replace
(#5104 by @falkoschindler) - Support
value=None
inui.checkbox
andui.switch
for indeterminate state (#5093 by @daya0576, @falkoschindler)
Bugfixes
- Fix event handlers being called multiple times (#5079, #5108 by @ftesser, @falkoschindler)
- Fix direct opening of async nested sub pages (#5085, #5089 by @alexzaech, @rodja, @falkoschindler)
- Strip path prefixes in sub pages router (#5106, #5111 by @SirTaros, @rodja, @falkoschindler)
- Fix browser exception in
interactive_image
layers (#5103 by @mpmX, @falkoschindler) - Fix
KeyError
appearing in the logs (#5090 by @alydersen, @sonicno1, @zbxiany, @evnchn, @maria-ems, @falkoschindler) - Fix
ui.aggrid
not calling the "onGridReady" event handler (#5087 by @denis-x, @falkoschindler) - Fix
ui.log
not scrolling to bottom when pushing multiple lines at once (#3909, #4830, #5112 by @mattie47, @golgitab, @pandabearcodes, @evnchn, @falkoschindler)
Testing
- Implement
user.should_see
andclick
forui.tree
(#5068, #5069 by @davetapley, @rodja, @falkoschindler)
Special thanks to all our sponsors and contributors! ✨
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!
v2.23.3
Bugfix
- Only start user storage pruning if a storage secret is set (#5077, #5078 by @pascalzauberzeug, @irham-rasyidi, @rodja)