NiceGUI: Web-based user interfaces with Python. The nice way.
Authors/Creators
Description
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
rootpage parameter forui.runto simplify single-page applications (#4964, #5005 by @rodja, @falkoschindler) - Introduce an
Eventsystem 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
strictoption for binding methods (#5040 by @denniswittich, @codingpaula, @falkoschindler) - Introduce a
sanitizeargument forui.htmlandui.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_areaforui.logto preserve a fixed height (#4925, #4935 by @e-nesse, @falkoschindler) - Let
ui.clipboard.read()returnNoneif the clipboard API isn't available (#4236, #4237 by @weinibuliu, @falkoschindler, @evnchn) - Call lifecycle event handlers more consistently (#5173 by @falkoschindler, @evnchn, @rodja)
- Improve
UploadEventArgumentsandMultiUploadEventArgumentsto 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
rootparameter 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@pagedecorators.Use page functions for all your pages, including the index page at "/".
Note that we are introducing a new
Eventclass. 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
updatemethod in custom elements, infinite recursions can occur. If, e.g., theupdatemethods 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
ui.tableandui.aggridcontentBefore 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 originalcolumnsorrows. This is not possible anymore.In NiceGUI 3.0 you need to modify
table.rows,table.columnsoraggrid.optionsinstead. A subsequenttable.update()oraggrid.updateis not necessary anymore.Upgrade to Tailwind 4; dropping the
ui.element.tailwindAPIAlthough 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.tailwindAPI 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.
ValueChangeEventArgumentsgot a newprevious_valueattributeIn some situations it might be helpful to have access to both, the current and the previous value. Therefore we added
previous_valueto theValueChangeEventArguments.Custom elements that emit
ValueChangeEventArgumentsneed 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 = Noneparameter (None: check object properties and ignore dictionaries).Sanitize content for
ui.htmlandui.chat_messageTo prevent NiceGUI apps from accidentally displaying unsafe user input as HTML,
ui.htmlandui.chat_messagenow have asanitizeargument. It can be set to a function likeSanitizer().sanitizefrom the html-sanitizer module, orFalseto disable sanitization. Whileui.htmlrequires the new argument to be specified,ui.chat_messageonly 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.logwith unspecified width can collapse inside containers with unspecified widthWe noticed that the height of
ui.logcould 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.logcan 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()returnsNoneif 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 returnsNoneif the clipboard API is not available.Lifecycle events are called more consistently
Handlers registered with
on_disconnectused 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_deletefunction can be used to register callbacks for the deletion of a client.UploadEventArgumentsandMultiUploadEventArgumentshave changedInstead of
content: BinaryIO,name: strandtype: strthe event arguments now contain a single fieldfile: FileUpload, which contains- properties
name: strandcontent_type: stras well as - methods
read,text,json,iterate,saveandsizeto access the content.
- properties
Remove deprecated code and APIs
app.add_static_fileandapp.add_media_fileraisesFileNotFoundErrorinstead ofValueErrorin case of non-existing files. SinceFileNotFoundErroris NOT a subclass ofValueError, existing code whichexcept ValueErrorwill fail to catch the newFileNotFoundError.ui.aggrid:run_column_methodis gone. Userun_grid_methodinstead.ui.tablecallingadd_rows()/remove_rows()with variable-length arguments no longer works. Pass a list instead or useadd_row()/remove_row()for a single row.ui.openis gone. Useui.navigate.to.nicegui.testing.conftestis gone and you can no longer import it. Usepytest_plugins = ["nicegui.testing.plugin"]instead.element.onparameterjs_handlernow has typestrinstead ofstr | None. You can pass aNoneand 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, #5168, #5190 by @falkoschindler):
- @tailwindcss/browser: 3.4.10 → 4.1.13 (#5057 by @falkoschindler)
- es-module-shims: 1.10.0 → 2.6.2
- quasar: 2.16.9 → 2.18.5 (resolves #4892 by @eddie3ruff, @evnchn, @xaptronic, @falkoschindler)
- socket.io: 4.7.5 → 4.8.1
- vue: 3.4.28 → 3.5.22
- ag-grid-community: 32.1.0 → 34.2.0 (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.25.2 (new)
- @babel/runtime: 7.28.4 (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.10.0
- leaflet: 1.9.4 (unchanged)
- leaflet-draw: 1.0.4 (unchanged)
- mermaid: 11.0.2 → 11.12.0
- plotly.js: 2.35.0 → 3.1.1
- three: 0.168.0 → 0.180.1
- @tweenjs/tween.js: 25.0.0 (unchanged)
The following contributions helped to fix problems during integration:
- Support AG Grid v34 Theme API for
ui.aggrid(#5122, #5131 by @egursu, @evnchn, @falkoschindler) - Segregate Quasar's important rules in Python-side (#5156, #5171 by @python-and-novella, @evnchn, @falkoschindler)
- Support client connection when Chrome performs speculative loading (#5115, #5116 by @python-and-novella, @rodja, @evnchn, @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!
Notes
Files
zauberzeug/nicegui-v3.0.0.zip
Files
(24.5 MB)
| Name | Size | Download all |
|---|---|---|
|
md5:eed356343bca02bee6ab54dee5d807af
|
24.5 MB | Preview Download |
Additional details
Related works
- Is supplement to
- Software: https://github.com/zauberzeug/nicegui/tree/v3.0.0 (URL)
Software
- Repository URL
- https://github.com/zauberzeug/nicegui