Transcript #138: Will PyOxidizer weld shut one of Python's major gaps?
Return to episode page view on github00:00 Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to
00:04 your earbuds. This is episode 138, recorded July 3rd, 2019. I'm Michael Kennedy. And I'm Brian
00:10 Akin. And this episode is brought to you by DigitalOcean. Check them out at pythonbytes.fm
00:14 slash DigitalOcean. More on that later. Brian, how you doing? I'm good. Been recording a lot.
00:19 Yeah, recording a lot and trying to survive a work move, huh? Yeah, I'm not looking forward
00:24 to half an hour drive. Yeah, a work move is like when you get to move and your commute changes,
00:29 but you don't get any say in it, right? Yeah, exactly. Yeah, I don't know if people know,
00:33 but traffic in Portland and in the Northwest, it's rough, man. Yeah, but I mean, I lucked out. So for
00:39 like nine years, I had a 10 minute commute. And I know a lot of people have worse commutes. Yeah,
00:44 my commute is really rough. My studio area is like above my garage and the garage is detached.
00:49 So I go across the sidewalk and periodically there's like a squirrel or something that will
00:52 startle me a little bit. And that's like a rough commute for me. Yeah, I'm just kidding. No one
00:57 should feel sorry for me on that regard. That's awesome. Nice. All right. Well,
01:01 speaking of keeping everything like legit and keeping surprises out of it, that's probably where
01:07 we should start, huh? Sure. You want to jump into the first item? Yeah, yeah. Flightgate,
01:10 let's do it. Okay. I use Flightgate all the time. I actually put it on almost every project to make
01:15 sure that I'm just not doing something stupid. So it does a whole bunch of different, I think we've
01:21 talked about it before. But one of the things that I came across, this was submitted by Florian
01:25 Dolitz, I think, is Flightgate Comprehensions, which is a plugin for Flightgate. You just install that
01:31 also and it'll run automatically. People are used to list comprehensions, but there's a whole bunch of
01:36 other things like dictionary comprehensions and things like that. Set comprehensions, yeah. Generator
01:42 expressions, all these things, right? Yeah. There might be some old code that works fine, but maybe it
01:47 would be easier to read if it was changed. So this is just some static analysis for your code to
01:53 check different things to, you know, make your code look nicer. Awesome. Like some of the warnings are
01:58 unnecessary generator. Rewrite that as a list comprehension or unnecessary list comprehension.
02:03 Rewrite it as a dictionary comprehension and interesting stuff along those lines. So yeah,
02:09 that's pretty cool. I'm going to hook it into all my projects. I haven't tried it yet to see if it's
02:13 helping me at all yet, but it looks like a fun thing to add. Yeah, there's some nice little
02:18 cleanups here and I'm just kind of always amazed at how similar the comprehensions are, but how different
02:26 the resulting outcome of them are. You know, especially with list comprehensions, square brackets,
02:31 and generator expressions, parentheses. One is like this lazily evaluated generated expression that can
02:38 be used once. The other is a list, right? But it's like you just round the edges a little bit on the
02:42 symbol and that's it. Yeah. And I always forget that set comprehensions are a thing. So nice,
02:48 nice. Yeah. So these are great. I feel like these are in the category of Pythonic code that a lot of
02:53 folks don't know about, don't use and so on. Right. They're like, well, in C++, what I would do is I
02:58 would write a for loop. And so they have four in loops in Python. So I write that as like, actually,
03:03 we have these comprehensions too. You don't need that. So pretty cool.
03:06 Anytime I can move code reviews out of personal opinions and into a static analysis tool, it just
03:14 makes the team smoother. Yeah, absolutely. I think it's really interesting psychologically that people,
03:19 developers respond differently to criticism from a robot than they do from a human.
03:23 Yeah. I mean, it's like a compiler warning or something at that point.
03:27 Exactly. It's like, well, CI says you got to do it. So we all agreed that this is how it's going to be.
03:31 So we do it rather than like, well, that's the guy that's always picky and always says to rewrite
03:37 my code and it's not Pythonic. I don't want to invite him to lunch anymore.
03:40 It's like somebody will pick up the torch and be the one person that's always telling other people
03:46 that they're, they need to change their code because of style. And that just gets old. So yeah,
03:51 let the computer do it. Exactly. And it's more consistent anyway, no matter how anal the person
03:56 is the computer is more so. So this next item here is something that is near and dear to my heart.
04:04 We've covered it before when it first came onto the scene, but it's now really ready to go. Now I
04:11 want to just set the stage here that I think, you know, we've talked about this before. I can't remember
04:15 where, but we've spoken about before that basically, you know, Python's growth is incredible. We've talked
04:22 about that a bunch, but fast becoming one of the most popular languages, but there's really three areas in my
04:28 assessment where Python could be, you know, it's weak or it could be dethroned or it could in the words of
04:36 Russell Keith McGee actually be an existential threat to the longevity of Python. And those are a proper way to
04:45 build mobile applications with Python. I know we have Kivy and we have some stuff from Russell stuff
04:52 as well. Right. But those are like sort of, well, we'll get it working. It's kind of proof of concept.
04:57 It's not like a visual designer drag and drop. Here's how you push this button to publish the app. So,
05:02 right. Like there's not really a proper way to build mobile apps for Python. That's an existential threat.
05:07 Number two is I would like something like the Slack app in Python. Build that. Yeah. Good luck with that.
05:16 Right. Like probably not. So there are ways to do stuff like that, but it's always either like some
05:21 kind of kludge or it's, yeah, you can build it, but it's going to look like from 1994. Nobody wants that.
05:27 I mean, Qt's pretty good.
05:28 Qt is pretty good. Yeah. Qt is pretty good. I'm thinking, you know, TK Enter. It's like,
05:32 it's definitely showing its age, right? For example. So yeah, those are great. And so like,
05:36 GUI is probably the least existential threat of these, but it's very clear,
05:40 closely tied to this last one, which is sharing your application with end users. Somebody who doesn't
05:47 care whether or not your program is written in Python, they would just want to run your program.
05:51 How does that happen? Oh yeah. Yeah. That's a problem. And you, what was really interesting was there's a while ago I talked about Gita Van Rossen being interviewed
05:59 on, I think it was the AI, the MIT's AI podcast. It was a super interesting interview and a lot of
06:06 great stuff that he said, I think they talked about it there with him. If it wasn't there,
06:11 it was him being interviewed somewhere else. And basically they said, well, how do you feel about
06:15 this deployment story? It doesn't seem like a weakness. And Gita's thought was, well, you can
06:21 really use a lot of the Linux package managers to solve a lot of these problems. Like if I want Python
06:26 there, I can apt install Python three. If I need to get pip, I can apt install Python three dash pip
06:33 and so on. And it was very clear, like his whole thinking about what getting an application to a
06:41 user meant was getting it properly set up on a server or like a developer gets the tool set up on
06:48 their Linux dev machine, which is all well and good. But you know, the most important thing is how do I
06:52 give an icon thing to a person on a Mac or on windows? They can double click and then their thing
06:58 runs. You know what I mean? Yeah, sure. Sure. I mean, for all the people that need a dev tool on
07:03 Linux, there are a hundred more, a hundred times more who need an application as an end user. You
07:10 know what I mean? Okay. Yeah. So if we want to get, if I want to get something like say, if I've created
07:15 some data science tooling and I want to give that to my team, I would like to say, here's like a DMG or
07:21 an MSI installer, you double click it and then you run. I don't care what version of Python you got
07:26 set up or anything like that. Right? So I think that's the third problem is like, how do we get
07:30 like end applications users? And the reason I think it's partly, it's kind of this chicken and egg
07:35 problem. I feel like partly the reason it's not got a lot of attention in the Python space is because
07:40 it's so bad. It's like so nearly impossible that people just generally don't do it. So there's like not a
07:47 lot of demand for people creating those types of applications to get them out because it's like,
07:51 why would you use Python for that? It's like, doesn't even make sense. Right? There's Pi installer,
07:55 but it's also good, but it has some limitations. And so the thing I want to cover again is Pi oxidizer.
08:03 And the reason is it's now officially released. It has its first release. And I had been watching the
08:10 GitHub repository, you know, as like, you can say, go watch this repository. And my email just like blew up.
08:16 Like I couldn't, I just go and like was constantly cleaning up like pull requests,
08:20 issues, all this kind of stuff. Like people were just going crazy on their repository.
08:26 Okay.
08:26 It's just got a ton of traction. So that's out. And I just want to kind of highlight some of the stuff.
08:31 The guy who created it, gosh, Gregory created it. And he's done some awesome stuff. He wrote a really
08:38 nice article, which I'm linking to here. And it covers a lot of the reasons why you would want it.
08:43 So at PyCon 2019, like I said, Russell Keith McGee said, basically, this distribution problem is like
08:51 a potential black swan event for Python, right?
08:56 I still don't know what that means, but sure.
08:58 An unseen super negative thing coming out of the blue that's going to dramatically disrupt it somehow.
09:05 I don't know if I would call it that. But I definitely think that distribution is like
09:09 a reason people would not be using Python first term. I don't know if I see it as like this negative
09:14 sense, but I definitely see it as a, it could be so much more, right?
09:18 Yeah. I mean, Python's so great everywhere else. It'd be cool if it was great there too.
09:21 Exactly. Why is it not good there?
09:23 Yeah.
09:23 Gregory said, basically, I'm going to create this project called PyOxidizer and it uses Rust
09:27 to bundle up your Python code into an executable application. A .app thing on Mac, a .exe on
09:35 Windows, and a statically linked binary executable on Linux. So it works on all the different platforms.
09:42 And what's cool is it takes all the dependencies you have. So if you depend on say pandas or whatever,
09:48 right, it'll bundle that up. It bundles the version of Python that you build it against,
09:52 right? So you're guaranteed you'll have 3.7 no matter what system you put it on,
09:56 if you build it against 3.7.
09:58 Okay.
09:58 And what's really interesting is the way it works is it builds a single executable and then
10:04 your Python code is loaded from bytecode in memory.
10:08 Oh, wow.
10:08 Right? So like it actually creates your Python files. It creates PYC files. So pre-computed
10:14 PYC bytecode and then loads that out of memory. So it actually runs faster than if you ran the code,
10:23 it starts faster than if you ran the code in regular Python.
10:27 Okay.
10:27 Some tools care about starting fast. Some don't, right? Like a website doesn't really care about
10:31 starting fast. But a command line thing...
10:33 If you're going to write an editor, you want it to just pop open.
10:36 Exactly. So the other problem with the other ways in which this was done was they would basically
10:42 zip up your Python code and maybe unzip it and then try to run it from there in memory thing.
10:47 So you also kind of leaks your source code a little bit, right?
10:50 Yeah, I guess so.
10:51 So if this is embedded as a binary, it's less obvious for people to go poking around that this
10:57 is Python code that they can go read and mess with, right? Like technically, I know it still could
11:02 be messed with. But it's not like, well, here's the directory of Python files. What is this doing
11:07 in my applications route? You know what I mean? Let's go play with those, right? So this is pretty,
11:11 there's just a lot of interesting things here. The article that Gregory put out announcing it,
11:15 it's pretty broad and it's really compelling. So it seems like this project is really taking off.
11:20 I definitely think it would change the landscape if we had something like this legitimately working
11:25 well across the board on all the OSes. I think it would actually drive people to build more
11:30 GUI based apps because there would be a much more clear path on how to get those applications
11:36 to end users, not just developers and developer tools and servers.
11:40 Yeah.
11:41 Cool. Well, anyway, PyOxidizer, it seems to be catching fire and that's pretty awesome.
11:44 Yeah, it is cool. I like it.
11:46 All right, what you got? What's the next one?
11:47 Well, speaking of sharing code, one of the things that people do is not with end users,
11:53 but with just other developers is to take a script. You've got like just a, you know,
11:58 you created a script, a little module or something, and it works on your machine. You want to share it
12:04 with other people. Even that there's a little bit of a barrier between writing a simple script and
12:09 packaging it up properly and getting that running. So it's one of the things I'm actually working on a
12:16 write-up, trying to do a write-up of all that with experimenting using it with using Flit and pytest
12:21 and Tox and Coverage to make sure it's well tested and structured well and all of that.
12:28 That's cool. Because you were, before you were sort of a fan of creating a source directory for your
12:33 packages and, but that ran into trouble with like Flit, right? Or some Flit or Tox?
12:37 That's the thing. With Coverage, you want to be able to, I want to be able to test or run against
12:42 the installed version, not the local version. So I want to do all of the packaging, install it into
12:48 an environment, and then run the test against that. And that was hard to do. I thought it was hard to
12:54 do. And a lot of people were recommending using an intermediate source directory to hide the local
13:01 code from Tox and from, well, not really from Tox, but from Coverage and pytest so that you were
13:06 really loading the installed one. I didn't know there was a thing here. And I'm highlighting
13:12 a feature of Tox that's called ChangeDir. And it's really simple. You just put this in your test
13:18 environment lines in Tox, in your ToxAny file, and just say, change the directory to like my test
13:24 directory. And then, voila, you can't see the top level source code anymore.
13:29 Oh, that's cool.
13:30 Problem solved. So I've got a longer explanation. I'm going to talk about this on,
13:36 I have on episode 80 of Test and Code, which will be out by the time this is out.
13:40 But I was amused because I'm walking through an example. And I'm trying all these things to make
13:45 sure they work. And the example project I built was a markdown converter using regular expressions.
13:51 And I thought this was really funny because of the news that came out recently that Cloudflare
13:56 went down because of a regular expression.
13:59 A single regular expression. And Cloudflare is like the intermediary to so many applications
14:05 out there. That's bad.
14:07 Big chunk of the internet not working because Cloudflare was pegged on one regular expression.
14:13 I don't even know how to do that. I don't know how to make a regular expression that...
14:16 I do simple regular expressions. So I don't know how to do something that's quadratic in
14:21 nature. But I thought it was funny.
14:23 Mine tell me they're not working right away. But they say that too frequently.
14:27 Yeah.
14:28 Why is this not finding the match? Oh, well.
14:31 Since I thought that was... I was using regular expressions and I thought it was funny that
14:34 somebody else reminded me of that Mel Brooks quote that it's tragedy when it happens to me.
14:40 It's comedy when it happens to you. So I'm laughing at Cloudflare, but I wouldn't be laughing
14:45 if I was working there.
14:46 Yeah. If your pager was going off at three in the morning, the humor would be entirely sucked
14:51 out of that situation. Yeah, that's rough.
14:53 Yeah.
14:53 Before we get on to the next one, let me just tell you all about Digital Ocean. I try to highlight
14:57 one of the features of what they've got going on. Like I said, many times our infrastructure
15:01 runs on Digital Ocean and they do a great job. So one of the things you might not want to deal
15:07 with is setting up a Postgres server, backing it up, setting up the right scaling infrastructure
15:11 and all that. So Digital Ocean has this great feature where you can get a managed Postgres database
15:17 as a service, which solves a whole bunch of problems like figuring out what the optimal
15:21 database infrastructure footprint is or scaling it as your app grows or creating highly available and failover infrastructure, all that kind of stuff you want,
15:31 but you don't want to deal with it or deal with like when the pager goes off because it stopped
15:36 replicating or it wouldn't scale or whatever. Just go to Digital Ocean and check the box to get your
15:42 managed Postgres database and let them deal with it all. So that's really nice. Runs right there in
15:47 that data center. So you're all good. Check them out at pythonbytes.fm/Digital Ocean.
15:52 They're big supporters of the show and highly recommended. All right. So this next one, Brian,
15:56 I think has some pretty interesting possibilities and maybe ties back to my item that I spoke about
16:01 before creating like a new type of apps or opportunities for more apps. Now it used to be if you wanted to
16:07 have some kind of communication, you'd have to go install like weird plugins into your browser.
16:13 So you could do, I don't know, some kind of real time chat or video communication. But recently,
16:19 these things have just been working all on their own, right? Things like Zencaster and whatnot.
16:23 Now it could just do like live communication in the browser. And that's because of WebRTC and ORTC.
16:29 The Web Real Time Communication is an open project that provides browsers and mobile apps real time
16:36 communication. And then the open ORTC one is basically a similar style of communication.
16:44 Okay.
16:44 The item I want to talk about is this implementation for Python that uses asyncio. So you can write
16:51 Python applications that then communicate with other things like browsers or mobile apps and whatnot
16:57 that use WebRTC.
16:59 Oh, cool.
16:59 Yeah. So it's called AIO RTC. AIO is for asyncio and then RTC, well, you know, for the protocol.
17:06 So it's pretty cool. It follows pretty close to the JavaScript counterpart, which is how you would do
17:12 it in the web. But it uses a lot of Pythonic constructs like the popular JavaScript ones use promises.
17:18 So this AIO RTC uses coroutines, which is cool. And events are emitted using the PyEventMeter,
17:26 which is all good. The main ones, like the main one is if you want to explore these communication
17:31 protocols are all baked into the browsers and they come in native code. But if you want to explore like
17:36 a more understandable version, a more hackable version, this one is all just in Python, which is
17:41 pretty cool for understanding how it works. They also talk about some of the kinds of apps you could
17:46 build, right? So like you can create some new things in the Python ecosystem. For example, you could
17:51 build a server handling both signaling and data channels and apply like computer vision to the
17:57 video frames using OpenCV like in real time or something cool like that.
18:01 Oh, that'd be neat.
18:01 Yeah. So people doing fun stuff with video communications. If you want to write a Python
18:06 application that can participate in that and you want it to be nice and modern using async and await and
18:11 asyncio, well, this is a pretty cool AIO RTC.
18:15 Yeah.
18:15 Yeah. Speaking of communications, you got another one, right?
18:18 This was a listener's suggestion and I can't remember who submitted it, but I think it's,
18:23 and they even have the, it's called a prize. I think that's how you pronounce it. Is that right?
18:27 A prize. Yes. To inform or to tell someone, to make one aware of something. They've apprised me of
18:34 the situation. Really? Yes. Okay. Carry on. Sorry.
18:36 Okay.
18:37 So a prize is for push notifications and their tagline was push notifications that work on just about every
18:45 platform. It's kind of a shim layer to put between your app and multiple notification services.
18:50 So it sends notifications to things like, Telegram. They say Telegram push bullet. Never
18:57 heard of either of those Slack and Twitter. Yes, I have heard of those, but also things like a discord,
19:03 getter mail gun matter. Most Microsoft teams, even sending SMSs through Twilio or Nexmo that's
19:11 supported email notifications supported for that. Some things that are, you want to just email people,
19:17 but if your server's on fire, you might want to send an SMS to somebody.
19:21 Yeah, that's cool. It's really cool.
19:23 It looks pretty neat. The API looks nice. It looks like it'd be pleasant to work with.
19:27 So I think this is a good one to highlight. It looks neat.
19:30 Yeah. Some of the stuff that stood out to me is Growl and Windows notifications.
19:34 Do you know what Growl is?
19:36 So Growl is, I don't know if this is the way it still works in macOS, but you know,
19:40 the little toast notifications that come up in the top right in macOS?
19:43 Oh yeah. Yeah.
19:44 Yeah. Growl does that.
19:45 Oh, okay.
19:45 But you might have to have a little daemon installed. I can't remember if it natively
19:49 talks to Mac. I don't think so. I think Growl is like before that was built into the OS,
19:54 but basically it does that. And then Windows notifications like similarly, but instead of
19:58 being the top right, they're in the bottom, right? So they're not at all the same thing.
20:01 And it also supposedly supports matrix. So I don't know if that texts Keanu Reeves or
20:05 Yeah, exactly. Yeah.
20:06 I know Kung Fu. Okay. Sorry.
20:11 Yeah. No, this is really cool. If you've got to communicate with Gitter, if this, then that,
20:17 all those different things, you know, Cisco teams, Microsoft teams, all those, rather than
20:22 integrate with all of their APIs or Twilio or whatever, just like bring this in as like a
20:28 facade over all that. It's great.
20:29 Yeah. So this last thing I want to talk about is a new web framework. And I feel like the web
20:34 in Python is getting really interesting and also a little more hard to choose the right thing to do
20:42 because it used to be, oh, Django Flask. There's Pyramid also. I like Pyramid. And there's,
20:47 there's a few others. There was Cherry Pie that's not used that much anymore. So I guess I'll choose
20:51 between those three, right? Like that was kind of like the end of the thought, but now there's like
20:55 hundreds like of little things, right? There's black sheep that we talked about. There's mace
20:59 tonight and there's Jepronto and there's, well, there's WebSana as well. So WebSana is a new
21:05 framework. And I think it's super interesting because it, you know, it kind of brings some
21:10 more beginner friendliness or CMS friendliness to some of the micro framework story. So we've got
21:19 another way you might break up the web framework thinking process as well as I want an app that's
21:24 kind of like, I've got to work the way it works, but I can block in the, I can like slot in these
21:29 big blocks and have stuff I want like Django. So like I can have an admin back in where I just like
21:34 have like an Excel, like view of my database if I want that, for example. Right. But if you want to
21:41 not work the way Django works, well, too bad you work the way Django works. That's how you use Django.
21:45 Right. On the other hand, you could use Flask or Pyramid where it's kind of like, well, here's how
21:49 you process a request. Whatever else you do, that's on you. Right. It's up to you. So a lot of people
21:55 kind of like that more fine grained stuff like, well, I think I'll use SQLAlchemy here and I'm going to
22:00 use like this for managing passwords. And here's how I do my users and email and all that. Right. You get
22:04 to choose all those little bits, but then you got to choose all the bits and build with it and so on.
22:08 So this WebSona framework is built on Pyramid, SQLAlchemy, and obviously Python 3, but it adds a lot
22:17 of the features people might choose Django for, but in like a super modern and cool way. So I really,
22:23 really like it. Their description is WebSona is a full snack Python web framework for building web
22:28 services and back offices with admin interfaces and user signup processes. That's good. Yeah. So it says,
22:34 well, they say, well, when should you use it? Well, it's focused on internet facing sites when
22:39 you have a public or private signup process and an admin interface face. And the sweet spot includes
22:44 custom business portals, software as a service products, which are too specialized for off the
22:49 shelf solutions, read WordPress, Squarespace, like all these things you're like, oh, you could use that.
22:55 Well, for like 80%, you could use that. Then, then what, then where do you go? Right. So WebSona can
23:00 now be a place that you might go for that. Cool. This might be take off. Yeah, I think it really
23:04 good. And so they talk about, they're focused on like core business logic. So you can, you know,
23:10 they build all, have all the building blocks. Like you want to sign up with Google with your Gmail.
23:15 Yeah. You just like put that in there and it just, now you can sign up for the, your app with Gmail.
23:19 It's nice. You can get started real easy. Lots of docs. Yeah. It's just all about being productive.
23:24 So they have a whole bunch of infrastructure built up and just like kind of fill in the pieces.
23:28 It's a little more Django-esque, but then like raw pyramid is, but it's kind of nice that you have
23:34 this blended option. So I think it's looks really promising. They have a lot of cool things like
23:40 asynchronous task processing and other stuff like that, that really makes it feel like pretty modern
23:47 and cool. Yeah, definitely. Yep. It looks like it's tested using pytest also. Yeah. It's tested using
23:52 pytest. It's deployed using Ansible. Let's see what else. There's a couple of things like,
23:58 yeah, that is super cool. It automatically comes with the top OWASP top 10 security vulnerabilities
24:03 limit, like restricted. So like they figure out what are like the top 10 reasons websites have
24:08 security problems and they built into the infrastructure by default to block all those
24:13 like cross-site scripting and whatnot. They have asynchrony built in and they even comes,
24:17 it even has a IPython notebook shell. So instead of just having like a grid view of admin stuff,
24:24 I can type in, they're like, oh, well, if you need to do admin tasks, like log in and just fire up,
24:28 you know, Jupyter on the backend and just start like manage it like that way. Right. So that's like,
24:34 all right. So it's like a web shell to your, your server, keep that super locked down, but you know,
24:39 still pretty awesome. So there's a bunch of like really interesting ideas here that I think are
24:43 quite cool. The documentation is pretty thorough. It even includes like, okay, once you get this
24:48 stuff working, how do you deploy it somewhere? Yeah, exactly. This is quite new, but it also
24:53 looks really promising to me and I hope it, I hope it takes off because I feel like this is like a
24:57 really nice modern take on what a modern Python web app framework should look like. Yeah, cool.
25:02 All right. Well, that's it for our main topics. Brian, you got something you want to share with us
25:07 just quickly at the end. Yeah, I was going to mention, so I did, we mentioned in my move,
25:12 the move at work has been caused my schedule to be crazy. And I don't know when to interview people.
25:19 If you've been paying attention to testing code, the episodes have been kind of solo episodes lately
25:24 because I don't have to schedule myself. It's just whenever I can do it. And later on in July,
25:29 things should settle down. And so if I've bugged you to do an interview or you've asked me
25:34 and I haven't gotten back to you, get back to me again and we'll schedule that. So that should go
25:39 on. Yeah, right on. You're doing a great job with testing code. There's a lot of stuff been coming
25:42 out nice and steady and a lot of good shows there. All right. Thanks. How about you? Well,
25:47 I just released another course that I've been working on for a couple of months on and off,
25:51 and it's called Building Data-Driven Web Applications with Flask and SQLAlchemy,
25:56 speaking of micro frameworks. So I had a similar course on Pyramid and a lot of people said,
26:01 hey, Pyramid's awesome, but we really need to know Flask because that's what we use our
26:06 company or that's what I'm trying to understand for a job or whatever. So I'm like, all right,
26:10 well, let me go and build the Flask version of this course. So basically the idea is we spend about
26:15 10 hours recreating PyPI.org from the ground up with Flask and SQLAlchemy.
26:21 Oh, that's cool. Yeah. I'm going to have to check that out too.
26:24 Yeah, absolutely. So people can check that out. Links from the show notes are just training.talkpython.fm.
26:28 That's the latest course. And you know, no time to rest. As soon as we're done recording here,
26:33 it's time to start the next, continue on the next one I'm working on. So I'm really excited to have
26:37 this out. I think a lot of people will appreciate it. And it was really fun to write because you got
26:41 to explore like a lot of these ideas we were just kind of just talking about.
26:43 Yeah. I'll be hopefully working on a course here pretty soon too.
26:46 I'm very excited about that. Yeah. I'm not really sure we're ready to share what the topic is yet,
26:51 but it's going to be in high demand and very popular.
26:53 Yeah. I'm looking forward to it. Yeah. Complete secret. Nobody will know what it is until it shows
26:57 up. Yeah. Computer vision, IoT probably, but I'm not going to...
27:01 Yeah, maybe. Yeah, sure.
27:05 Or something else. Probably.
27:07 Yeah. So speaking of jokes and sarcasm, a SQL query goes into a bar, walks up to two tables and asks, can I join you?
27:15 I really like that.
27:19 Yeah, it's pretty bad, but...
27:21 That's good.
27:22 It's a good one.
27:22 Yeah. So I don't have a joke, but I saw this on Twitter and I tracked up.
27:29 I did watch this. Yes.
27:30 The reset procedure from GE light bulbs. It's so funny.
27:34 These are smart, in quotes, smart light bulbs.
27:36 Yeah.
27:37 And you may have like paired them to your device, but then you lost your phone or you gave the
27:43 light bulbs to your friend. You're like, well, how do I reset my light bulb? Right?
27:47 Yeah. Because you can't just like turn it off and turn it on because that's what light bulbs do. So
27:52 you have to do something else. And this procedure that they've got is hilarious. And it's like,
27:57 turn it off for five seconds, then on for eight seconds, then off for two seconds,
28:01 then on for eight seconds. And if you go through this like five times...
28:05 It goes on and on because like, what if somebody accidentally turns it off for five seconds,
28:09 on for two seconds, on for eight seconds, then off for eight seconds, but didn't mean to reset
28:13 their bulb. You got to do like three more rounds of that. It's insane. Yeah. So yeah. Yeah. You will
28:19 link to the video for that.
28:20 At the end, it's like, if that didn't work, maybe it's an old firmware version. Try this other,
28:26 even worse procedure.
28:29 Awesome user interface experience. So I love it. What do you do when like the only interface you
28:34 have is like power on power off? This apparently is it. Yeah. But the register like noted that you
28:39 could put a hole in it and people could poke it with a like clothespin or whatever. Oh, you mean like
28:45 my router and like all these other normal pieces of technology? Yeah. The reset button. Exactly.
28:51 Yeah. Maybe they don't want people poking metal things into bulbs because it's like too close to
28:57 poking it right to the socket. Because people are always poking metal into light sockets. Yeah.
29:03 Exactly. Exactly. All right. Well, yeah, people can go check this out and it's intended to be
29:10 serious, but it's actually kind of funny. Yep. All right. Well, thanks a lot, Michael.
29:13 You bet. Thanks for being here. See you. Bye.
29:15 Thank you for listening to Python Bytes. Follow the show on Twitter via at Python Bytes. That's
29:20 Python Bytes as in B-Y-T-E-S. And get the full show notes at pythonbytes.fm.
29:25 If you have a news item you want featured, just visit pythonbytes.fm and send it our way.
29:29 We're always on the lookout for sharing something cool. On behalf of myself and Brian Okken,
29:34 this is Michael Kennedy. Thank you for listening and sharing this podcast with your friends and