I'm always on the lookout for a good Python UI framework.
In this episode, we're going to focus on one called DeerPyGUI.
DeerPyGUI is a fast and powerful graphical user interface toolkit for Python with minimal
dependencies. It's created by Jonathan Hofstad and Preston Cothran, and they're here to tell
us all about it. This is Talk Python to Me, episode 348, recorded November 18th, 2021.
Welcome to Talk Python to Me, a weekly podcast on Python. This is your host, Michael Kennedy.
Follow me on Twitter where I'm @mkennedy and keep up with the show and listen to past episodes
at talkpython.fm and follow the show on Twitter via at talkpython. We've started streaming most
of our episodes live on YouTube. Subscribe to our YouTube channel over at talkpython.fm
slash YouTube to get notified about upcoming shows and be part of that episode.
This episode is brought to you by Sentry and TopTal. Please check out what they're offering
during their segments. It really helps support the show.
Let me tell you about a new project I'm working on. It's a YouTube series called Python Shorts.
This series will consist of fun and quick videos teaching you one amazing thing about Python.
They're usually less than five minutes long and put a practical spin on topics you might have been
and counting the number of times an item appears with collections.counter. I already have a list of
about 100 videos to create over the next year in this series, so there will be many more to come.
And if you have an idea for one, please shoot me an email or tweet and I'll add it to my list.
If these sound fun, please subscribe to my personal YouTube channel. Just visit talkpython.fm
slash python dash shorts to see the playlist and there you can click on my face and subscribe.
You may already be subscribed to Talk Python's YouTube channel. That's where we do the live
streaming of the recordings, but I decided on my personal one. So be sure to subscribe there too
if you want to get these videos. Thanks for listening and thank you for supporting all of my work.
Let's get to that interview. Jonathan Preston, welcome to Talk Python to me.
Hi, glad to be here.
Hey, it's great to have you guys here. I'm very excited to talk about GUIs and UI frameworks and
stuff like that. I think Python needs more of it and we're building some cool projects,
frameworks there. It'll be fun to talk about it. We're going to talk about DeerPyGUI,
which is one of these frameworks tries to have a quick getting started story.
That is correct.
Let's just get into your stories and hear a little bit about you since there's both of you,
maybe not too extended, but Jonathan, how do you get into programming in Python?
I got into programming when I was around 13 years old. My stepdad and mom got me a C++ for dummies book.
And worked with that for a while until just as a hobby project or as a hobby thing. And once I got to
college, I went to mechanical engineering, which is also where I met Preston. They typically like to
use MATLAB, which everybody knows isn't a real programming language. The indices start at one.
Of course.
As an alternative to that, ChemCurls Python. It had a lot of the same features, actually a lot
more features than MATLAB and it was free. So didn't have to pay for the MATLAB license.
Yeah. MATLAB is expensive for people who haven't messed with it. It's like really expensive outside
the student story.
It is. And you have to use their entire environment and everything just to, just to use it. So aside
from that, on top of that, with the Raspberry Pi, it was into electronics and things like that. And
the Raspberry Pi are able to control the GPIO pins using Python. Naturally, I just started playing
with Python from there. And yeah, that's pretty much where Python came into my picture.
So you said you were in chemical engineering? Is that what it was?
Mechanical.
Mechanical. Okay. I was in chemical for a little while and they said that, I asked if I could take
a C++ class. They said, you can as an elective, but you have to take Fortran because that's going
to be the most important language you ever learned. I thought, I'm just jealous. MATLAB is not that
amazing, but I'll tell you what, it's better than Fortran.
That is very true. We occasionally have to use Fortran at work with our FEA programs,
finite element analysis programs with Abacus. You're able to extend it with Fortran. So
occasionally we have to look at a little bit of Fortran to do that. And it's, yeah, it's ugly.
Yeah, for sure. Preston, how about you?
Mine was mostly junior year in college, MATLAB course. Incidentally enough, that's why it's not
a real programming language. I moved from that directly into Python. I thought when I started
my first job and I just started working with C++ after that and then tailed into a little bit of C,
not much. Right on. And what are you all doing now? Sounds like still engineering work?
Yeah. So I'm doing engineering. So I'm doing mechanical engineering. I'm doing design on
threaded connectors for oil and gas industry, mainly designing the seals and threads that hold
production tubing together down hole that actually sends the oil up through the well.
Wow. So you must be talking about a lot of pressure, talking about materials that would
like to destroy rubber and other things as well, possibly.
Yeah. So I guess that, that tails into coding. Mainly we, or I use most of Python to just extend
that because like we were talking about for scripting and stuff like that.
Yeah. Jonathan?
I started out in the same position and slowly moved into the software side of things. A lot of that's
working with Preston, some of the other mechanical engineers on extending some of those applications
like Abacus and that choosing Python or extending AutoCAD and that's C++. So there's that side of
the day-to-day work. And then the other side is we actually have some internal software that
we work on one for inspecting connections without contact. So using lasers and robot arms and all
that stuff to basically just take measurements instead of having to go out and manually doing
it. This, this can be on an assembly line and most of that's in C++ and C. We do use our library,
DeerPock GUI for a lot of the prototyping and some of the tooling for the project, but for projects in C and C++.
Sure. I don't think I've really covered mechanical engineering on Talk Python properly. What's the
story with software automation and that kind of stuff? Is it mostly using programs like sounds
like this Abacus one versus writing your own software, doing your own automation?
A large part of mechanical engineering is, at least in our field, is stress analysis and computational
fluid dynamics, fluid flow type problems. And as far as software goes, it's usually in relation to that.
Like Abacus is, as an example, a software package for stress analysis. And then there's other ones,
OpenFoam.
Yeah, OpenFoam. You, you wrote some solvers at your first job for that?
Yeah, that, that's correct. We took some electives while we were in college and some of those were for
writing these solvers. And most of those you could write in whatever you want. Those professors didn't
actually care. And a lot of times I wrote in Python on there. Most of the time it was Python, I would say.
Yeah. What's the story for packages, PyPI type of things in your space?
As far as what we used or what we used?
Yeah. Is there a lot of stuff out there? I know, for example, astronomy is filled with libraries,
like AstroPy and whatnot that people could just grab and use.
For mechanical engineering, I don't know if there's NumPy or NumPy.
Yeah.
But as far as specific to mechanical engineering, I really don't think there's any. There may be a few
FEA solvers, but I don't think they're maintained or well documented for sure.
We typically found that a lot of engineers end up staying in the MATLAB realm and not really venturing
into any more hardcore languages. So they end up using all, because a lot of them want symbolic math,
integration and ODE solvers and all of that. It's all right there in MATLAB. And then the companies
typically pay for it. So you're in that realm.
And once some group gets embedded in there, it's just going to stay in that space unless somebody
takes some effort. Yeah. All right. Awesome. Thanks for that background. Although we're not here
exactly to talk about deep dive in mechanical engineering, it is cool to get a look. Let's talk
about your project, your PyGUI. So when I think of the GUI graphical user interface space
in Python, there's TK-Enter, there's PyQt, there's a few other things, but they all have some kind of
oddity about them. There's not like one framework that people just like, yeah, we're just going to
use that thing. It's not like a Swift and Objective-C Coco controls would be in say,
an iOS app or something, where it's really clear. Just generally use that one. Where did you guys get
started working on GUIs and Python? What was the goal with the Geopy GUI? Like where does it stand
out? Where does it fit in this space? I got started in UIs working at one of my internships while I was in
school. And we were using this package, which I think I already mentioned once, open foam for CFD.
And it didn't have a front end interface at all. It was a C++ solver that just pretty sure just output
text files in the end. I don't remember. It's been about six, seven years. So I wanted to build a UI so
that the other engineers could use it. And at that time, I was just getting into it. So I used to Kentr
because, you know, it's a Python. And then also used VTK, if I remember correctly. That would,
I would say that's the first experience I had with it. And then our senior design project,
being pressed were also on the same team for that, was to build an arc welding 3D printer.
It actually created things by doing arc welding. Right.
Rather than printing some other sort of material out of it.
Right. Yeah. It was a MIG welder. I was on the software side of that. Preston was on a lot more
of the physical side. We should put them in the software for now.
Yeah. Anyway, built, that was the goal of the project. And we used some open source
slicing software. I don't remember. It's like Slicer 3D or...
It had a three for the E. Yeah. Slicer and it had three for the E. And we basically modified that
and ran it in a headless mode and built a UI on top of it using Tkenter. And I want to say we used
Pygame to be able to access OpenGL. And at the time we were using legacy OpenGL. Those are first
experience with graphics APIs. Yeah. Which, you know, OpenGL is pretty neat. It was certainly
good when it first came out. It was as good as anything else. But I feel like it hasn't been
getting the same amount of growth and adoption, maybe as some of the other frameworks, DirectX and Metal and
so on.
DeerPyGUI uses DirectX, Metal and OpenGL at the moment. So we've been using a lot of them over the last few
years. And the biggest reason for that is just that the hardware's changed since those APIs were
created. And they no longer directly match the hardware.
DeerPyGUI came out of trying to basically build something better than direct OpenGL access. What'd
you say? Or direct framework access?
DeerPyGUI not quite. It came more out of a, I guess, going back to answering where
where DBG itself came from. We had a previous project that we worked on, a commercial project
on engineer sandbox. The program had an embedded Python interpreter in it. And you basically created little
mechanical engineering apps. And we could create one in, I don't know, an hour or two. And it was just
this collection of apps. And over time, it started to get a little annoying to have to recompile it,
especially before we added Python. We added Python because we were getting tired of
recompiling it every time we want to add an app or modify something and have to redeploy.
From there, we embedded Python. And it was very limited. You were able to create a few
small apps. You couldn't, it really wasn't a full GUI library. What happened is we were trying to sell it.
Didn't really work out. We can never really catch traction. And we had some users and customers,
but most people weren't really interested in it. And developers aren't really interested in paying for
libraries or any SDK. Most of them just wanted to be free. So that just kind of fell out. And we gave
up on that after that. That's a tough place to be, right? You want to put a lot of energy into building
tools and making stuff for people. How do you put enough time into it if people just want it to be free?
Maybe what we got to do is maybe the world is the VS Code model where there's large companies that have
other motivations for creating it rather than directly funding through that. But that's a deeper
conversation that we have to solve.
Selling to developers in easy is the key point there.
Yeah, sure.
So we did keep it in house and we continued. We still have apps written in it at our day job.
We ended up revisiting it because it didn't do everything we wanted to do. And we said,
this time let's target developers from the beginning. So it's not going to be very limited. It's going to be,
should be able to do most things you can do in any other UI library. And on top of that, make it free.
And that's where your PI GUI came from. And between those stages, we came across the library
or in GUI, which I'm not sure if you're familiar with, but...
Yeah, I'm not familiar with it. What is this?
It is a...
It is an extremely popular immediate mode graphical user interface for real-time applications.
It's usually used.
C++.
Yeah, it's C++.
Yeah, yeah, yeah.
But it's kind of a weird, I mean, it's an immediate mode interface and there's not many,
I would say there is no Python user interface that's like that. And if you look at it...
Maybe we should talk about the different modes real quick, since you bring it up.
This immediate mode versus retained mode. What are those two worlds? What does that mean?
I take this one.
So I don't want the internet to jump on me here because there's a lot of...
A little bit of argument there, but there's a few key points, I think, that really make it stand out.
One of those is that the stage is not retained. If you have a slider that controls a float,
it doesn't... You don't have to basically have a float stored on your side and a float stored in the UI,
and you're constantly having to deal with keeping them up to date and things like that. Instead,
the library itself doesn't store that at all. Now, the way it's implemented is a little different,
but I'm talking about from the user side of using an immediate mode library.
It doesn't retain any state. The other big thing is that, at least with, especially when it's on GUI,
is the UI items and widgets are submitted every frame. So 60 times a second. And that gives you a
credible amount of dynamicism, I guess you'd call that. To be able to do a lot of things,
and completely redo the UI on a per-frame basis, you can...
Yeah, as opposed to something where maybe you say a text box goes here and a button goes there,
and then you set the text to the button, and then the button knows what its text is.
This is almost like a game loop type thing where it...
Right.
Each time, like however, whatever the frame rate is, 50, 60, 200 frames a second, it's like,
draw the UI, draw the UI, draw the UI, right?
Yep. And the interesting that that kind of 60 frames a second can lead into what we just put in a few
weeks ago talking about not redrawing the GUI every 60, every frame.
Right. That's a good point. One of the issues we had, especially early on with some users complaining
as well, do you need to update everything every frame 60, 60 times a second?
So we did recently add in 1.1, the ability to basically stop, only update if there is some
user input, whether that's moving the mouse or resizing the window, things like that, because
a lot of people, they'd complain to be more energy conscious with having your GUI run all the time.
Which you might care about, say, on a laptop or a tablet, but less so if you're plugged into the wall.
Right. Yeah.
Yeah. Interesting. Yeah. And even some of the new, what are they, ProRes displays,
like the new MacBooks and stuff? Like the entire display will slow down if stuff is not happening.
And I wonder if maybe if you had a GUI app that was refreshing the screen a lot, maybe it would
prevent it from actually going into a slower mode.
Look and do that. Variable refresh rate plays into the software actually rendering.
Yeah. Yeah. Yeah. I don't really work at that level, so I don't really know for sure, but all in the same
space, I'm going to go back to the app. This portion of Talk Python To Me is brought to you by Sentry.
How would you like to remove a little stress from your life? Do you worry that users may be
encountering errors, slowdowns, or crashes with your app right now? Would you even know it until they
sent you that support email? How much better would it be to have the error or performance details
immediately sent to you, including the call stack and values of local variables and the active user
recorded in the report? With Sentry, this is not only possible, it's simple. In fact, we use Sentry on
all the Talk Python web properties. We've actually fixed a bug triggered by a user and had the upgrade
ready to roll out as we got the support email. That was a great email to write back. Hey, we already saw
your error and have already rolled out the fix. Imagine their surprise. Surprise and delight your users.
Create your Sentry account at talkpython.fm/sentry. And if you sign up with the code talkpython, all one
word, it's good for two free months of Sentry's business plan, which will give you up to
20 times as many monthly events as well as other features. Create better software, delight your
users and support the podcast. Visit talkpython.fm/sentry and use the coupon code talkpython.
It looks to me like that some of the, there's some similarities from the I am GUI in terms of the
UI look and feel, but then you've got the retained mode versus immediate mode and things like that.
What's the relationship between these? I'm GUI itself.
I'm GUI itself just outputs. You can read as read me, but outputs and optimize vertex buffer.
It sends basically the coordinates and everything needed to draw the UI, but it is up to you to take
that and actually do something with it and render it. We use that. We use I'm GUI to basically create
those vertex buffers. As far as the retain mode stuff, originally we were doing more of a one-to-one
wrapping with that library. And we started to hit some performance issues with Python itself, just because
the second, if you're having to do a lot of conversions between maybe the Python types and
the C and underlying C types that can slow things down. Also just the GIL gets in the way with a lot
of different. So what we did with the retain mode is we basically just created a barrier between that,
where we do go against the immediate mode style thing. And we have, we do keep up with things like the
the underlying value is just the floats, the, the ends, the strings, whatever it is.
So it goes back to a more retain mode, which is what every other library is that most Python users would
be used to. The float actually stores a, sorry, an input text has its underlying string and you can
get that value, set that value.
So a lot of UI code, you don't even need to have some variable that holds the thing. You might just
put it in the button and if you need it back, you could get it from the button potentially. Right.
Right. Yep. And that's how it works. So I guess one of the only other things that's neat is underneath it,
it is just a raw, I'm pretty sure probably using smart pointer and you can actually link a lot of these
widgets together to when they're truly controlling the same value. And you can get some pretty cool effects
with that to where directly moving this slider is updating the plot and there's not some update
code that's having to happen or any callbacks. It's just that they're truly the same value.
And because we're updating 60 times a second, you're able to see those changes live, which is pretty
neat. And you can create some pretty cool stuff with that. Yeah, that's fantastic. Before we jump into some
of the details, if you visit the GitHub page, which of course I'll link to, let's maybe just talk through
some of the features. I was going to go to the gallery, but maybe the features is a better place
to start. And you guys have this engineering background. It feels like a lot of what this
creates and allows us to build real easily has this engineering visualizing aspect to it. Right.
Yeah. Yeah. So maybe talk us through some of the features and things you can do. So for example,
one of the things you have, you can see right at the top of the feature section is the I am plot stuff,
which looks like really interactive and dynamic plots and graphs and pie charts and so on.
Yeah. It's another immediate mode interface that the guy that wrote it, Evan Peasant, I'm not sure
how to pronounce his last name, who also happens to be located here in Houston, wrote it on top of
on GUI and tried to model that immediate mode interface. So again, you get all the same dynamic
features that you get with GUI itself. And that's why you can see on here a lot of the, just how crazy
dynamic it looks, right? With the live QCAP clearing and everything you see there. And obviously we,
again, built on top of it because we have to go from that immediate mode to retain mode style. And
it, you have multiple axes, you have drag and drop support, custom drag and drop support. There's a lot
of series you don't see there, candlesticks, shaded series, stem plots.
Yeah. One that looks really good is this one down here that has full zoomed out graph and then a graph
below it that as you pan around and zoom in, you can actually, it's like a high level and then a low
level or zoomed in detail view of what you're exploring there. Yep. And that's pretty obituary
than the demo. Well, it's actually not technically built in. That's a query region. So you have to
set up another plot with the same. Also, it looks like they have animations and stuff. The one below
it sort of just cruising by without any interaction. So are you able to just feed it live data and it just
keeps refreshing 60 frames a second or something? Yeah, that's exactly how it's working because it's,
again, already updating 60 times a second. All you're doing is changing the data and it just by
default, you basically get an animation. If the data changes, it's going to re-render it no matter
what. And so then it gets a different picture, right? Yep. It's worth noting that it's only 60 frames a
second. If you, if you use VSync with your, with your screen, it actually runs as fast as your screen
can run. So 144 to whatever hertz your monitor is on. Oh, interesting.
It depends on your GPU and everything else. Yeah. We'll control the render loop so you can actually
slow it to whatever exact frame resolution you want. You could 30, whatever you want. Right. You
probably can't exceed your monitor, but you could slow it down or do something if you need to chill it out.
You can, it just won't.
The effect of, the effect of people seeing it, they won't see it. Right. Yeah. And that, yeah,
that's really cool. Cross platform. Yeah, it is cross platform, but I was going back there. There are
some cases where we will turn VSync off to just test how fast certain things are happening. Right.
Because you want to know what's the performance upper limit of this, regardless of the screen.
the screen. And a lot of people love to send us messages with that while we're trying to do
something like update a texture or something as fast as they can and trying to get 300 or 400 frames a
second. But it was pretty neat to see that. What else should I highlight in here? These are all,
there's a bunch of graphs. I think people really just need to go see them, but there's,
there's nice heat map looking things. There's some statistical stuff. Anything else you want to shout out on the.
Yeah, there's some candlesticks. We've seen some great interaction with some APIs through some actual
cryptocurrency interfaces people have done. They made crypto wallets, which is pretty cool. We've seen some of that.
Right. Yeah. So we've seen probably maybe 10 of those. So it is a lot of people seem interested in that.
Interesting. Yeah. So people are using
DearPyGUI to build something like a dashboard trader application.
A lot of dashboards. Yeah.
We can pull in a comment from the audience, Mr. Hypermagnetic. Hey, good to see you again.
I've always been curious why not use HTML for desktop GUIs. And then also adds that these are
definitely nice looking graphs and user interface, which is cool. Maybe I'll let you all take a shot
at answering that question for you. If you got that, if not, I could throw something out there as well.
Because we got a ton of Electron apps that fit that realm.
That's what I was going to bring up with Electron.
And VS Code and other things, Slack and whatnot. I think there's a couple areas that you would care
about. One is you probably are not going to be getting 300 frames a second refresh rate with HTML.
There's a lot of layers in there. If you want to take advantage of the GPUs in like deep ways,
if you want to push a mesh of objects in there and then have them re-rendered, that's not really what
HTML is for. The native integration also gets tricky. I don't know about Geopie GUI,
but you want to integrate with the menu bar and other stuff, right?
Yeah, we need the hardware access. Now you can use WebGL, but basically you'd be using HTML just to
create that GL canvas. And then after that, it's the same thing as what we're doing now. So you could
do that. I think we have some sample projects where we use that. You can get 60 frames a second higher,
but again, you're just using HTML just to get to the canvas. And then after that, the HTML is gone.
Yeah, you'd use it for anything.
Let me see here if I can get a quick read on say like VS Code here. Hold on. A little activity monitor
doesn't.
If I happen to run through the browser, there's your text stat becomes considerably deeper when we're
trying to be as light as possible.
Yeah. Yeah. If you want to do a lot of the stuff that we're seeing on the screen here,
you're almost down to rendering directly on canvas. And then at that point, there's not a huge value
for the HTML side of thing because you're just drawing pixels anyway. So to wrap that up,
I'm a trap hypermagnetic says I've seen performance issues with electron versus more native apps.
Antonio out there. Hey, Antonio. Good to see you. Loves these plotting features. He's also in the oil
and gas industry. So very, very cool. Great. And following up on that, John says there's also a
limitation to threading and concurrency, which you definitely have more control, right? Very quickly.
So for example, like I just launched VS Code and it's doing nothing. And there's one,
two, three, four, five, six, seven, eight, nine, 10 processes running VS Code, which quick math
across those looks like something like 350 megs of RAM. I don't know what your pipe would take,
but I suspect it would be far lower than that.
It should be much lower.
So you're multi-processing and so on. It's pretty neat. Although Python itself is not known for its
massive, taking advantage of multi-core stuff because of the deal. Still, you got a little
more flexibility. Cool. It's always interesting to think about. Now, let's see, let's scroll down and
look through a few more of these pictures here. So you've got this node editor and this node sounds like
a core thing in this UI framework.
Yeah. That's another one of those libraries that somebody had built on top of GUI. It's usually
just a single file and a pretty light. A lot of people made some really cool stuff with that
because you could put any widget that's in the UI library in these nodes.
So let me take a shot at trying to describe what this looks like for people listening.
You can check out under node editor on the GitHub page. It almost looks like a database diagram
where you've got relationships between these nodes. But instead of just having table info,
you've got graphs, you've got XY values, you've got other little bits of computation and stuff that are
visually in the nodes that are also connected together. That looks pretty cool.
Kind of like a data flow thing, which is an actual picture you're looking at. It is a tool we built here
at work to prototype some of the systems that we're working on here. We took a little piece of that as
a snapshot. But yeah, it's a pretty cool feature. A lot of people do a lot of cool things with it.
So it was the idea I could build a little section that will take in some, let's say, fluid flow rate and then
apply some algorithm and visualize that. But then it also is an output value that can be flow
passed on to some other simulate part of a simulation that's also showing up there and stuff. Is that my understanding?
Yeah, that's it. And you can redirect the inputs from one to the output of the other
or whatever widget that are being connected, whether it be a slider and input or radio box, any of those.
And it's a pretty low level. Some of this stuff can be a little bit misleading when you look at it and
it looks like it should just come around out of the box. And most of these are not. For instance, the this node editor that you're looking at
in general, you create these nodes. And when a user tries to grab one of the pins and link it to another one,
another one, the callback is ran and it's up to the actual user to decide whether to make that link
where it's given information about where it came from, where it's trying to connect. So it's really up to the user to make something with it. It's pretty low level. And you'll notice that with a lot of these, even in the plots, they're low level. And it's meant for the user to wrap on top of and build more complex.
I don't know. Because we want it to be as generic as possible.
There's an example of Tetris, like who doesn't love Tetris, of course. What is this last one here? Several tools to help developers.
There's a lot of built in tools.
As far as it's like tab, tab views and list views and stuff like that. Or what are we talking about?
As an example, like you create whenever you go to create the UI, you may create a window and then add a group and then a collapsing header and then a button. And you have this parent relationship. One of the tools is the item registry. And when if you just type in the command show item registry,
you get this basically tree view where you can look through all the items in your UI, click on it, see information about the state of it. Is it visible? Is it clicked on? Is it hovered? That's one of them.
Most of these use for debugging.
Yeah, it's mostly.
Yeah, it's tricky to get a view into that kind of stuff in the UI, right?
Right.
Obviously, you can print out something or set a breakpoint and see it. But a lot of times they're hierarchical and whatnot. And the right visualization of that makes a big difference.
Another great one is to say, if you're loading a texture or a couple of textures into the texture registry, preparing them to be added to a widget, you can use the texture registry viewer to actually go in and inspect your different resources. Like you can preview it before you actually use it.
Oh, that's really cool. Yeah.
And with fonts, you can inspect fonts and other things like that.
Is DeerPy GUI primarily focused on 2D UIs? Or does it have a 3D component?
Right. So we are currently it's 2D, but we are working on a 3D engine to go with it.
But the UI won't be 3D, but there will be 3D widgets and we can have support for that now, but it's not hardware accelerated. The actual 3D engine we're working on will be.
Yeah, cool. So for example, like all these charts that are on the GitHub page that are active and moving, like I can totally imagine that one of it is spherical or it's, it's modeling.
You know, it's spikes that represent peaks of some kind of measurement all over the place and you want to look at it from different directions and whatnot.
Yeah. And I think at the bottom of the readme you can see some examples of users that have already skipped ahead and hacked into some 3D work.
Yeah. Like there's a gallery section that people should check out. One of the things I really like to do when I hear about a new UI framework or some tool that does UI graphical stuff is to just go look at the screenshots and go, what I want my app to look like this.
Maybe that looks pretty cool. Let me take the time to learn it. Honestly, it blows my mind. There's a lot of UI frameworks out there that don't have a single screenshot of what your whole job is to build pictures. Show us some pictures.
Yeah, really important gallery part of it.
Yeah, the gallery is looking really good. So one, it looks like almost the first one is almost like an AutoCAD thing. It looks like some kind of turbine or something is there. Maybe you know more about it. You guys can see them.
One of the users made it wasn't sure what they were working on. We helped them a little bit with getting access to the underlying OpenGL context because that was on Linux, but not sure what they were working on past that.
This next one looks like some kind of modeling system. Another one of those user saw a user with it. We snapped the photo and again, no idea what they were doing with it. Just looked cool.
Definitely looks cool. Bunch of left-hand side, right-hand side elements here. Almost looks like it could be modeling some sort of machine learning thing, but I don't think so.
Yeah, definitely some kind of interesting model here.
It might have been.
Some really nice visualizers here for, it looks like maybe looking at some astronomy stuff, which is great. And then a game and some more drawing tools. Yeah, here is this maybe a ray tracing?
No, that was just a Phong, just a Phong render that we're working on when testing some of the earlier versions of the 3D engine we're working on.
Mm-hmm. Okay.
So that's just some of the early prototypes. And we thought it was a pretty neat picture to do. And you can do that now if you just kind of, like that other user did, just hack in and get access to the OpenGL context or GrimDirect tags.
Okay, so one of the things it sounds like you can do is work with your PyGUI, but when maybe there's some low-level thing you need to do, like a shader context or some weird graphical thing, if it's not directly supported, you can just go, all right, let me just get straight to the OpenGL context object.
All right.
That's correct. And for now, that's the way it's done. But one of the things that we've been working on, and a lot of the users have been around a while and know this is, like I said, right now, the backends are Windows, we're using DirectX 11.
We're Linux, we're using OpenGL, and for Mac, we're using Metal. That was early on, that was probably a bad decision. So now we've been working on replacing the backend with Vulkan across the board.
And part of that would be that we'd be able to directly support giving users access to the GPU there. Because one of the things with the library is we do want it to be cross-platform and not have to change the code, pretty much not have to change the code at all across the platform.
Right.
Right now, with us using different backends, we wanted to expose access to compute shaders. But when you're on Windows, you'd have to write in HLSL. When you're in Mac, you'd have to write it in whatever the language is, Metal.
And then in OpenGLSL. So by switching to the Vulkan backend, we're going to be able to expose that and use the same thing across the board. And that's part of one of the big things that we've been working on. And it's taking a lot of time, but in the 3D engine itself is also going to be written in Vulkan.
I see pictures of that too, by the way, on the...
Okay, where do I find those?
Go to the very top. You might have to actually click on my name, but it's dp3d.
Oh, got it, got it. Okay, so it's a separate repo up there.
It will be combined. It's just while we're prototyping.
Sure, sure. Right here.
And by the way, nice GitHub profile. Your nice readme looks good.
Yeah, here you go. So the DeerPy GUI 3D engine. Pretty neat.
Oh, look at that. Yeah, you do have some cool pictures in here.
That will be...
And that's the stuff you need, true 3D stuff.
Yeah, that's true 3D, real time.
Let's go back just for a minute on this cross-platform business, because I think this is worth thinking about.
First of all, I was really impressed that you had support for DirectX and Metal and OpenGL,
because that means on Windows, you get the best option there, which is DirectX.
On macOS, especially in the new Apple Silicon ones, if you want to take advantage of the GPUs that are built in there,
the best way to do that is Metal and so on.
But yeah, those APIs are super different.
So if you're going to expose them, say, here, let me just hand you the low-level context and talk straight to it.
Well, setting them up for getting locked into one or the other, plus also having to learn Metal and or learn DirectX and all that, right?
And again, that's part of the reason we are switching to Vulkan.
We will leave those backends as legacy.
Legacy is a bad word, but you'll be able to switch to those backends.
But if you're really wanting to do the low-level stuff and wanting to access the 3D engine, you will have to use Vulkan.
Yeah, so tell people about what this Vulkan thing is.
I've heard of it as a way to have one API that talks both DirectX and Metal and OpenGL or something like that.
Is that sort of the deal?
OpenGL, DirectX 11, and I guess that's the two main ones.
The older, I guess the previous generation graphics APIs, and those are used to, they go through the driver and they talk to your GPU directly.
Like I said earlier on in this, that basically the hardware has changed considerably since those APIs were designed.
Very, very different.
So it's a lot more work on the driver developers to have to go from, here's how the hardware works, to here's the API we had.
So the move over the last five or six years has been towards these lower-level graphics APIs like Metal, DirectX 12, and Vulkan.
And these are considerably lower-level.
Just as an example, to get a triangle on the screen in DirectX 11, it's maybe 300 lines of code.
In OpenGL, it's maybe 100, if that.
To do it in Vulkan, you're easily at 1,000, just getting a triangle on the screen.
Really?
I was already feeling bad that it was 300 in DirectX.
And I can just remember the OpenGL code.
Set the scale.
Set the transform.
Set the viewport.
All of those things.
It's not easy programming type of work.
So Vulkan is even lower than that, huh?
Right.
Vulkan and DirectX 12 are really your lowest level.
But DirectX 12 is just Windows.
And with these APIs, you're able to utilize so much more in terms of what your GPU is capable of.
But you have to manage a lot more.
And that's part of why even the 3D engine and that switch in the back end is taking as long as it is.
Because the driver developers do a lot less for those APIs.
As an example, in DirectX and OpenGL, you can say I need a texture and load it with data.
And that's it.
And you can do it as many times as you want.
And Vulkan and DirectX 12, there's a max number of times you can do that.
I think the low number is maybe 4,000 allocations.
So it's up to you to instead allocate one big block, manage it yourself, and not keep doing that, as an example.
Right. You end up with those sort of maps, right, where this square is the actual whole picture or something else.
But to the right of it might be some other thing that you load all into one texture and you viewport into it or something.
Yeah.
Yeah, that doesn't sound fun.
It could be fun, but also you pull your hair out.
Another one of the things that the new APIs have changed is actually having to synchronize between the GPU and CPU and DirectX and OpenGL.
When you swap the buffers, execute this draw, whatever you're doing, your main loop where you're doing that, you don't have to wait until it's finished.
It's automatically synchronized between the GPU and CPU.
I see.
With the new APIs, that's not the case.
You typically, you have to actually add in barriers and fences between the different operations and just a lot of stuff.
You typically have more than one frame processing at a time.
You can actually utilize multiprocessing, which is a problem right now with Python because of the GIL.
So even though Vulcan has that, you can't really utilize it yet.
Maybe the no GIL stuff will gain traction in it.
It won't be a problem anymore.
One can hope.
So when I'm looking at this Vulcan page here, I see Windows, Switch, Stadia, Linux, Android.
I don't see macOS.
Is it still support Mac or what's the story there?
So the Molten VK is a layer on top of metal so that you can use it for Mac.
It's not directly supported.
You know how Apple is.
You got to use Objective-C.
They don't want you using C++.
It's not as supported.
It's the same thing.
They deprecated OpenGL.
And as of right now, there is no direct support for Vulcan.
So Molten VK is the...
See, it's like an intermediate layer between metal and Vulcan.
Right.
Talk about possibly leaving metal in.
Yeah, we...
As a support.
It's a possibility too.
Leaving...
It breaks your perfect abstraction though.
Yes.
Right.
What are you going to do though?
Pretty cool.
Metal's already doing that right now.
Some of the formats for the textures aren't supported.
That's a good point.
It's a little annoying.
Yeah.
Everyone's a snowflake over in the Mac world.
That is correct.
As I say on my Mac.
Okay.
Let's see.
One of the things I liked when I was looking through here is you've got a nice getting started tutorial.
Maybe we could talk just a little bit about just what the code looks like to get some stuff on the screen.
But you also have some video tutorials.
Jonathan, I know you put some of these together.
A while back.
They're a little outdated.
They're 06.
06.
Which is pretty old.
But we need to recreate them soon.
As someone who creates a bunch of videos.
They're very tricky to keep them in sync.
You can't just edit a few words or change a thing here.
It's different.
But yeah.
So people want to learn through the video style they can go through and watch some of these and get a sense of simple plotting or working with tabs and stuff like that.
Right?
Mm-hmm.
Yeah.
Most of the things are there.
Documentation still is a bit.
But with video tutorials and our read mirror, it's still a little bit lacking.
There's still some stuff that's undocumented that we're having to add.
But that's part of the point of the demo is you can see how all those, you know, most of the features are there and you can see how to code them.
Yeah.
But that's no excuse.
That's for us not in doing it for the docs.
I went to Toptal to hire a solid developer at a fair rate to help create those mobile apps.
It was a great experience and I can totally recommend working with them.
I met with a specialist who helped figure out my goals and technical skills that were required for the project.
Then they did all the work to find just the right person.
I had short interviews with two folks.
I hired the second one and we released our apps just two months later.
If you'd like to do something similar, please visit talkpython.fm/Toptal and click that hire top talent button.
It really helps support the show.
That's true.
But also contributing to the docs and contributing to a tutorial or something like that.
That's also a good way for people to contribute.
That's a very good way.
Are you all open to having contributors and PRs and other things along those lines?
Apps.
Yeah.
I had a bunch of PRs and welcome to join the Discord.
We're in there all the time talking to people about when they're working on different spots in the API.
The problem is, you know, most of the users are Python users and libraries written in C and Objective-C and things like that.
So it's just a little bit of a disconnect there where a lot of users would like to help.
And when they go over to the library and see it's that, they go, oh, right.
You know what?
Actually, I wanted to work on a Python project.
We have this problem in a lot of the very popular places.
People want to contribute to Python itself.
And often that means C, not Python.
And darn it.
People want to contribute to Jupyter.
But a lot of times that means JavaScript, not Python.
Like, oh, come on.
But yeah, that's kind of what it means to build tools sometimes.
You guys have the demo fired up on your screen here.
Maybe you want to just talk us through a couple of the highlights and how we get this thing going.
Sure.
Got to keep in mind that not everyone can see what we're seeing.
So you can see the demo.
And we modeled this after GUI's demo and some of the other demos we saw of people doing similar things where you can see all the different features.
So if I pip install DeerPyGUI, is there just a command I run to just get this going?
It's one of the modules.
You have import DeerPyGUI.deerPyGUI.
And then you have import DeerPyGUI.demo.
And there's just one command show demo.
So you could even do that from a REPL if you wanted, right?
Yeah, you can.
And do that right away.
So you can kind of see a lot of different widgets.
Just your typical UI widgets that you have.
Yeah, go back to the widgets real quick for a sec.
Yeah.
So you've got a lot of nice ones.
You've got buttons.
You've got checkboxes.
You've got radio buttons.
You know, like you can only select one versus checkboxes.
You've got drop-down combo boxes, text, text with placeholder hint, I guess.
One of the areas that you have a lot of UIs around is the slider, what do you call them?
Slider float, slider ints.
It's like a thing that has a number, but then as you slot, you can not just type in it, but
you can drag it around and actually scale it.
I see this a lot in the Adobe Tools Audition.
You can go on if you want to change something.
You can click on a number and just move the mouse instead of typing to the number.
There was a lot of these other things because, again, this is really meant for a lot of 3D
engines and content creation.
A lot of color maps and things like that.
Let's see what else.
Text input, a lot of stuff here.
And remember, I told you a lot of the back ends are the same exact numbers, so you can get
things automatically like this.
All of these are linked together.
All right.
So what you're doing, there's like three text boxes, one that's plain text and two that
are passwords.
And as you type in one, they all, it's not real practical for passwords, but as you type
in one, it'll show you in the different locations.
So we're showing different flags, just different flags.
Yeah.
How do you create that binding between them?
Is that...
Well, that's what I'll tell you.
There is no actual binding.
They're truly the same value underneath.
Whenever you go to create this, let's say you call this item password one.
And when you go to create the second one, you can specify a source as password one, and
it will just, rather than have its own value, it will just truly use a pointer to the other
one.
And that's why all these...
Yeah, yeah.
That's really cool.
So that's how they stay in sync is...
Yeah.
Because they just, they are the same data.
Yeah, exactly.
It's free.
It doesn't cost anything.
There's no callback that has to run.
A lot of basic, simple plots for just pretty simple stuff.
Let's see.
Again, these are linked in the same way.
Okay.
Yeah.
So I encourage people, if they want to think about this framework,
is create a virtual environment, pip install Geopi GUI, and then do the import command to
run the demo.
Yeah.
Yeah, really.
Date pickers.
But some of the cooler ones that, you know, you want to see, I mean, I can show these.
These are all pretty typical on most UI libraries.
I don't know.
Some of the ones...
That's on the knobs.
That's true.
Some of the ones, I guess, we have a table API, which...
Oh, that's nice looking.
Pretty cool.
You're able to...
These examples are just showing text, but you can put any widget.
You can put plots.
You can do all kinds of stuff.
So, yeah, with the table one, probably, if people think about it, like, it probably would
be called a grid in a lot of frameworks.
It's kind of a read-only Excel type of view, but very colorful and nice.
These aren't read-only.
These can be any widget you want.
They're more layout.
Oh, so you can put, like, a graph in one of the cells?
Yeah, you can put a plot.
You can put a node editor.
You can put anything you want in these.
It's best to think about a table as more or less a layout, essentially just giving you
columns of rows where you can put anything in it.
Oh, yeah.
Okay.
That makes sense.
Yeah.
And you can see here, this sorting one, you can kind of see.
You've got a checkbox in here.
I think there's an input at different things.
Tables, school, like I said, there's tons of plots.
Yeah, there's lots.
Anyone wants to put in the mouse.
And we have that example that you saw in there.
Oh, yeah.
You even have that detail, high-level and the detail graph in there.
That's cool.
Do you have trees?
We do.
Stuff with textures and the high-performance flip stuff.
The, for those that haven't seen, where's that?
The node editor.
So, those that are unfamiliar with that, I ran out of room here.
You know, this is for these node editors.
That node editor is exactly what I expected.
So, you've got these three little boxes with different bits of information or graphs, and
you just drag and connect them.
And, yeah, that's fantastic.
And you can put any widget in the library in these.
So, it's not limited to just, you know, a small subset.
And then, again, with the drawing API, your typical stuff that you're used to and other
drawing APIs, being able to draw a line, a box, a cube, things like that.
And then, also, some support for a lot of 3D operations, things like perspective divide
and depth clipping and all that to help support these type things.
Let's maybe round out our conversation here by talking a bit about, just give us a sense
on what it looks like to write some code.
So, there's not, I'm guessing there's not a graphical designer type of thing, like Xcode
storyboard or whatever.
We're not big fans of those.
Yeah.
You do this through code.
Yeah.
You build up your UI through code and layout elements.
Right.
Just give us a sense of how do I get, like, a text box and a button or something on the
screen.
What does the code story look like?
We talked about the 100 lines of OpenGL or whatever.
So, pretty much every DPG app, you just import DPG.
We do it as DPG most of the time.
From there, you'll create a context, which basically sets up the I'm GUI context, sets up
I'm nodes, sets up our internal context with all the different settings and state.
Oftentimes, these lower level frameworks, they have to go and get some context from the
graphics card itself and, like, get that from the operating system.
And I'm sure that kind of wraps that stuff all up.
Absolutely.
And then from there, you typically create the viewport.
And again, that's platform specific.
On Win32, we're using Win32.
We're using X11 on Linux.
And on Map, we're using Carriover or whatever it is.
We'll touch that one in about a year.
You got it working.
And there you decided to stay away from it.
Got it working and walked away from it for a while.
So, the viewport is basically like an empty window?
Right.
It's your actual operating system window.
Got it.
We call it a viewport.
And from there, you can create something like a window.
There's these root objects.
A window is like the I'm GUI window that you see below.
The blue window that you would see on a demo, things like that.
floating windows within the main viewport.
From there, to just add something like a text widget, it's dpg add text.
dpg add button.
dpg add input text.
Whatever the widget is.
And you can impose the hierarchy of parent-child relationship with context managers kind of the way that you could just use.
If I'm going to create a window, one of the windows, one of multiple possible windows, instead of creating a window object and say window add this or that, you would create a context manager and just do a bunch of ads.
Because.
Then it all just goes to that window.
Right.
Again, we're not object oriented, which kind of also sets us apart here.
If you weren't using the context manager, that same operation would be dpg add window.
And it returns either an ID or you can put the ID in with the keyword tag equals whatever your ID is.
Then you would push to the container stack.
And then when you're done adding items, you pop it back off.
The context manager handles that for you.
Right.
So it's adding the window, pushing it and popping it.
And if you wanted to do something, like I said, it's not object oriented.
So when you do add button, you don't get a button back.
You get a handle to internal button.
And then you use that handle and you can store it.
Just say B equals dpg add button.
And then all the various commands, you would use that handle to control it.
If you want to say, get the checked state of a checkbox.
Right.
Get value.
Yeah.
Or configure everything you did when you created it.
When you started off, you can modify later on using configure item.
And then you just pass in that handle and go from there.
Cool.
Is there an event loop type of thing?
There is.
So after you've created the viewport and you add your widgets, you would do set up Deerpy GUI.
And what that runs is that starts up the second thread.
We have two threads.
We have the rendering thread running.
And then we have a callback thread where all the Python's at.
So that's what set up Deerpy GUI does.
Show viewport actually shows the viewport and starts basically the platform specific event loop.
From there, start Deerpy GUI.
That is your event loop.
If you actually want to see the event loop, you would just do while is Deerpy GUI running, render Deerpy GUI frame.
Right.
And you could do everything you want inside of there.
And then when you're completely done, you destroy the context.
Looks super straightforward.
One thing that I don't see here is the callbacks.
So like when the slider slides or the button clicks, is there some way to hook that action?
Like obviously the save button is going to need some.
Yep.
It's a callback.
It's a keyword for callback.
And basically it can have three arguments.
The sender, which will send you the ID of the item that called the callback.
The second one is app data, which for us that can be either the value or if the callback's related to window resizing, it'll be the new size.
It's just data that DPG sends you.
And then the third argument, user data, is user can pretty much put anything they want, then it'll get passed through.
And it's useful for a lot of people that are creating OFB wrappings around the library.
Yeah, nice.
Is there one callback that handles all the events and then you do like a switch statement?
It's really up to the user.
You can have a different callback for every one or you can have one master callback where you just check the sender and do different operations based on what called the callback.
You have a little bit of freedom there.
We do have callbacks you can attach to inputs such as the mouse or the keyboard or the window resize.
Like you mentioned, we have callbacks to set up.
It is nice to be able to say, when this button gets clicked, do this.
And that makes it real simple.
But there's also times that you might want to, I want to capture all the button clicks and then do some common thing regardless of which button gets clicked.
It's nice to have that flexibility to go either way.
That's the biggest thing.
We try to be as flexible as possible and allow really geared towards a lot of people wanting to wrap and create their own kind of interfaces.
So there's a lot of freedom.
So I noticed that you have this, you call it the viewport, this like window that comes out of the operating system.
And then the DeerPy GUI windows live in that space.
Is there a way to simulate it looking almost like the DeerPy GUI window is the whole thing?
Could I not show the title bar of the one window and then maximize the inner window to fill it?
You can undecorate the viewport.
There are settings for that.
And then we have a command that's set primary window and you can basically set one of the, whatever I'm doing, one is the primary one and it'll fill the whole viewport.
And you get that.
But you can't necessarily move them.
When you do that, you can't have multiple viewports at the moment.
We're still working on that.
Is there like modal dialogues and that kind of stuff in there?
There is modal dialogues.
There is file dialogues.
A lot of people still tend to just import to Kenter and use their file dialogue because a lot of people don't like ours.
It's right.
The context menus.
Yeah, it looks great.
Like I said, people who are possibly interested should check out the gallery on the GitHub page.
That's a good litmus test of what does it look like if you want to use it?
I think it looks pretty good.
I like it.
Sure.
We're getting close to the end here.
One thing, we talked a lot about the future stuff already.
Maybe we don't really need to go into that.
We've got the Vulkan backend, the 3D engine and stuff like that.
One of the things that I always want to do with a GUI is put it into my taskbar or put it into my macOS dock.
And I want to be able to give a binary thing to a user and not tell them about virtual environments and pip install and all that.
What's the deployment story about giving somebody a distributable version of this app?
So a lot of users have used some of the tools, Pi, Pi 2.
Like Pi Installer or Pi 2.
Things like that.
Yep.
We did early on when we first started the project, had a batch file and some batch files that packaged it up for you.
Actually created the executable and everything so we could hand them around here, embedded the Python interpreter and everything.
We did remove those, but we do eventually plan on adding back.
So we really don't like having dependencies on other libraries.
So even though you are using that now, we would like to bring back that.
It wouldn't be that hard.
We already do that.
When we develop it, we are using an embedded version of Python and an executable.
We're not actually using this.
What is it?
This utils.
And we're not using any of that.
We're actually just using the Python C API directly and embedding it.
Yeah, just as a sidebar, one of the things I really think would benefit Python as a community is if there was just a built-in Python-M package or build executable or whatever.
And out the other side comes a .app, a binary Linux app, or a .exe.
And you just hand it out, right?
There's so many scenarios where people would like a tool that they would like to be able to share.
I feel like it's a bit of a chicken and egg thing.
People aren't doing that very frequently.
So why do we need that feature?
Well, they're not doing it because it's so super hard and fragile, right?
If it were as easy as pushing a button, I think maybe people would do it more.
So I don't know.
Anyway.
Absolutely.
That was one of the original reasons for our engineer sandbox project way early on is we did do the tools in Python, but we couldn't hand them to people.
We had to tell them, we got to install Python and then pip install this.
So the idea of that one was we were able to just hand them that.
A little bit wrap up on the audience side.
Mr. Hypermagnetic once again says, very nice design and similar to small JS libraries.
Yeah.
Nice.
Appreciate it.
Looks good.
Last thing.
I always am interested how these projects gain traction, how people find time and energy to put into them.
And one of the ways is for companies that use them or people that use them to sponsor you guys.
So you guys have a sponsor option here, which is part of the GitHub sponsor story, right?
We have GitHub sponsors.
I think that's actually a pretty big deal because it used to just be like, oh, you put a PayPal donate button or something on there, which is fine and all.
This is an awesome feature that they, I guess, Microsoft added.
I assume that they're the ones that did it.
Yeah, it's pretty good.
We do have the GitHub sponsors open collected and buy me a coffee.
Yeah.
So this is a part-time project for you guys, not full-time.
It sounds like you're doing mechanical engineering work full-time.
And then also this both at work, but then also bringing it out to the community a little bit.
That is correct.
If it directly applies to something we're doing at work, a bug or something, we'll add it here.
But for the most part, it is at home at night, you know, after our families are in bed and working on it there.
A labor of love.
Awesome.
And it's great.
It's great to see more UI frameworks and more UI innovation in the Python space.
So thanks for doing that.
Now, before we get out of here, let me ask you all the final two questions.
If you're going to write some Python code, what editor do you use?
Typically PyCharm.
Yeah, pretty much PyCharm.
And then a notable PyPI package, something you've run across.
Like, oh, this is awesome.
People should know about.
Typically just numpy is about the only one.
NumPy is about the only one to use.
We like to reinvent the wheel.
Viewer dependencies.
Right on.
Anthony out in the audience says, I'm guessing, question mark.
Does DearPython GUI play nicely with third-party libs like Nutka, PyInstaller, and so on?
PyInstaller, I know it does.
Nutka, I do not believe it does.
And then numpy or anything that supports the buffer protocol, you can use in a lot of our functions.
Very nice work.
Final call to action.
People want to get started with DearPyGUI or maybe give back to it.
Sorry, and Anthony says, it was a statement, not a question.
Thanks, Anthony.
Nice.
Yeah, final call to action.
People want to get started with DearPyGUI.
What do they do?
Just pip install and run the demo on the readme.
You can also join our Discord server.
There's about a thousand.
Go through the reason.
Read the docs for sure.
Read the docs.
Contributing would be nice.
We're still in the middle of refactoring a lot of things internally, so it may be a little
hard.
But other than that, also just sponsoring really helps out, makes it worth it.
Jonathan, Preston, thanks for being here.
Appreciate it.
You bet.
This has been another episode of Talk Python to Me.
Thank you to our sponsors.
Be sure to check out what they're offering.
It really helps support the show.
Take some stress out of your life.
Get notified immediately about errors and performance issues in your web or mobile applications with
Sentry.
Just visit talkpython.fm/sentry and get started for free.
And be sure to use the promo code TALKPYTHON, all one word.
With Toptal, you get quality talent without the whole hiring process.
Start 80% closer to success by working with Toptal.
Just visit talkpython.fm/Toptal to get started.
Want to level up your Python?
We have one of the largest catalogs of Python video courses over at Talk Python.
Our content ranges from true beginners to deeply advanced topics like memory and async.
And best of all, there's not a subscription in sight.
Check it out for yourself at training.talkpython.fm.
Be sure to subscribe to the show.
Open your favorite podcast app and search for Python.
We should be right at the top.
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.
We're live streaming most of our recordings these days.
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.
This is your host, Michael Kennedy.
Thanks so much for listening.
I really appreciate it.
Now get out there and write some Python code.
I'll see you next time.
Bye.
you
Thank you.