New course: Agentic AI for Python Devs

NiceGUI Goes 3.0

Episode #525, published Mon, Oct 27, 2025, recorded Thu, Sep 25, 2025
Guests and sponsors
Building a UI in Python usually means choosing between "quick and limited" or "powerful and painful." What if you could write modern, component-based web apps in pure Python and still keep full control? NiceGUI, pronounced "Nice Guy" sits on FastAPI with a Vue/Quasar front end, gives you real components, live updates over websockets, and it’s running in production at Zauberzeug, a German robotic company. On this episode, I’m talking with NiceGUI’s creators, Rodja Trappe and Falko Schindler, about how it works, where it shines, and what’s coming next. With version 3.0 releasing around the same time this episode comes out, we spend the end of the episode celebrating the 3.0 release.

Watch this episode on YouTube
Play on YouTube
Watch the live stream version

Episode Deep Dive

Guests introduction and background

Rodja Trappe and Falko Schindler are the creators and maintainers of NiceGUI, engineers at Zauberzeug, a German robotics company using Python-powered UIs in production. In the episode they trace NiceGUI from its early FastAPI proof of concept to a full component library backed by Vue/Quasar, purpose-built for building modern, real-time web apps in pure Python (no JavaScript required).

What to Know If You're New to Python

Here are a few quick primers so you get the most out of this episode’s discussion about NiceGUI and its stack:

  • nicegui.io/documentation: Start here for the three-line "hello ui" and the mental model of components and pages.
  • fastapi.tiangolo.com/advanced/websockets: NiceGUI rides on FastAPI and uses WebSockets for live updates; this page shows the handshake and usage.
  • quasar.dev: Many NiceGUI widgets wrap Quasar components, which explains features like data tables, tabs, and menus.
  • tailwindcss.com/docs: Styling in NiceGUI embraces Tailwind classes; you can drop down to utility classes when you need precision.

Key points and takeaways

  • NiceGUI’s core idea: modern, component-based web apps in pure Python
    NiceGUI lets you write UIs entirely in Python while it handles the browser side through Vue and Quasar. It sits on FastAPI for HTTP and uses WebSockets for live, push-based updates, so you can sync UI state in real time without polling. That "Python-first" flow makes it feel like traditional GUI programming, but the output is a responsive web app that works on desktop and mobile. The framework is open source and actively maintained by its creators.

  • Why teams pick NiceGUI over "data-app" tools
    In the show, the guests compare NiceGUI with Streamlit, Gradio, and earlier frameworks like JustPy. Streamlit and Gradio are fantastic for quick demos, but NiceGUI’s strength is full control: routing, component composition, styling, and integration with the rest of your Python back end. That’s why they run it in production at Zauberzeug to control robots and visualize data-rich UIs.

  • NiceGUI 3.0 highlights: script mode, SPA root, event system, Tailwind 4
    Version 3 focuses on developer ergonomics: a new script mode for "hello world" workflows, a root page parameter to simplify single-page apps, an event system to communicate between long-lived objects and the UI, and an upgrade to Tailwind 4. The release also cleans up bindings and tightens Python version support. These additions make app structure and state management cleaner while keeping the "write it in Python" feel.

  • Robotics and computer-vision friendly components
    The team calls out components that make robotics dashboards straightforward: ui.scene for 3D visualization powered by three.js and ui.interactive_image for mouse-aware image overlays. Interactive image lets you draw, select, and map clicks in image coordinates, which is ideal for camera-based workflows; updates are efficient and flicker-free. These are practical building blocks they actually use for robot interfaces.

  • Data-heavy UIs out of the box: tables and charts
    NiceGUI wraps Quasar’s QTable as ui.table, handling pagination, selection, and custom columns, and integrates with Apache ECharts for highly interactive charts. For advanced grid needs, AG Grid is supported, giving you a path to enterprise-grade tables. Because the state lives server-side in Python, you can push updates as your computations finish.

  • Developer experience: three lines to running UI, hot reload, and browser auto-open
    The guests demo the minimal app: import ui, create an element, call ui.run(). In dev, it auto-reloads on code change and opens your browser to the right URL. That quick feedback loop accelerates iteration while keeping the layout and state model simple.

  • Styling with Tailwind for precision without Yak-shaving
    NiceGUI exposes Tailwind classes so you can jump straight to utility-first styling when you need exact spacing, color, or layout control. Because many widgets map to Quasar components, you get a consistent baseline and can layer Tailwind on top instead of fighting opaque themes. This gives you design freedom without abandoning the Python-first workflow.

  • Routing and single-page apps
    You define pages with @ui.page similar to FastAPI routes, with typed parameters and client-side navigation helpers. For SPAs, NiceGUI supports sub-pages and, in 3.0, a root parameter on ui.run() to simplify top-level routing. This keeps complex apps organized without a separate JavaScript router.

  • State, sessions, and authentication paths
    NiceGUI includes built-in storage dicts (like app.storage.user) keyed by a signed browser session cookie, which makes per-user state and multi-tab sync trivial. For auth, you can roll your own forms or adopt FastAPI OAuth2/JWT patterns, and the community has several examples. In the episode, the maintainers argue for keeping auth simple and leaning on established FastAPI security flows.

  • Running multiple workers and scaling behind a proxy
    Because interactions use WebSockets, production setups typically place NiceGUI behind a reverse proxy and enable sticky sessions so a client reconnects to the same worker. Shared server-side storage (for example via Redis) helps multiple instances coordinate per-user state. This pattern is widely used when deploying real-time apps and is reflected in NiceGUI’s storage back ends and docs.

  • Native desktop mode and packaging
    NiceGUI can open in a native window with ui.run(native=True), which is handy for kiosk apps or distributing to users who expect a desktop experience. For packaging, PyInstaller is a common choice to bundle the app for Windows, macOS, and Linux. The show covers tradeoffs and notes that under the hood you are still serving a local web app.

  • Docker and simple deploys
    There is an official NiceGUI image on Docker Hub, and the docs outline common configuration knobs (host, port, reload) for production. Teams often front the container with Nginx or Caddy and wire in TLS and sticky sessions there. This makes it straightforward to host on your platform of choice.

  • Install and run with uvx for quick experiments
    The maintainers mention using uvx to run tools in ephemeral environments. With uv from Astral, uvx nicegui can launch a minimal app without manually creating a virtual environment, which is great for trying examples or reproducing issues.

Interesting quotes and stories

"And the minimal NiceGUI app is basically three lines of code... you import UI from NiceGUI, add a label, and then you write ui.run." -- Falko Schindler

"It turned out to be the main UI framework in NiceGUI. Most or many elements are based on Quasar or existing Quasar components." -- Falko Schindler

"Another interesting element could be the interactive image... where you can overlay camera data and things like that. And also the image can be very efficiently updated." -- Rodja Trappe

"As a default, it auto-reloads when you change the code. It automatically opens the browser for you." -- Falko Schindler

"Then you only need a proxy server which can have sticky sessions... and it routes you back to the right server instance." -- Rodja Trappe

key definitions and terms

  • WebSocket: A persistent, bi-directional communication channel between browser and server. NiceGUI uses this for live UI updates.
  • Quasar: A Vue-based UI framework whose components power many NiceGUI widgets (e.g., tables, tabs).
  • ECharts: A high-performance charting library used via ui.echart.
  • SPA (Single Page Application): An app that updates views client-side without full page reloads; NiceGUI supports SPA patterns and a root page option in 3.0.
  • Tailwind CSS: A utility-first CSS framework used for styling NiceGUI apps with fine-grained control.
  • Reverse proxy: A front server like Nginx or Caddy that terminates TLS, handles routing, and can enforce sticky sessions for WebSocket apps.

Learning resources

Here are curated Talk Python courses to deepen skills that pair well with NiceGUI. All links include a source tag.

Overall takeaway

NiceGUI keeps the promise of "write real web apps in Python" without giving up modern front-end power. You get real components, real-time updates, first-class routing, and production patterns that scale, plus the ability to go native or stay web-only as your use case demands. If you’re a Python developer who wants a UI that feels as direct as writing a script but behaves like a modern app, NiceGUI 3.0 is a very practical path forward.

Rodja Trappe: github.com
Falko Schindler: github.com

NiceGUI 3.0.0 release: github.com
Full LLM/Agentic AI docs instructions for NiceGUI: github.com

Zauberzeug: zauberzeug.com
NiceGUI: nicegui.io
NiceGUI GitHub Repository: github.com
NiceGUI Authentication Examples: github.com
NiceGUI v3.0.0rc1 Release: github.com
Valkey: valkey.io
Caddy Web Server: caddyserver.com
JustPy: justpy.io
Tailwind CSS: tailwindcss.com
Quasar ECharts v5 Demo: quasar-echarts-v5.netlify.app
AG Grid: ag-grid.com
Quasar Framework: quasar.dev
NiceGUI Interactive Image Documentation: nicegui.io
NiceGUI 3D Scene Documentation: nicegui.io

Watch this episode on YouTube: youtube.com
Episode #525 deep-dive: talkpython.fm/525
Episode transcripts: talkpython.fm

Theme Song: Developer Rap
🥁 Served in a Flask 🎸: talkpython.fm/flasksong

---== Don't be a stranger ==---
YouTube: youtube.com/@talkpython

Bluesky: @talkpython.fm
Mastodon: @talkpython@fosstodon.org
X.com: @talkpython

Michael on Bluesky: @mkennedy.codes
Michael on Mastodon: @mkennedy@fosstodon.org
Michael on X.com: @mkennedy

Episode Transcript

Collapse transcript

00:00 Building a UI in Python usually means choosing between quick and limited or powerful and painful.

00:06 What if you could write modern, component-based web apps in pure Python and still keep full control?

00:12 Nice GUI, pronounced NiceGUI, sits on FastAPI with a Vue Quasar front end and gives you real components, live updates over WebSockets, and is running in production at Saubersoig, a German robotic company.

00:25 On this episode, I'm talking with NiceGUIs creators, Radja Trappe and Falco Schindler, about how it works, where it shines, and what's coming next.

00:35 With version 3.0 releasing around the same time as this episode drops, we spend time at the end celebrating the 3.0 release.

00:43 This is Talk Python To Me, episode 525, recorded September 25th, 2025.

01:03 Welcome to Talk Python To Me, a weekly podcast on Python. This is your host, Michael Kennedy.

01:09 Follow me on Mastodon, where I'm @mkennedy, and follow the podcast using @talkpython, both accounts over at fosstodon.org, and keep up with the show and listen to over nine years of episodes at talkpython.fm.

01:23 If you want to be part of our live episodes, you can find the live streams over on YouTube.

01:27 Subscribe to our YouTube channel over at talkpython.fm/youtube and get notified about upcoming shows.

01:34 This episode is sponsored by Posit Connect from the makers of Shiny.

01:38 Publish, share, and deploy all of your data projects that you're creating using Python.

01:42 Streamlit, Dash, Shiny, Bokeh, FastAPI, Flask, Quarto, Reports, Dashboards, and APIs.

01:49 Posit Connect supports all of them.

01:51 Try Posit Connect for free by going to talkpython.fm/posit, P-O-S-I-T.

01:57 And it's brought to you by Agency.

02:00 Discover agentic AI with Agency.

02:02 Their layer lets agents find, connect, and work together, any stack, anywhere.

02:07 Start building the Internet of Agents at talkpython.fm/agency, spelled A-G-N-T-C-Y.

02:14 Falco, Raja, welcome to Talk Python To Me.

02:17 I'm so excited to talk about GUIs, maybe even a little hint of a desktop GUI for Python.

02:24 Oh my goodness.

02:25 You all have built something great.

02:27 So welcome to Talk Python To Me.

02:28 Happy to have you here.

02:29 Thank you for having us.

02:30 We're going to talk about NiceGUI.

02:33 Sometimes said nice GUI, but we're going to learn that it's NiceGUI.

02:37 And basically a nice blend of Python plus web plus a possible package in these up as, I don't know what you want to call it.

02:47 I think the name's probably already taken, but I feel like not Electron, but Positron, right?

02:51 Like we got to have something with a P, but that's kind of like Electron for like desktop

02:56 apps.

02:57 Yeah, I believe Posit would already have that taken for their new IDE thing.

03:02 Anyway, welcome.

03:03 Let's get a quick bit of background on both of you all before we dive into the project.

03:08 Falko, you want to go first?

03:09 Tell us about yourself.

03:10 Yeah, I'm Falko Schindler.

03:12 I'm basically addicted to programming since my childhood, but I only discovered Python around 12 years ago.

03:19 It was the time when I finished my PhD at the university.

03:22 And that was also the time I met Rodja and I became one of his first employees of the newly founded company, Zauberzeug.

03:30 Now I'm a full-stack software developer and robotics engineer.

03:33 and have been working on a wide range of projects like mobile apps, web apps, robotics, microcontrollers, basically the full stack.

03:42 And yeah, and since 2021, I'm one of the, or we both are the creators of NiceGUI, a Python-based web framework.

03:51 - Awesome, what languages, what tech were you using before?

03:54 You said 12 years ago you got into Python.

03:56 What was before Python?

03:57 - I basically was introduced to Python as an alternative to MATLAB, which I was using at the university quite a lot.

04:03 But I grew up with Pascal and did other stuff like web development, of course, with HTML, CSS, JavaScript, and some C-based languages, of course.

04:16 Yeah, nice. I did a lot of MATLAB when I was in university and grad school and stuff, and then I escaped.

04:22 Radja.

04:23 Yeah.

04:24 Welcome.

04:24 Welcome. Thank you.

04:25 My name is Rodja Trapper.

04:27 I'm living here in Haviksbeck near Münster, where I founded the company.

04:32 And I've grown up on a horse farm.

04:35 But at 13 years of age or so, there was the first computer in my room.

04:40 And I was really addicted.

04:42 But I started only programming.

04:44 Then in school afterwards, there was a course of study where I needed to program something.

04:49 And I really got into this.

04:50 And I liked it very much.

04:51 I struggled in school normally, but the programming made it all worse, I think.

04:56 And yeah, then after a course of study of computer science, I worked a little bit in Berlin.

05:00 and then moved back to my hometown with my three kids now.

05:05 And yeah, now I founded the company in 2012.

05:08 It's Zauberzeug.

05:10 It's like a company where we do mobile automation, robotics stuff, and also a lot of software development and AI.

05:18 So we bring everything together.

05:19 We have mechanical people and electrical engineers, but a lot of software engineers.

05:24 And yeah, we are doing all the things which are needed to automate stuff, and mainly in the agricultural sector because we are, of course, very close to test grounds there.

05:38 Yeah, it's nice.

05:39 Yeah, very neat.

05:40 A lot of the places that say robotics, they're like kind of toy things or Roomba-like things, but these are serious.

05:48 These go out on farms and are large-scale human assistants.

05:53 Yeah, it's fantastic.

05:54 Yeah, we really, in Soberzeug, we really want to do the hard and the difficult stuff to advance in the field and do the advanced research to find new solutions and automations for the difficult parts where traditionally only human hands can do stuff.

06:11 And we want to be on organic farms and in horse stables and so all the tricky parts where everything needs to be very perfectly suited together to bring a new age into place.

06:23 Yeah, it sounds cool. Did you found Sapozoi right out of school or how did you get to starting this company?

06:30 Yeah, while studying, I was very sure, even in school, I was sure that I wanted to one day found my own company, but I needed to know a little bit about how to run a company.

06:48 And so I moved to Berlin for four years and got into a nice company, Art & Comm, and learned a lot of project work and how things work together.

06:59 And after that, I was very sure I can do that.

07:03 And I did the freelancing and contractual work.

07:06 And then the contracts grew a little bit bigger.

07:08 And then I decided, okay, this is the right time.

07:11 I can hire my first employee and start the company and grow from there just in little steps and basically bootstrap myself.

07:22 Yeah.

07:23 Well, congratulations.

07:24 It's not easy to start or run a business, is it?

07:27 Yeah.

07:27 Yeah, it's true.

07:28 But especially if you really, most things I like is programming.

07:33 So I needed to really think about how to arrange the company and how to do the things that I still can do like 20 to 30 hours a day a week by programming and sitting down and thinking about the cool and nice stuff.

07:47 Yeah, of course. We're going to talk about it.

07:53 Good for you because I think staying grounded in the technology really gives you an edge to, you know, Valco comes to you and says, hey, I'm working on this project and I want to use this tech or should we use FastAPI or whatever? You're like, yeah, of course. I've been working FastAPI or whatever, vice versa, right? Like you're swimming in the waters and it's really good.

08:13 Awesome. All right. Well, you already gave a bit of a shout out to it. Let's talk about NiceGUI and like i like you know we were talking just a little bit before i hit record a lot of the projects it's really i think powerful to talk a bit about how you pronounce things because i don't know i i end up at a lot of conferences or maybe conferences not as much but meet people that are doing programming and they'll they'll tell me that they installed a library from pi pi and it was numpy and i'm like hold on hold on hold on you know the people who make that. They call that PyPI and they call it NumPy. And so just pyx, for example, right? It could have many pronunciations. There's nothing implicit about how you say that one, but Charlie Maher says pyx. And so you guys talk a bit about the naming and the pronunciation. I think it's an interesting

09:05 story. We have been looking for a name for a UI framework where the term nice was not on the table yet, but we had a kind of mindset in our minds. And in the end, we played around with the GUI term and ended up wanting to call it a NiceGUI, a pun on the Nice Guy ethos, a guy which is just who tries to be nice to everyone and tries to do things right. And that's a friendly UI framework, right? Exactly. And that's what we had in mind for our UI framework. But the guy with the Y, because then you would Google a NiceGUI and you would never find our framework.

09:48 And that's why we had to find a term that's unique in the internet and it works quite well.

09:54 There were other examples where I don't understand until today, why did they call it like that?

10:01 You just don't find it. Yeah, that was basically the motivation for the name. And we didn't make that explicit that it should be pronounced NiceGUI but we are fine with NiceGUI as well

10:14 yeah well i think it's i do appreciate that you have something unique in the search in the search both in the search and in these days in the ai like i'm working on a program with NiceGUI like well is he really helpful like no no no i mean there's a framework right you know so it's having something that you can search is super, super important. It's as if Jupyter spelled it the same way as the planet instead of with the Y, right? And you're like, oh no, you're never going to find anything about this. It's like all space. So very cool. I know at some point we're going to talk about version 3.0 and there's already a couple of comments in the chat of excited things about there, but we're going to save that for a little bit later. Let's just start by talking a little bit about you know where did this come from why did you all build this i'm gonna guess robots

11:07 but radia yeah it's um of course it's it's robots uh because a lot of things uh hinge around the robot uh interfaces and interaction with that um basically um i think we did a lot of interface design before and we also invented uh interfaces before and how to write them but um uh one day Falco came into the office and said, OK, I need to control this motor controller and I need to tune it.

11:35 And the robot is driving around. So we only have Wi-Fi.

11:38 We need to have some access to the system.

11:40 And he basically wrote something up where he could write some Python code.

11:45 And there came out some web interface. And it was really nice.

11:48 And I said, well, this is great. Let's do that.

11:51 And maybe, Falco, you can take it from here because, yeah.

11:54 Exactly. We had a kind of a moving target and we had to control it.

11:58 but just the command line interface is sometimes too weak to control sliders because we had to tune some parameters.

12:06 So we wanted some sliders and maybe a joystick and some things like that.

12:11 And I think the manufacturer already came with some user interface for it, or they were in the making of such a framework.

12:21 And it was very limited, but it gave the idea of, okay, the UI framework could consist of some building blocks that you could somehow arrange, but why do it graphically? Why not writing it? You could simply write the building blocks in Python or in other language, but of course, Python was our choice.

12:39 And so in Python, you can quickly create a web server with FastAPI. So this part is basically solved. And then the idea was the building blocks could simply deliver some HTML with corresponding CSS and JavaScript. At that time, I was working in Angular. So the very first commits of NiceGUI was based on FastAPI and Angular. And later we switched to Vue. Yeah. Yeah. And within a few hours, the basic concept was there and was looking promising. Of course, not to the extent that we could imagine it could get that large. It was just meant as an internal tool just for doing some internal things.

13:25 But what we did there is we set a lot on one computer and did wishful programming.

13:32 How did we would like to have written the UI and what should be on the screen there?

13:38 So we wrote it and tested it and then we thought, okay, how to implement this?

13:42 So we have a very, very nice interface for the developer, but how to write it actually the framework behind that?

13:48 And this was the challenge.

13:50 But after we did it a little bit, and then we started the first project with that, and we thought, okay, let's do all the robotic stuff with it.

13:55 And let's do our website with that.

13:57 So the website of sauberzoic.com is also written in NiceGuy, like the full documentation of the NiceGuy webpage and all the things.

14:08 We are doing really a lot of things, big interfaces where we have annotation programs and data pipelines.

14:14 So we really use it now everywhere and it's grown much faster and more robust than only just conductorial motor.

14:24 That's really great.

14:26 You know, even just looking at the UI, it's got this kind of friendly feel to the way the UI looks.

14:36 You know what I mean?

14:37 Yeah.

14:37 We are very happy to have also a professional graphic designer in our team, not only for the robotics, but also for websites.

14:46 And we really are thinking about how to present the things here.

14:50 And you can do basically anything in NiceGUI here because it's just HTML, HTML and JavaScript.

14:59 You can do everything, but most things you can do simply in Python without touching all the underlying infrastructure.

15:06 So you're telling me that those cool robots we saw cruising around,

15:10 They're running NiceGUIs.

15:11 They have a little web.

15:13 Yeah, exactly.

15:14 NiceGUI server cruising on top of them.

15:17 Yeah.

15:18 Sorry, do you give them DNS names, like Marco or whatever, like Marco, HTTP Marco, and start working with them?

15:28 Or how does that work?

15:29 The first few robots, we had some names for it, but right now we are just counting them up.

15:34 So like it's F35 or something, because there are so many and you need to really find the right one, which is running where.

15:43 But we have also in NiceGUI a web interface where we can manage the whole hive of all the robots running around and looking at the battery status and what they have done, the KPIs and so on.

15:56 The F stands for field friend.

15:59 So we call them the field friends.

16:02 Yeah, amazing.

16:05 This portion of Talk Python To Me is brought to you by the folks at Posit.

16:08 Posit has made a huge investment in the Python community lately.

16:12 Known originally for RStudio, they've been building out a suite of tools and services for Team Python.

16:19 Today, I want to focus on hosting your Python-based data science workloads.

16:23 This includes dashboards, reports, plots, interactive web apps, all the way to custom Flask and Django apps.

16:30 Their service is Posit Connect.

16:32 Posit Connect makes it easy for data scientists to share work built with Python code.

16:37 If you have a Streamlit app, Dashboard, Plotly interactive plot, a FastAPI service, or even a Quarto report, just give Posit Connect the code it needs to maintain the asset and Connect automatically does the rest.

16:51 Connect will manage your APIs and serve your interactive apps for you.

16:55 And if you want, you can update your reports and dashboards on a scheduled basis.

17:00 That's right. No need to explain to the stakeholders why that dashboard or plot stopped updating last week.

17:06 You get a focus on your data science and leveraging your skill set while Connect makes you look good, keeping your code running and private.

17:14 With Connect, you get a private URL on your Connect server, ensuring that your asset is continuously available to your shareholders.

17:21 And you can control which users have access to the asset.

17:25 Let Posit Connect handle the delivery and DevOps involved in sharing your work.

17:29 You focus on what you do best.

17:31 So if you work on a data science team, you owe it to you and your org to check out Posit Connect.

17:37 Visit talkpython.fm/connect today and get a three-month free trial to see if it's a good fit.

17:43 That's talkpython.fm/connect.

17:46 The link is in your podcast player's show notes.

17:48 Thank you to Posit for supporting Talk Python To Me.

17:52 Let's talk a little bit about building blocks, I guess, and then we could talk a little bit about the API.

17:58 So you chose FastAPI, and you said you considered Angular, but you went with Vue, but maybe through Quasar.

18:05 So let's, why FastAPI?

18:09 I mean, FastAPI is certainly a good choice.

18:12 Yeah.

18:13 But why?

18:14 FastAPI is great because it's, yeah, you can write very good REST interfaces with that.

18:22 And also what you get is this whole async support.

18:28 So you have an ASGI server running there.

18:32 So it's, from our point of view, much better suited for this super large scaling and a single CPU running all the tasks than, for example, Flask or so.

18:43 And so FastAPI was quite natural for us because we switched from Flask to FastAPI a few years before.

18:51 We were very sure that we can work with that.

18:54 this is supporting all the web traffic and server stuff we need.

19:00 And we did also a few big applications with that.

19:03 So this was quite a no-brainer farce.

19:07 Okay.

19:08 And then, Falco, you talked about Angular.

19:10 I don't know if this is Angular 1 or 2, but I know the transition from 1 to 2 was a little rocky.

19:17 It was after 1.

19:19 It was 2 or 3.

19:20 I'm not sure.

19:21 Okay.

19:21 So you didn't have to write out that roller coaster.

19:24 But then you chose Vue, and if I got that right, it's actually Quasar.

19:29 That's not Quasar, that's Quasar.

19:32 Tell us a bit about this.

19:34 I know Vue pretty well, but I don't know Quasar.

19:36 We didn't know it either.

19:38 Though I have to mention one important step in the development of the NiceGUIs was when we were thinking about a good name, we brainstormed.

19:49 And we thought, yeah, at one point we thought it's basically we are writing everything in Python.

19:54 So it's just Python, just Python, just Py.

19:58 So we ended up and wanted to use the name just Py.

20:01 And we looked up if there's something else called just Py already.

20:05 And as it turns out, there was a UI framework, exactly what we were about to do with NiceGUI.

20:12 And what was your thought?

20:13 Were you like, oh no, it's, why am I even doing this?

20:17 Kind of.

20:18 Oh, look.

20:20 They've been ahead of us pretty much.

20:24 They already had a full-fledged UI framework, basically.

20:28 But it was a bit low-level for us.

20:32 They basically mimicked HTML elements.

20:35 Yeah, I think I've seen this before and talked about it, yeah.

20:38 Yeah, maybe.

20:40 But they also used Quasar already.

20:44 And so we still wanted to build our own framework with our own components and some nicer API in our point of views. But we decided to use JustPy as a foundation. And that's where Vue and Quasar came into NiceGuy as part of the JustPy foundation. And just maybe a year later, we had some issues, some unsolved bugs with just by a bit poor performance.

21:12 And there was an effort to save just by and to push it forward.

21:18 And though that we can stay relying on it, but in the end we decided to stop it, to remove it from the code base, to reimplement the whole transportation layer and do it ourselves.

21:30 And it turned out pretty successful.

21:34 I think we turned out, yeah, with less bugs, with a better performance.

21:39 And maybe a year later, TrustPy was basically put on hold and isn't developed any longer.

21:47 But it was a very important tool for us, a very important foundation.

21:52 It's a great stepping stone to give us some fundament which we could use to show what we want to do with the user interface, how to develop the user interface and what abstraction is the right one.

22:07 And then we could easily swap out the engine after the first release.

22:11 Yeah.

22:12 One thing when I see, this is not a judgment on just Py, people see me this kind of stuff all the time, not all the time, but often enough, like, oh, here's a really cool thing that lets you not use HTML or JavaScript.

22:25 You just do everything in Python.

22:26 And sometimes the examples are just so close to HTML, but the frameworks are so close to HTML.

22:33 It's like, well, why would I not just use HTML?

22:36 If it's like I have to create divs and I've got to create spans.

22:42 And like I've literally, the framework is just the same as HTML, but in Python, like that's interesting and it's a cool framework, but also there's so much tooling for working with styling, et cetera, deploying HTML like that.

22:58 I don't know, I feel like it's maybe too low level, kind of like you were saying.

23:02 Yeah.

23:03 And so, yeah, a little bit higher abstraction where you have a button and you can put a click handler on there and if the button is clicked, then of course the click handler is called.

23:14 That was really the main goal of NiceGUI.

23:18 And I think that works pretty well and it scaled very far.

23:21 So we could also have other UI elements like e-charts or so where we have really diagrams and things like that.

23:29 Yeah.

23:29 Yeah, I think, Ido, you were talking about Vue and Quasar.

23:34 One of the concepts in that world is kind of like components and bigger building blocks than just raw HTML elements.

23:41 You know, here's a card or here's a turnstile or here's a panel or whatever, right?

23:47 And I think that that's a much better programming level to talk about these UI building block elements rather than HTML elements.

23:56 It relieves the developer from the plumbing a lot.

24:01 We can think about, okay, what do we want to show at what time and how does it all connect together?

24:07 If it's too fine granular, then it's really this fine-grained stuff is really taking up all your mental energy to think about what you really want to achieve there.

24:17 100% agree.

24:18 Okay, so that brings us back to Quasar a bit.

24:22 So Quasar is kind of these building blocks.

24:25 Is that right?

24:26 Yeah, right. Exactly. It turned out to be the main UI framework in NiceGuy. Most or many elements are based on Quasar or existing Quasar components. We call them elements in NiceGuy, but there are components in Quasar. It's just a choice.

24:43 And other components or elements like eCharts or Acrid or something, they are independent of Quasar.

24:52 So you're not tied to using Quasar when using NiceGUI, but it delivers a nice foundation, a basic set of elements you can use.

25:04 Cool.

25:05 So another one.

25:07 Let's go with this.

25:09 The AG grid looks like a super cool way to put grids of data, editable grids, sortable grids.

25:17 And tell us about like this.

25:18 It's probably something you do a lot with the analytics coming off the robots and stuff.

25:22 But I know other people do other interesting things.

25:25 An example on their website is like kind of a stock chart that updates live.

25:30 Yeah, we learned AG grid also through JustPy.

25:34 It was the way to present a table in JustPy.

25:37 So we basically adopted it.

25:40 Meanwhile, we are also offering a UI table, which is a quasar table.

25:49 So you can choose if you want to use UI ag grid or ag grid for an ag grid, or you can use the quasar table, which is a bit different in look and feel and the interface.

26:03 Yeah, but generally what we discovered when NiceGuy grew bigger and bigger that people really are into these tables.

26:11 They really need that a lot.

26:13 And all the features.

26:15 And AG Grid, for example, is really, really powerful.

26:18 And the abstraction we chose at NiceGuy is really great to bring all this into the Python world, where you can simply write something in and you can use it in the web like it would be in the web, but you use it simply in Python.

26:32 And so the interaction with that when you're writing, when you're developing, what do we want to do?

26:39 And so it's quite a good fit together.

26:42 And we could map all the features basically into Python.

26:47 And this is true for all the other elements also, that they are simply just a JavaScript component somewhere.

26:54 And we can write a small layer around that to bring it into the Python world.

26:58 And then you can really instantiate the object.

27:00 And then it automatically connects to, we have a web server and sends the messages over the secure channel to the website.

27:09 And so we have this great user interface at the browser.

27:12 And in Python, it's simply just a Python program running everything you want to run.

27:18 Yeah.

27:18 And I definitely want to dive into the server front-end data exchange.

27:23 This is going to be fun.

27:25 But rounding things out, I guess we also have some really nice charts.

27:28 with eCharts. I guess there's a pretty strong data science story here as well with what you all can build and the tools you got integrated, right? Yeah, of course. There are a lot of data scientists

27:43 out there which really like to use a simple framework to simply show a chart. And there are other kinds of frameworks which can deliver on that, like Streamlit or so. But Streamlit is quite difficult when you come to state management, how to do the database or how to integrate another third-party library.

28:03 You get really stuck into that. This was also one of the motivations behind NiceGuy when we invented it because of course we knew Streamlit and we know how to use it. This also has a lot of charts. NiceGuy is really meant to be very friendly for the programmer to not break the intentions you have and also be very powerful.

28:28 And of course, with eCharts and also other charting libraries, we can very easily integrate.

28:34 We have some powerful tools here for data scientists.

28:37 Yeah, it looks beautiful.

28:39 Now, the final building block that I want to talk about.

28:42 One, and I kind of said this earlier with this looking towards this in mind, is if you do everything in Python and you're just doing HTML, then it gets really hard to style those sorts of things.

28:53 But you all chose Tailwind for your styling, right?

28:58 If you need to, you can actually almost drop into the HTML level and do Tailwind type of stuff.

29:03 But there's also a fluent API in Python to apply Tailwind classes.

29:08 Give people, I don't know how much I've talked about Tailwind.

29:11 I'm sure there's a lot of people that are like, what is Tailwind?

29:14 And then why is it special?

29:17 Why is it especially good for this type of programming where you're interacting with the widgets?

29:23 or the components themselves.

29:27 Yeah, Tailwind or Tailwind CSS is basically an abstraction layer for CSS.

29:34 CSS is the way you are styling things in the web in HTML.

29:40 Plain HTML is pretty dry and has no styling, and you're usually using CSS to style it.

29:46 And Tailwind CSS makes it a bit easier, for example, well, they have a good example, It provides many shortcuts by adding classes to your HTML elements.

30:00 You're achieving more complicated things or you just can write it shorter.

30:06 And so like a P4 is four units padding for an element.

30:12 Right, right, right. All the way around.

30:13 Yeah, usually then the fun starts when you can add prefixes like hover.

30:19 then this styling only applies when hovering and for certain screen sizes or in dark mode and not in light mode and same things. So it's pretty powerful. And by adding it to NiceGuy, you have an easy way to style your elements. You have been written in Python without having to write plain CSS. It's a bit shorter. In the beginning, we didn't think that it would take off so much, but when you start using it, you do not want to stop. And then you want to write all your styling in Tailwind. Easy and simple. But to address your thought about, well, then you can, I'm assuming that you are thinking then you can just use plain HTML and Tailwind.

31:05 We thought about introducing a NiceGUI abstraction, some kind of styling language in NiceGUI, which is on top of Tailwind CSS. But this proves to be very hard. And then you don't win that much that it's worth the effort. And if you are introducing a new abstraction layer,

31:24 then you have to document it, you have to test it, you have to find the right level of abstraction.

31:29 And using Tailwind CSS as it is, we just can refer to the documentation, which is great.

31:35 and everybody can just look it up.

31:38 And while doing, though, learning CSS and styling and tailwind, and that's useful as well.

31:46 I think we had a pull request like four years ago or multiple attempts to create an own layout engine where you can define, okay, how the width and how the height and stuff like that.

31:59 But then you need to think about, okay, this is always the web, what you're talking about, and it's super, super powerful.

32:04 And the language for the web for styling is CSS.

32:08 There's no way around it.

32:09 If you find some other abstraction, it will definitely break at some points and also not allow every mutation and every kind of variance or so.

32:19 And maybe we will introduce something later on or sometime.

32:26 But what we really try to do with NiceGUI is that you can do the simple things very easily and you can do it very quickly.

32:34 But the difficult things should also be doable.

32:37 And so if we have an abstraction, then like in Streamlit, you cannot do it.

32:43 It's just you are locked in.

32:45 And this is not something we would like to have in NiceGUI.

32:49 This portion of Talk Python To Me is brought to you by Agency.

32:53 Build the future of multi-agent software with Agency, spelled A-G-N-T-C-Y.

32:59 Now an open source Linux foundation project, Agency is building the Internet of Agents.

33:04 Think of it as a collaboration layer where AI agents can discover, connect, and work across any framework.

33:11 Here's what that means for developers.

33:13 The core pieces engineers need to deploy multi-agent systems now belong to everyone who builds on agency.

33:19 You get robust identity and access management, so every agent is authenticated and trusted before it interacts.

33:25 You get open, standardized tools for agent discovery, clean protocols for agent-to-agent communication, and modular components that let you compose scalable workflows instead of wiring up brittle glue code.

33:38 Agency is not a walled garden.

33:40 You'll be contributing alongside developers from Cisco, Dell Technologies, Google Cloud, Oracle, Red Hat, and more than 75 supporting companies.

33:49 The goal is simple.

33:51 Build the next generation of AI infrastructure together in the open so agents can cooperate across tools, vendors, and runtimes.

33:59 Agencies dropping code, specs, and services with no strings attached.

34:03 Sound awesome?

34:04 Well, visit talkpython.fm/agency to contribute.

34:08 that's talkpython.fm/agntcy the link is in your podcast player show notes and on the episode page thank you as always to agency for supporting talk python to me i think one of the interesting things on tailwind is that you know it's kind of grouped in the utility css frameworks and i don't know that that makes any more sense to people that already know tailwind but it lets you put the css classes right onto the elements and that directly affects them because a lot of CSS frameworks have a kind of a very separated, here's your CSS and style. And then here's your, the effect it has, like if it's in a row, if it's in a container, which is in a row, which then has this property, then it has some effect. And there's a very big separation of ideas. And this is more of a, let's leverage the locality, like right on the element, you can see that it says font dash medium text-2xl.

35:03 Oh, okay, well, that's what the property...

35:05 You don't have to look anywhere else than right there, right?

35:08 And so it still works pretty well, I think, with NiceGUI, because as you're working in Python writing code, when you apply the style, you apply it to the thing in a real similar way to Tailwind, unlike, say, Bootstrap or something more separated.

35:24 Yeah.

35:24 Also, when you look at C# and Samuel also, they wanted to separate the layout from the content, and we decided that it's not good to do this.

35:31 Because when you're writing UI, this is a good example for the with statement, where you open a context to do an intent like, okay, now we have a new row, and inside the row there's another row, but we have always an intent invention so that you can look at it and you see in the code, okay, there's something new going on in Clojure.

35:52 And when you can then put the styling right to it, then you really know, okay, this is the point, there it's going on, and you can simply do it.

35:59 And of course, you can do all the abstractions you can do with Python.

36:02 You can make a class from that and use the component somewhere more abstract.

36:07 You don't need to write like 100 lines of code in UI code right from one step to the other.

36:13 But when you have UI code, you can really look at it and understand very good the structure of it.

36:19 Yeah, 100%.

36:20 Yeah, I'm actually, I don't know if people know, I'm a pretty big fan of C# and.NET and so on.

36:25 Not as much as Python, but for sure.

36:27 But I hate SAML.

36:28 I hate the way they build that.

36:29 It's such a frustrating framework to work in.

36:31 I never.

36:33 Interesting.

36:33 Astro Strongbox out there says, Love NiceGUI.

36:36 Building a battery pack simulation GUI plot.

36:40 UI.plotly.figure.classes.

36:42 W-full.

36:44 H-100.

36:45 Boom.

36:45 Just like that.

36:46 Great.

36:46 Yeah.

36:47 And that is the NiceGUI code.

36:48 So maybe it's a good time to start talking about, you know, how do we maybe, how do we get started working with this?

36:55 Let me zoom out a little.

36:56 So find some examples.

36:59 Right on the start page of our website, exactly.

37:02 There we have basically the most minimal NiceGUI app.

37:06 And it was always important to us that this is easy and short.

37:11 And the minimal NiceGUI app is basically three lines of code.

37:15 You import NiceGUI or you import UI from NiceGUI.

37:19 You add some label, maybe UI label, hello.

37:23 And then you write UI run.

37:24 And this will run the UI for you, start the server.

37:28 As a default, it auto-reloads when you change the code.

37:31 It automatically opens the browser for you.

37:33 So you're right on the right URL.

37:35 And that's it.

37:36 And your app is running.

37:38 All right.

37:39 Let's talk through what actually happens when this code runs.

37:42 So you run this.

37:43 And then this basically starts a server running UVicorn on the default port for FastAPI, which is 8,000.

37:50 So localhost 8,000.

37:52 You click that, it opens in a browser.

37:53 And you've got a UI element that is a label.

37:56 Excuse me.

37:56 That's a label.

37:57 It says, hello, NiceGUI.

37:59 That's unimpressive, of course, because it's just sending some HTML to the web browser and the web browser is rendering it.

38:06 But in the background, the web page is connecting back to the server with an ID of a client which is created on the server and says, okay, I'm connecting back.

38:15 I now establish a WebSocket connection.

38:17 And from there on, the web browser is connected to the web server.

38:20 And all the events which happen, like when you have a button or so, when you press it, the command is sent through the web socket to the server.

38:28 And then the server can decide, OK, what to do about this?

38:30 What is the command?

38:31 What should be done?

38:32 And then it executes the Python code and sends back the commands for the UI update to the web page.

38:37 And so we have this dynamic interaction very neatly packed into the web socket connection.

38:42 Yeah, and that's where it starts to get interesting.

38:44 So for example, if you pull up the docs for button, it has an on click.

38:50 And the thing you pass to that on click is a Python callable, right?

38:54 And if I go to the button in the page and I click it, stuff happens in HTML.

38:59 But you're telling me that's because there's a web socket that connects some kind of JavaScript trigger to a Python action on the backend.

39:07 Is that right?

39:08 Yeah, exactly.

39:08 In the example here, the onClickHandler is just a Lambda statement calling UINotify and then a message like "You clicked me." And then if the button is clicked, the WebSocket sends to the server that the button is clicked and then the server decides, "Okay, I have a click handler on this button and I will now execute the Python code there." UI notify will then decide, okay, when I execute, I will take the message, pack it into the WebSocket connection and send it to the browser again.

39:39 And the browser then decides, okay, let's show the message here in Quasar.

39:43 And so you see the message appearing on the screen like a pop-up.

39:47 And this runs in the context of a Python executable on the server, I guess, depends on how you connect to it, right?

39:54 It could be a desktop application.

39:55 runs maybe as an invisible server on your machine or in the case you described earlier on the robot

40:03 so on right yeah yeah or simply deployed to the cloud like um with um any framework there are a lot of things like you can simply uh host it behind an apache web server or traffic or even uh use things like uh these um what we are using a lot when we are hosting services like fly io they are hosting it, getting an IP address and the domain registration and then you can simply run all the code there.

40:34 That's awesome.

40:35 Fly.io. Interesting. How about Caddy? Have you checked out Caddy?

40:40 Have you guys played with this?

40:41 I think we have not used it a lot ourselves, but this is something people in the community ask us about or use it even and reported that it's a nice and a great server environment. Yeah. Yeah. And it seems really, it seems really interesting. One of the big selling

41:01 points is it automatically does SSL creation through let's encrypt. So if you set up a server and on a domain and you just access it and it doesn't have SSL yet, it'll just, as part of the first request, just create an SSL certificate, which is pretty cool. I've thought about using it, but I have 2000 lines of Nginx configuration. It's just, it's not time well spent to try to convert all that to work seamlessly with caddy it's just like you know what it works let's just not go down that so very cool all right let's go back to more um more ui elements and more programming models i think it might be fun to take a little bit of a tour of the different things that you can build you know so if i jump over here maybe let's go controls for example We talked about buttons, but you've got little groups of action buttons.

41:54 You've got dropdowns, a lot of different little expanding, what do you call this, floating action buttons.

42:01 Badges that have numbers like in macOS in your dock or on mobile phones.

42:06 You've got like a little icon, but then it gets a little number over it with notifications, those kinds of things.

42:11 Talk about some of the UI elements that you think are good building blocks.

42:16 Yeah, you mentioned some.

42:17 And most of them, if you check the first line of the documentation, it says based on Quasar's

42:24 Q button toggle or Q chip.

42:27 And so right now you're looking at mostly the elements which were borrowed from Quasar.

42:34 And they are mostly not that spectacular from the implementation point of view because they've just fit easily into the NiceGUI framework.

42:44 We are writing a small wrapper class, and that's mostly it.

42:47 We just say, use the tag Q button, and then the rest is done by view, translating the view button tag into a real button.

42:58 Other elements need some help from our side where we adjust the front end code.

43:04 And then there are elements like the more complex things.

43:07 We have 3D views where we use 3JS, which is completely independent of a quasar, which we use for our robots quite a bit.

43:20 So we implemented kind of a subset of a tiny subset of three jets.

43:25 Three jets is just huge, but some building blocks we are using a lot.

43:31 Some 3D objects like cubes, spheres, even 3D meshes and some 2D elements.

43:40 And you can control the camera and move it around and actively group objects, animate objects.

43:47 And it's a quite powerful foundation for what you want to do with your robot maybe.

43:53 And what you can see when you look at the interface and the writing the API or so, you simply say, OK, I get it with a new UI scene. I then have with a group or with some element. And you can then write the scene STL and you load some STL file in 3D.

44:14 And the thing is that we try to make it very, very simple from the API that when you are writing code, that you don't have to think about what to do next and how to arrange it.

44:25 But you simply can write it down and then you have modifiers like.scale 0.3 that you can really say, say, okay, no, it's a little bit smaller, and here you go with auto intention and completion.

44:38 Yeah, you know what I really like about this?

44:40 That the shape of the code mirrors, the hierarchy of the code mirrors the hierarchy of the HTML and the DOM and all those kinds of things.

44:50 That is really nice.

44:51 So you have a width, you have a context manager for the grid, and then you put the things into the grid.

44:59 And it looks visually like the code of the things that are in the grid is indented into that area, right?

45:05 Yeah, that's an example for two very important design decisions in our language, basically.

45:12 The one is the with statement, which could be read as a within statement, but it's called with, but it's close enough.

45:19 So you're saying with a grid, we are arranging these elements like this, and all elements that are nested in the with statement in the grid appear within the grid.

45:30 That's one thing.

45:31 And as you say, that results in a very visually clear code.

45:35 And the other one is the builder pattern, which we strongly encourage and use a lot.

45:41 Most modifiers like styling or event registrations or binding can be done with a method which returns the object itself.

45:52 So you can chain them like you could scale the teapot and move it and rotate it and all in one line.

45:59 And if you break the line, then it still looks visually grouped and you still see, okay, that's one element which is undergoing some transformations.

46:08 And it turns out pretty nicely.

46:11 In contrast to what we saw at the JustPy example, which was one pain point with JustPy itself, they don't do that, the automatic context switching, but they use classic add functions.

46:27 You have to create the object first, and then you can create the container, and then you can add the object to the container.

46:33 And in the end, you lose complete control over the structure of the UI.

46:40 The code doesn't match the UI.

46:42 And that's what we...

46:42 It's really tough to figure out when it gets to be a complicated UI setup.

46:47 And it's fine for automation to write this kind of code if you had a builder sort of thing, but it's not good to read.

46:55 Yeah, exactly.

46:56 Yeah.

46:57 Another interesting element could be the interactive image, which we came up with because the normal image from Quasar is very powerful, but could not do overlays where you can paint on the object in image coordinates.

47:14 And so now the interactive image where you can simply click and do annotations like drawing circles and getting mouse events back from the image coordinates, which we use for annotating images for AI trainings and so, but also to overlay camera data and things like that.

47:35 Also, the image can be very efficiently updated.

47:38 So we simply update the image content.

47:42 And when we send the data back to the browser, only when the browser really decides, "Okay, now I can load a new image," then it will update the image.

47:50 So if you have a lower bandwidth connection and you send update images 30 times per second and the connection only can do two images per second, then it will only load two images per second And you have automatic frame control with that.

48:06 Very cool.

48:07 Yeah, that's amazing.

48:08 So I think I want to focus a little bit more on some UI elements and some building concepts to drive home a few points.

48:15 And then maybe we can talk some of the deployment, the 3.0 side of things.

48:20 So that's a very interesting question in the chat.

48:23 We'll come to that.

48:25 So one of the things I want to talk about is subpages and building basically how do you build.

48:32 So these are all really interesting building blocks, right?

48:35 Each of these have been super impressive.

48:37 But how do I create something that has the feeling of more than one page?

48:43 How do I navigate around?

48:44 How do I give it like a navigational structure and elements and so on?

48:49 So, yeah, maybe talk a bit about that.

48:52 The basic idea of what comes from FastAPI is simply you send a get request via browser and you get a webpage and then you look at it and when you click on a link, then you send another GET request and you get another page and you show it.

49:07 So this is the normal way and this is what NiceGuy supports from day one.

49:12 But now in preparation for our 3.0 release, we also introduced the sub-page concept where you simply have support for a single page application. You only once connect to the server, get your image, get your website, and then you can say, okay, there's a subpage. And if I click that, then the content will be replaced, cleared, and drawn anew with another function. And so you can

49:40 navigate on the page and it's much, much faster. Yeah, that's, and it's support, it's more spa friendly, single page application friendly, which potentially you could right click on and say,

49:53 install. Yeah, exactly. The single page application sounds so easy from the concept. So we did a few runs and edits to get the API right and to get everything into place. And if you look at the code, it's really demanding from the maintainer point of view because there's a lot going on. You need to rewrite the history of the browser so back and forth buttons are working correctly and nested sub pages so sub pages in sub pages and stuff like that you need to all support that it was really

50:25 you could take a take a grab the url and then like send it to somebody and they have to open it as they go to the right place all these things are hard yeah yeah so is this something sorry go

50:35 ahead falker um the documentation page itself uses the sub page uh concept which is basically a single page application um uh our way of writing single page applications so if you uh open the menu and jump from one subject to another. This is all done without reloading, without sending new get requests to the server, just swapping the content, and that's much faster. Yeah, that's cool.

51:02 And if I right-click on it, I can say install page as an app, right? That's pretty awesome.

51:08 I'm actually a huge fan of single-page applications. I think it's really great.

51:12 You know, you can save it into your doc or your taskbar.

51:16 And sure, it's just a web page.

51:19 But it actually, I think it makes a really big difference to have it there just appearing to you as a separate thing.

51:26 You can command tab or alt tab between them easier, all sorts of stuff.

51:31 Yeah, the web is really the most powerful application engine you have ever got.

51:38 So running web pages as desktop applications like Electron or like your Proton idea was that you say, okay, there's something and we support this.

51:53 With NiceGuy, you can simply write, okay, I will have a native true argument in the UI run.

51:59 And then you start it up and it's really enclosed in a window.

52:03 But it's still running the web application there.

52:06 And because the web is so powerful and with NiceGuy, you can get access to all these powerful features.

52:11 You can really write very nice applications right now with all the interaction simply in Python.

52:17 Yeah.

52:18 All right.

52:18 Let's talk a little more deployment before we jump into the 3.0 features.

52:24 So first of all, you've got UI.run.

52:27 And that was even in your three-line example that appears at the end.

52:31 you pass a bunch of commands like reload false and those sorts of things, right?

52:37 In order to give it more of a high performance perspective instead of watching for reloads and that kind of stuff. With that one, I can just go and put it into, you know, like running on my server in a VM point engine X or caddy or whatever at the local host port and set up an SSL certificate get and just turn it into a proper web application, right? Because it's basically FastAPI on that end,

53:01 right? So it's simply starting the server and then it opens support and you can access it however you like and how you want your deployment to be. But I think one of the interesting feature requests from the community was that they have an existing FastAPI application and they want to add some UI to it. And the interesting part is that it's really easy because it's all FastAPI, So we could sub-mount it.

53:25 And there's a UI run with statement where you can say, okay, I want to run this with another FAS API app behind that.

53:35 And then you give a sub-path and then all your application is running on another FAS API app.

53:42 Interesting.

53:43 Okay.

53:44 And I guess because it's running on U of Ecorn, that's already a production Python app server.

53:49 But one of the things that happens frequently when you put stuff into production for more than just a small project is you have a web garden, I guess it's called, where we have multiple workers of UVicorn or something like that.

54:02 And that works okay if you set it up that way.

54:04 It's not some kind of weird issue.

54:06 The main problem is that the NiceGUI architecture demands that the web socket connection comes back to the same server to find the ID.

54:18 And if you have multiple workers, then there's round robin from the unicorn to send it to some of the other workers.

54:24 And maybe the worker doesn't know about it.

54:27 We recently introduced a feature, or maybe it's a year ago already, that we support a storage space where you get access to via Redis.

54:41 So you can get the data stored from the user again or so.

54:46 then you only need a proxy server which can have sticky sessions where you connect to the server and it routes you back to the right server instance.

54:55 And so you can really get a lot of instances running.

54:59 And we do this for the documentation page, which is crazy.

55:03 Also deployed around the world so that in Taiwan, they are also having a nice snappy interface.

55:11 So we need to run, like, it's now 30 servers or so to have really at the edge all the documentation ready.

55:18 Wow, that's amazing.

55:19 That's so cool.

55:21 So you mentioned Redis.

55:23 What about Valkey?

55:24 Are you familiar with Valkey?

55:25 I imagine you could probably just swap it off.

55:27 Yeah, it could work very similar, I guess.

55:32 We have not tested it yet, to be true, but I think from the concept space, it's the same.

55:40 You need to really store the data and get it back to get the synchronization right.

55:45 Yeah, I think Valkeyis basically was forked from Redis.

55:49 So it probably, it might be able to just work.

55:53 Okay, yeah, yeah.

55:54 Could be that too simple.

55:55 Yeah, because I think Redis changed their license in ways that some people were frustrated with or didn't work for them.

56:01 So a group said, okay, well, there was a really permissive license not too long ago.

56:06 We're going to make a version of that basically.

56:08 Yeah, so it could work out of the box.

56:10 Worth a try.

56:11 I have not tried it.

56:12 I mean, let's be sure.

56:14 Okay, a couple other options here that I think are interesting.

56:18 I'm a big fan of Docker and Docker Compose.

56:21 And you all provide a really interesting way to just run it in Docker.

56:26 So a lot of times I find, okay, I'm building, I'm going to deploy an app, so I'm going to copy my code over and set up a, maybe I'd set up UVicorn in that Docker image and then run it.

56:35 But because it's all the, you already have that as a concept of it.

56:39 You guys have a NiceGUI image and you just map to the source and run it, which I think is actually really nice.

56:46 Yeah.

56:46 Yeah, it helps to make deployments a little bit easier.

56:50 And the NiceGUI image we deploy there has also some fancy features like having a non-root environment where you can simply have your group ID and things you normally not want at the first start when you do it.

57:09 but when you are going into production, you really need that.

57:12 And it's all packaged away in the stocker container already.

57:14 So you can simply use that for running and deploying.

57:18 Yeah. Yeah. Yeah. Very cool. All right.

57:21 I do want to leave just at least a little bit of time to talk about the 3.0 direction, but the one that there's one here, that's just, we got to talk about it. It's native. Yeah. This, this is incredible. This is the proton, right? Yeah, exactly.

57:34 You guys tell me about this. This is great.

57:37 Yeah, when you run UI run, when you call UI run, you have a parameter native and you will set it to true. And then there is no web browser opening, but a native window. And what used to be a website is now running inside this native window. And yeah, it's behaving like a native app and you don't notice that it's actually a website running.

58:03 Yeah, because it uses PyInstaller, or you can use PyInstaller to package it up.

58:07 That's the next step, yeah, of course.

58:09 You can take this app, or you can also use a regular app, which is not native, I guess.

58:14 I'm not sure.

58:16 But yeah, once you have a native app, you can package it, and then you can distribute it much easier.

58:23 Let me throw an idea out there for you.

58:26 With either PIPX or uv, you can basically install something from PyPI, right?

58:32 In there, you can set a entry point, like my app or whatever, right?

58:37 Give it a good name.

58:38 And then, so you could just say uvx space, like the name of your package, you know, run, yeah, uvx space package, right?

58:45 And it'll just run it and it'll download it and run it from the virtual environment like you need.

58:50 I think people could start shipping GUI apps that look like native windows just using uv and uvx.

58:59 Yeah.

58:59 Have you tried this?

59:01 We haven't tried it.

59:02 But we're just beginning to work with UE and UEX, but UEX is a really powerful tool.

59:10 You're right.

59:11 Yeah, and if you just put an entry point or a script entry into the PyProject.toml, then that would do the launch.

59:20 And then if you run it as native, it would show up without a terminal.

59:22 And you wouldn't even need to package it, right?

59:25 Yes, exactly.

59:26 Yeah, you wouldn't have to package it at all, and it would be cross-platform.

59:30 That's an intriguing idea.

59:31 Maybe someone has already done it.

59:34 So if so, please leave a comment there.

59:38 Indeed, indeed.

59:40 Okay, let's talk about 3.0.

59:43 So if I go to the GitHub right now, and I unzoom my window and go to releases, we're on 2.24.2, but I know really soon you are going to be releasing 3.0.

59:55 You have plans for some really cool features.

59:57 And sort of the title of this podcast was like, Let's celebrate both NiceGUI and then sort of a milestone of you guys reaching that.

01:00:07 Most of the people will be listening in like four weeks, so you got a little time before.

01:00:12 But let's just talk about what's coming in 3.0.

01:00:15 You can scroll a little bit down.

01:00:17 There you'll find the release candidate.

01:00:20 Ooh.

01:00:21 Around.

01:00:22 There we are.

01:00:22 Yeah.

01:00:23 There it is.

01:00:24 Three weeks ago, we released release candidate one.

01:00:26 That was before I went on vacation for two weeks.

01:00:30 And yeah, we are in the last steps, maybe a few days ahead of releasing 3.0.

01:00:38 And yeah, it started with some housekeeping and basically no big breaking changes.

01:00:45 And we just wanted to update all dependencies like upgrading from, well, the most important thing was upgrading Tailwind, which is on version 4 for a while now.

01:00:56 and we've still been using version 3.

01:01:01 But as it turns out, of course, there are some nasty changes that we have to account for so our users don't have to.

01:01:08 And that's why it takes quite a while to tackle all tiny difficulties.

01:01:15 So that we are trying to release a major version once a year, around once a year, to get all dependencies up to date and that people are not confused on the tailwind documentation, there's a feature which NiceGUI doesn't have.

01:01:30 And of course, it depends on the version.

01:01:34 But at that time, once in the year, we are liberal. We are free to break some things, but we only want to do it once. So we have to be careful to do it right. And we can't change it a few weeks later again.

01:01:49 And we want to have only breaking changes that are okay to migrate. We want to have a migration guide and no nasty things that you only find when you're reading all your code again and with the changes in mind. That's why it can become a bit difficult. Yeah. The new release is really,

01:02:11 like the major version, is really challenging, but also a good point where we can introduce very great and new features which help the code base and NiceGUI to evolve into the thing we envisioned there. And one of the great things we did there is we have this now a new root parameter where you can say UIRun and then you pass one page like a function, simply a function there, and this will be the main page. So it's much more single page application friendly. You simply have one function and you pass it into the UIRun and this is your page. And then inside you can use UI page, subpages, to create subpages, which are then single pages running.

01:02:56 And so it makes it much more easier.

01:02:58 You don't have these boilerplate annotations, at UI page, and then some URL parameters or so, but you can streamline that a little bit.

01:03:07 And things like that are really nice to have in a framework.

01:03:11 Yeah, that sounds really great.

01:03:13 Will it have full spa support?

01:03:15 If somebody writes an app that way, could they right click and say install page?

01:03:19 or install this app so it'll have serviceworker.js and all that kind of business?

01:03:24 Yeah, you can basically do it. We don't have a Python API for the service workers yet, but of course you can always write your special JavaScript or HTML code and pass it along with your Python code and then you can get the data there. But most of the applications when you write them with NiceGUI they rely on this server connection so if you are offline it doesn't make so much sense to to use it and um but still there are if you install something on your desktop um and you connect to it back then of course if you have an internet connection you can load everything and um be right back where you left yeah yeah i think there's two

01:04:09 parts to single page applications more like pwas i guess is the way i want to say it exactly and I know one of the ideas is it can completely work offline

01:04:20 and it uses local DB and all.

01:04:22 And it's just an app that runs locally.

01:04:25 But I think a lot of apps need the server to be doing anything interesting anyway.

01:04:31 You've got to have a very complicated app to do.

01:04:33 If I was building Notion but 100% offline, that's a really complicated app.

01:04:38 But I think it's also really nice to have an app model for the way you interact with it.

01:04:43 So you don't have all the Chrome around.

01:04:46 If you close your browser, you don't necessarily close that.

01:04:48 But also just the speed of loading, you can cache a bunch of things potentially and then sync them with the server.

01:04:55 I think there's still a lot of interesting benefits, even if it requires being connected to work.

01:04:59 Yeah, totally true.

01:05:01 Okay, a couple of questions real quick, and then we're out of time.

01:05:06 First, Alan out there says, will 3.0 have LLM-friendly docs in the sense that could I download something that I could put into my project and tell my agentic coding agent, anytime you need to know about it, this is the one, look here, and then not have to have it always searching different parts of the web and so on.

01:05:28 Rodja, remind me, we do have an endpoint for AIs already, right?

01:05:33 Yeah.

01:05:34 We don't have the rendered documentation in a single page format, but we prepared for AIs.

01:05:45 Yeah.

01:05:45 When you look at the documentation implementation, it's simply Python code running through our PyDocs and getting all the strings out.

01:05:53 And the same mechanics is used to build a text version only, dump down version where you simply have a TXT file.

01:06:02 And I think we provided it a year ago or so already.

01:06:06 And right now the LLMs not know everything of NiceGuy, but a lot.

01:06:12 But if you put this URL in there to have a documentation lookup, it's much, much better.

01:06:17 Okay, that's really awesome.

01:06:19 What about an MCP server?

01:06:21 Have you considered this?

01:06:22 I think it's probably not super different.

01:06:25 It could be a worthwhile addition.

01:06:27 We have not taken the time to do it.

01:06:30 But, of course, contributions in that area would be really nice to make it even better.

01:06:35 I think there are also two ChatGPT endpoints which are primed to answer questions for that.

01:06:45 At least two.

01:06:46 What's the URL?

01:06:47 How do I find it so I can put it in the show notes?

01:06:50 Do you know?

01:06:51 I don't know.

01:06:51 All right.

01:06:52 Give it to me later.

01:06:53 We'll put it in the show notes.

01:06:53 Yeah, give it to me later.

01:06:54 Give it to me later.

01:06:55 Okay.

01:06:55 And then another one is I have a friend who's building really interesting full-fledged SaaS type of application applications using NiceGuy.

01:07:07 And it looks so impressive, what they're building.

01:07:10 It's great.

01:07:11 But what about authentication, multi-tenants, so certain people can only see their data versus all the data?

01:07:22 What's the authentication and multi-tenancy, I guess?

01:07:26 Basically, because we are running FastAPI, you can do anything what FastAPI can do with authentication.

01:07:33 And we also have quite a few examples on the webpage where you can see, okay, how to do OAuth authentication with Google or Runtab authentications.

01:07:44 You could simply build a passphrase input and do a login.

01:07:49 Because when you are looking at it, it's simply a decision what to show the user.

01:07:54 And you have Python at your hands, so you can decide whatever you want.

01:07:59 And you can load the right data from a database or use our local storage system where you can ask, okay, for the user, what are the configurations?

01:08:09 What is he allowed to see?

01:08:11 What are the permissions?

01:08:12 And you can store it there and you can retrieve it from there.

01:08:15 And it's a cookie-signed process, which is a web cookie, which is pretty safe and is right the way to do the authentication.

01:08:26 Yeah.

01:08:27 Yeah.

01:08:27 Okay.

01:08:27 Fantastic.

01:08:28 And a couple of people have asked, including SilverBlade says, will it be possible to switch from Quasar to something else, or would it be possible to switch Tailwind for another utility-type framework like Bulma or something like that?

01:08:42 That's a good question.

01:08:44 Right now, starting with Tailwind.

01:08:46 Tailwind is already a pretty thin layer on top.

01:08:50 You can already disable Tailwind, and NiceGUI runs without Tailwind support.

01:08:55 And you can pretty easily add other frameworks like Bulma as far as...

01:09:00 I haven't tried it, but it looks like you just have to add a CSS file.

01:09:05 You can simply add it to your...

01:09:07 Yeah, that's right.

01:09:07 You literally just include the CSS file.

01:09:09 There's no build steps.

01:09:10 And then you just use utility classes there.

01:09:12 So it's plausible.

01:09:14 Exactly.

01:09:14 And because NiceGUI is pretty agnostic when it comes to classes, you can simply add classes to your elements.

01:09:20 And then they will use Bulma if you loaded Bulma.

01:09:24 So that's pretty easy. We can think about official support that you can switch between frameworks. Yeah, that could be a feature request we could be thinking about. The more difficult thing is replacing Quasar because the Python implementation of these elements is pretty tightly coupled to the framework.

01:09:50 a quasar button behaves a bit differently than maybe some other button.

01:09:56 So that's where we would probably have to implement new elements, maybe with a different name or we have to use some global switch.

01:10:06 It is not planned right now, but it's not completely off the table because sometimes we get asked if we could get a more modern feel for NiceGUI apps.

01:10:17 And Quasar is already a bit dated.

01:10:21 The material design is not the very newest.

01:10:25 I do like it, though.

01:10:26 It looks clean and friendly.

01:10:29 Especially if you deviate a little bit from the standards.

01:10:32 If you remove the shadow, make sharp edges or something, which is pretty easy and nice to do globally.

01:10:38 You can say all my buttons should have these props.

01:10:42 Then you can build pretty nice apps, I guess, even with Quasar.

01:10:46 But last days, I spent so much time with Quasar Tailwind and their CSS layers, because Tailwind 4 introduced CSS layers.

01:10:59 Or they don't introduce it, but they are using them right now.

01:11:02 Quasar does not.

01:11:03 And Quasar does its own things to make some statements more important than others.

01:11:09 And it makes it pretty difficult to integrate with other frameworks.

01:11:13 and I started to think about maybe removing Quasar in MySky 4 or 5.

01:11:22 But we'll have to see.

01:11:23 Maybe Quasar comes out with a new version with a better CSS layering strategy and maybe a new look and feel or maybe a better theming support.

01:11:32 Then it's back.

01:11:33 A few weeks ago, we had a pull request merged in where you could add very simply other frameworks on top of you to put them in and replace either the quasar part completely.

01:11:50 Then you cannot write UI button, but you can do it with the underlying mechanics of NiceGUI nonetheless.

01:11:58 But yeah, or you could use it as an addition.

01:12:01 Yeah.

01:12:02 Just to be clear, I'm not saying you should be doing this.

01:12:04 Like you all want to stay focused, but I do think it's interesting.

01:12:06 You know, these people, they're all like, hey, we're using this other thing.

01:12:10 There's so many features you could do, and we need to decide, okay, what is going on?

01:12:15 What do we like and what do we not like?

01:12:17 But also what comes from the community as feedback and as feature requests.

01:12:22 We cannot implement everything, but we really like to have a very feature-rich environment which doesn't constrain you so much, which allows you to deviate from the norm, find different aspects and evolve from that.

01:12:39 Yeah.

01:12:40 And our main guideline is, would it be nice?

01:12:42 If another framework would be nice to have a nice guide, then we should maybe do it.

01:12:47 And we are always open to alternatives.

01:12:50 Okay. Sounds great.

01:12:50 All right.

01:12:51 Well, we're pretty much over time.

01:12:53 So that means out of time.

01:12:55 Let's round this out with a quick question as sort of leading into the final call to action for people who are interested in the project.

01:13:03 So first of all, 14,000 GitHub stars, 834, you'll must be super proud of that.

01:13:09 The other one is, are you looking for contributors?

01:13:13 What can people help with?

01:13:14 That kind of thing, right?

01:13:16 Yeah, we are definitely always happy about any new contributors.

01:13:21 We are always encouraging new users, new members of the community.

01:13:27 If they have an idea how to improve it, we encourage them to, hey, do you want to make a pull request?

01:13:32 Yeah.

01:13:33 Maybe it's the first one ever, but it's a great experience.

01:13:36 And then you are an official NiceGUI contributor.

01:13:39 What kind of contributions would you want?

01:13:42 Like, what would be most helpful from the community for you all?

01:13:45 Versus maybe it's in certain areas, right?

01:13:46 Yeah, it's so complicated.

01:13:47 Let us handle this part.

01:13:48 It has to be this way.

01:13:50 That's a good question.

01:13:51 And we don't have a really easy answer about it.

01:13:56 There are parts where we reach the edge of our knowledge, where if especially if users are scrolling through the open issues or pull requests and see some topic where they are maybe very experienced and there are we are we're trying to be very transparent about unsolved bugs or feature requests and where we don't know how to do it and yeah maybe even an open issue where we are still missing a reproduction something that that's weird, but we can't reproduce it.

01:14:34 Any step forward to solving these issues is helpful.

01:14:38 Yeah, especially in areas where we are out of knowledge.

01:14:41 Yeah.

01:14:42 Yeah.

01:14:42 All right.

01:14:42 Sounds great.

01:14:43 All right.

01:14:44 Well, I guess we're going to leave it there with that.

01:14:47 So final call to action.

01:14:48 People want to get started with NiceGUI.

01:14:49 What do you tell them?

01:14:50 Yeah.

01:14:50 Simply pip install NiceGUI or uv install NiceGUI and then launch it up, write some code in it And feel free to give us some notes and things, what you would like to see, but also just experiment with it.

01:15:06 And maybe it doesn't click with everyone, and that's fine.

01:15:10 And maybe there are people who really much more like another framework or even write HTML and simply FastAPI.

01:15:18 But for those who don't want to leave the environment where they are very familiar with, I think NiceGUI is really a good starting point.

01:15:27 Yeah. Awesome. Well, thank you so much.

01:15:30 Congratulations on the great project.

01:15:32 I know tons of people are getting lots of value.

01:15:35 So thanks for being on the show.

01:15:36 Thanks for creating it and sharing it.

01:15:38 Yeah.

01:15:38 Thanks for having us.

01:15:39 Thank you very much.

01:15:40 Yeah. See y'all.

01:15:41 Bye.

01:15:42 This has been another episode of Talk Python To Me.

01:15:45 Thank you to our sponsors.

01:15:47 Be sure to check out what they're offering.

01:15:48 It really helps support the show.

01:15:50 Posit Connect from the makers of Shiny.

01:15:52 Publish, share, and deploy all of your data projects that you're creating using Python.

01:15:57 Streamlit, Dash, Shiny, Bokeh, FastAPI, Flask, Quarto, Reports, Dashboards, and APIs.

01:16:04 Posit Connect supports all of them.

01:16:05 Try Posit Connect for free by going to talkpython.fm/posit, P-O-S-I-T.

01:16:11 Agency.

01:16:12 Discover agentic AI with agency.

01:16:15 Their layer lets agents find, connect, and work together, any stack, anywhere.

01:16:19 Start building the internet of agents at talkpython.fm/agency, spelled A-G-N-T-C-Y.

01:16:26 Want to level up your Python?

01:16:27 We have one of the largest catalogs of Python video courses over at Talk Python.

01:16:31 Our content ranges from true beginners to deeply advanced topics like memory and async.

01:16:37 And best of all, there's not a subscription in sight.

01:16:39 Check it out for yourself at training.talkpython.fm.

01:16:42 Be sure to subscribe to the show.

01:16:44 open your favorite podcast app and search for Python.

01:16:47 We should be right at the top.

01:16:48 You can also find the iTunes feed at /itunes, the Google Play feed at /play, and the direct RSS feed at /rss on talkpython.fm.

01:16:58 We're live streaming most of our recordings these days.

01:17:01 If you want to be part of the show and have your comments featured on the air, be sure to subscribe to our YouTube channel at talkpython.fm/youtube.

01:17:09 This is your host, Michael Kennedy.

01:17:10 Thanks so much for listening.

01:17:12 I really appreciate it.

01:17:13 Now get out there and write some Python code.

01:17:40 Talk Python, the async is the norm.

Talk Python's Mastodon Michael Kennedy's Mastodon