Brought to you by Michael and Brian - take a Talk Python course or get Brian's pytest book


Transcript #264: We're just playing games with Jupyter at this point

Return to episode page view on github
Recorded on Wednesday, Dec 22, 2021.

00:00 Hey there, thanks for listening.

00:01 Before we jump into this episode, I just want to remind you that this episode is brought to you by us over at Talk Python Training, and Brian through his pytest book.

00:10 So if you want to get hands on and learn something with Python, be sure to consider our courses over at Talk Python Training.

00:17 Visit them via pythonbytes.fm/courses.

00:21 And if you're looking to do testing and get better with pytest, check out Brian's book at pythonbytes.fm/pytest.

00:29 the episode. Hello and welcome to Python Bytes where we deliver Python news and headlines directly to your earbuds. This is episode 264 recorded December 22nd, 2021. I'm Michael Kennedy.

00:41 And I'm Brian Ockett.

00:43 And I am Kim van Dijk.

00:44 Kim, welcome. You've been on Talk Python before, but not here.

00:47 Yeah, that's right. I've done a couple of TalkBytes with you, including the one where you bravely submitted yourself to questions from your audience. The other one, I taught them some small tools. So that was very good fun. I'm very much looking forward to this one as well.

00:58 - You know, both the episodes you were on were super popular.

01:02 One was about little automation tools and just cool stuff that people can pick up and use really easily there.

01:07 And that was great.

01:07 And the "Ask Me Anything" was surprisingly one of the more popular episodes as well.

01:11 So thank you for being part of that.

01:12 And you've been part of the audience for sure.

01:15 You've offered comments and feedback as we do the live show and the recording.

01:20 - Could be so, yeah, to be honest.

01:22 - Yeah, but now here you are on stage.

01:24 Thank you for being here.

01:25 Tell people a bit about yourself before we get started.

01:27 - Sure, I am a DevOps engineer at the moment and also move engineering based in South Africa, working with a home loan provider, a mortgage provider in the American sense.

01:38 I've been probably doing Python for close on 20 years.

01:42 So the fact that I've shaved means you can't see the gray beard, but I have been around for a while.

01:47 - Not the gray beard.

01:48 We're gonna come back for some good jokes at the end about this as well.

01:51 Not your beard, but just beards in general.

01:54 - Gray hair. - Gray hair, yeah.

01:55 Awesome, that sounds like really fun stuff.

01:58 So yeah, thanks for being here.

02:00 Now, before we actually get into the main content of the show, Brian, I wanna do something just a little bit meta.

02:06 So I went and pulled up or created a question air for people.

02:11 When we first created Python Bytes, we're like, all right, it's 20 minutes.

02:14 The time of this episode is gonna be 20 minutes.

02:16 So we're just gonna like knock it out, you and me real quick.

02:19 And I think it's grown a little bit.

02:20 We've done, we cover a little bit more detail.

02:22 We've added a joke.

02:24 We've added a few like little extra things.

02:26 We brought on guests like Kim.

02:28 And is that still in line with what people want when they signed up?

02:33 So I put together a questionnaire here that just asks three simple questions.

02:37 And I'd really appreciate if listeners could go to the show notes and just click on the link that says this three question Google form, or find it on our Twitter account or wherever, but should be in your podcast player show notes right near the top.

02:50 And they can just click that and fill it out Give us some quick feedback on the idea of having a guest, on the length of the show, and so on.

02:57 So anything you wanna add about that, Brian?

02:58 Just encourage people to give us feedback so we know.

03:01 - Yeah, I'd love to hear feedback because sometimes we feel a little guilty that we're running long, but I enjoy the a little bit more in-depth conversation.

03:09 We still don't go super deep, but I think it's a good...

03:12 Well, I'm flavoring the survey, though, so forget what I said.

03:18 No, I'd love to hear feedback on what people think.

03:20 - Yeah, absolutely.

03:22 Yeah, so people can give us feedback there.

03:23 We'd really appreciate it.

03:24 The way people seem to be feeling so far is they kind of like the link.

03:28 They definitely like the guest format.

03:31 So you're welcome here, Kim.

03:32 According to listeners, fantastic.

03:34 - Thank you.

03:35 - But yeah, I think people are generally liking, but still, let's just hear from everyone 'cause if a bunch of the people in the audience are like, "No, we really want no more than 20 minutes "and my going on about this "is actually making it still longer," then it'd be great to know, right?

03:50 So we'll go from there.

03:52 And with that, let's play a game.

03:54 - Jump into the first topic.

03:56 Yeah.

03:57 I wanna talk about Jupyter games and the idea around this is a iPython canvas or iPy canvas with Box2D.

04:06 I'll get a little bit more into it.

04:07 But the gist is making video games and small video games is one of the ways that a lot of us started programming.

04:17 I know that was the case for me.

04:20 And they were not difficult games, but it was difficult enough, these 2D engines.

04:26 And some of that's lacking, and I haven't seen that in Jupyter before.

04:30 And Jupyter is an excellent platform for a lot of things, especially teaching with people that don't have computers if they use an iPad or something like that.

04:40 So often they can still get access to Jupyter through hosted systems.

04:45 So this is a Jupyter, This article talks about writing 2D games and mostly it's a 2D physics engine around a library called Box2D, which is a C++ type engine, but it's something that you can access through Python.

05:04 - And that is neat.

05:05 - Yeah, the author--

05:06 - Those kinds of physics stuff, when people think of games, they think of, oh, here's what I gotta do to get the picture on the screen.

05:12 Oh, that's just a start.

05:14 Like you need physics, you need collisions, there's like so much stuff that also gets done.

05:18 So this is really cool.

05:20 - Yeah, things like physics and gravity and collision detection and like the examples on this page are great.

05:26 But the person that wrote it is Torsten Beer.

05:30 And he's one of the, I think he's got a library called PyB2D, which is one of two different Python accesses to this Box2D system, but it's pretty cool.

05:46 The one of the things I like about this article is it talk.

05:49 It has like lots of pretty examples, but physics engines are, even if they're built for games, they can also be used for things like an engine simulation or even like airflow simulations.

06:04 So there's a lot of cool uses for this too that are outside of games.

06:08 But the one of the incredible things is how small the programs can be.

06:13 So this article has a contained, like an attached notebook, hosted notebook that has things like angry shapes, which is like angry birds and a rocket game.

06:26 And there's a color mixing game, which I was just fascinated by.

06:30 There's like a bunch of colors drop into it.

06:32 It isn't listed on the article, but if you go to the example, it's kind of color mixing thing.

06:38 And it's only like 70 lines of code.

06:42 And with that, you can have some amazing physics examples.

06:47 And I'm pretty excited about this actually.

06:49 So I'd like to do those.

06:51 - You know, I think this makes a lot of sense in the notebook form because you're trying to visualize certain things.

06:57 And sometimes graphs are fine, but other times they just don't capture like flow and that kind of stuff.

07:04 And it seems like game animation would be great.

07:07 Kim, what do you think?

07:07 - I was also gonna say, if you can get something very impressive done in 70 lines of code as a learning tool, that's brilliant, because that's effectively a screen of code.

07:15 Otherwise, if you're looking at hundreds and hundreds of lines, if you're a seasoned developer, that's perfectly reasonable, but to a new person, that must look overwhelming.

07:24 If you can fit a single screen and say, here is it, this is everything you need to make this thing work, it's quite a powerful tool, and it looks like a lot of fun, actually.

07:33 - It does look fun.

07:34 - Yeah, and so there's some interesting, the article talks about some interesting hoops he had to jump through using IPyEvents, and I I pie widgets and canvas to be able to draw things and get events from people. But this is just some fun stuff. Here's like the I'm sure we're showing on the screen the thing like angry birds and to be honest, like the play ability of it isn't maybe like it's not on the level of what we don't play in an Xbox or something like that. Obviously you probably won't hook a controller to it. Yeah, but that you can do something like this so quickly is pretty amazing.

08:13 And also on the other hand, if you write, once you write it yourself, the playability actually doesn't matter that much. I mean, it's you're looking at interacting with the thing you wrote.

08:22 I think that. Yeah. Yeah. I love it. This is really cool. Nice find, Brian. All right. Let me tell you about some really interesting cyber security side of things. So I'm going to first tell you about this thing called a thinkst canary, but that's not actually what I want to talk about.

08:39 It's just to set the stage. Okay. So here's a challenge, something that always stresses me out is what if somebody was to break into your app, into your systems, into your cloud infrastructure or whatever, how would you know, right? Like what, what would be the indicator, right? If long, if they don't trash it, they don't, you know, lock it with a crypto lockers or anything like that, ransomware, then they could just cruise around there, right?

09:04 So this company thinks Canary created this.

09:09 I think you can put it in the cloud as like a hosted container type thing, or you can get like a little raspberry pi like things and put them physically on your network.

09:16 If you had a physical network and you could say you act like a SQL server, you act like an exchange server.

09:22 You if somebody tries to search the network and says, show me all the active directories, you be that maybe we're not even using active directory because we're not on Windows.

09:30 But if somebody breaks in, they may well start looking for those types of things.

09:34 And what they'll do is they'll trigger alarms if somebody tries to interact with them.

09:38 And normal things shouldn't because only if you're like trolling around looking for them, should it be discovered, right?

09:43 So that's what this is.

09:44 And with this whole log for shell stuff that's going on, it's just such a nightmare of like, well, we installed this app that did invoice management for us.

09:54 Did it have a log for shell vulnerability?

09:56 I don't know, maybe they said they fixed it.

09:58 And, but if somebody gets in, it's not just, we have to patch the log for shell or the log for J version, we've also got to then know what else has been run.

10:07 Cause they could have installed whatever.

10:08 Right.

10:08 Yeah.

10:09 So the thing I actually want to recommend to Python people is this thing called canary tokens.

10:15 So check this out.

10:16 This is fantastic.

10:17 So what you can do is you can get different things that will then trigger alarms, like emails or other sorts of stuff to you.

10:24 So I can come over here and I can say, I would like to get a URL.

10:27 And if anybody visits that URL, send me an email and say, you know, whatever message I put in here.

10:33 So I could come in and say, here's a URL and send me at Michael at talk by Thon or my email and say, this is hidden in the admin section.

10:43 Unused or something like that.

10:44 If somebody sends me an email, if I get that email, somebody's gone in and click that link in the admin section of my site.

10:50 And if I didn't, it gives you like IP address and all that sort of stuff.

10:54 of what comes back.

10:55 So if I didn't do it, or it looks like an unknown IP, that should be highly concerning, right?

11:01 So what else?

11:01 That URL is interesting.

11:03 I can get a DNS token.

11:04 Somebody requests, like, does a DNS lookup on rollouts.pythonbytes.fm.

11:12 I can get an alert to that.

11:13 That'd be pretty interesting.

11:15 A unique email address.

11:17 If somebody ever tries to contact that.

11:19 A Word document.

11:20 So you get like a Word document and put it in say like SharePoint or something dreadful like that.

11:24 And if it gets opened, you'll get an email that somebody got that.

11:28 Let's see, you've got VPN wire guards, file, you can create a custom EXE.

11:33 And if somebody runs your EXE or a SQL server instance, or you can even do like directly a log for shell link that will run.

11:42 So if you are trying to like figure out, just put stuff in there to let you know if somebody gets into a part they're not supposed to be in, like this is really cool.

11:49 There's no, it's free, it doesn't cost anything.

11:51 It doesn't require any setup, like put a Word document in a folder.

11:55 If it gets opened, let us know.

11:56 What do you think?

11:57 Well, I was going to say, I'm, I've been looking for ways to do exactly this kind of thing, because, you know, I'm totally unique in being concerned that log for shell has got impacts that I don't, that I can't see on our systems.

12:10 Yeah.

12:10 Just because your public facing systems happen not to have used log for shell things, doesn't mean that you're necessarily safe.

12:15 All it means is that, you know, if some other, by some other means, somebody's got into one of your internal systems wouldn't necessarily know that.

12:22 So, I'm very much interested in this.

12:25 I knew about canaries already, things happened to sponsor the local South African PyCon ZA conference.

12:32 but I can, every tokens are very funky, additional add onto that.

12:36 These, exactly.

12:37 I knew about the canaries as well.

12:38 I'm like, ah, but that doesn't really apply to the world that I live in.

12:40 I'm not like an enterprise, but like this, these make a lot of sense and they're free, which I think is cool.

12:45 Yeah.

12:46 Here's what it looks like if you get a notice.

12:50 It says, this is the email I got.

12:52 Your Canary token was triggered.

12:54 The channel was HTTP.

12:55 The token was that.

12:56 This is a test, the IP address of the person.

12:59 So this was one of those URLs.

13:00 Somebody interacts with this URL, let me know.

13:02 Here's their user agent.

13:04 Here's the message.

13:05 There's the IP and so on.

13:06 So you would just get a notice like that that says somebody clicked on something they shouldn't have had access to.

13:11 Yeah, so anyway, pretty neat.

13:12 Brian?

13:13 - Yeah, I'm not sure.

13:15 - Yeah, it's actually pretty cool.

13:17 Some of the things I didn't think you could, I wouldn't even expect, like can somebody cloning your website or didn't know that was a thing.

13:25 - I'm scared now to be honest.

13:28 (laughing)

13:29 I didn't realize that was something I should be worrying about.

13:32 - Get an alert when a MySQL dump is loaded.

13:35 Like, okay, like how does that happen?

13:37 I don't know, but that's pretty awesome that it's possible and also frightening.

13:40 - Yeah.

13:41 - Yeah, and Sam out in the audience says, Ironically, the log for shell might have its own vulnerabilities.

13:46 (laughs)

13:47 You know, that thing's been patched a couple of times.

13:50 It's going to be a big, big problem.

13:51 Anyway, Canary tokens, I think this is broadly useful for Python people.

13:55 You could put the URL stuff inside of your app.

13:58 You could put an email inside of locations.

14:01 There's lots of stuff that I like this, the database restore type things and so on.

14:05 This looks useful.

14:06 - Yeah, so I'm still a little lost.

14:09 You throw this, like, for instance, like you said, in the admin section that you shouldn't and you just know about it so you don't click it or something.

14:16 - Yeah. So imagine this, imagine you've got, in your admin section, you've got a, like a search for user button and then next to it, you could just put an export all data.

14:26 - Yeah.

14:27 - And then put one of these URLs at the end point.

14:30 And nobody who works, you just tell everyone, never click the export all data.

14:33 It doesn't do anything.

14:34 But if someone were to break in, what's the first thing they're going to want?

14:37 Oh, well, let's get the export all data.

14:38 Boom, they'll go click it and you'll know.

14:40 They're still in, it's bad, but at least they're not in and just have unlimited time to be in, you know?

14:46 - Yeah, you can put some other stuff too.

14:48 Like let's say you've got a Django website and you stick, you load a like a PHP admin page or something like that, just at the same URL in case somebody's trying to grab that or something.

14:59 - Yep, yeah, a lot of interesting little breadcrumbs you can leave in there.

15:04 Okay, Kim, that brings us to yours.

15:07 - Sure, the first topic I was going to talk about are actually two similar, but not quite the same pieces of software by pi auto GUI and pi win auto are both toolkits for automating GUIs, effectively, or automating GUIs for interacting programmatically with GUIs.

15:25 Nice.

15:25 I wouldn't want to be really hard, right?

15:27 Hey, before you go on, before you go on, could you give that like three control pluses just for sure.

15:31 Sorry.

15:31 I was just seeing now it's a little bit on the small side.

15:34 Thanks.

15:34 How's that?

15:35 A little more space to play with.

15:37 There you go.

15:37 Fair enough.

15:39 Well, let me just, while I remember, do it to this one as well.

15:41 They both happen to be Read the Docs documents.

15:44 So you're quite right, the programmatically controlling a GUI, it can be quite a pain, particularly for GUIs that aren't particularly easy to understand.

15:53 And the reason I bring tools like this up is that there's quite a lot of use cases.

15:58 I can think of two examples off the top of my own career, and I'm sure there's hundreds more, where this kind of thing is useful, and you might not know it's something you can do.

16:06 And the kind of examples I'm thinking of particularly in I'm sure much enterprise and in industrial software.

16:13 When you get a piece of equipment, you frequently get a GUI tool that accompanies it, but it is no API, right?

16:19 Well, no API server.

16:21 There's a tool you fire up and you set all the settings, but because the company that supplied you the piece of equipment, they don't write software.

16:27 It's not their thing.

16:28 You know, they, they, they either outsource the tool or the intern writes it.

16:31 And it has 50 check boxes and you know, in laid out in grid form, and you need set it up every single time you want to use that piece of software. There's no ability to remember what you set, there's nothing to do. And I've worked with a couple of those systems, and I see Brian, I think you probably have as well, where basically there's a piece of paper next to the computer the software is on with a screen print of what the settings should be. So that the person who has to come down and use it knows which of the 50 tick boxes to check, and then they have to check that the pattern effectively matches on screen, and then they hit run. And something like PyAutoGUI or PyWinauto are both useful so that you can effectively script the startup of that app. And you can say to you write a small piece of Python that fires this tool up, identifies all the checkboxes, ticks the ones you've programmed in, and then either leaves it for the human to push go or whatever it is the app does, or for that matter, pushes go itself and then closes the app and records that it did that. So that kind of use case is very powerful. And I think there are lots of cases, particularly in enterprise software, or internal software that, you know, somebody wrote for the company to do something very useful, but it's been around for 20 years, and the guy who wrote it is not around. Nobody wants to touch it because the source is terrifying. So nobody's going to sit down and change it. How do you even get that Visual Basic 6 or Visual Basic 5 and solve it? Well, exactly. How do you even compile it now? Exactly. So to be able to wrap it is a very powerful thing to be able to do. And the other kind of use case that's somewhat related, it also comes to mind, is I've spent a large amount of my career doing industrial automation, factory-based type work. And there, the faster you can go and the fewer steps you need a human to repeatedly do, the better for you in many ways. The human's time is best spent actually manipulating objects and checking things rather than opening pieces of software and clicking boxes and closing them again. So quite frequently, we've had cases on the production line where the vendor of the chip we're using has supplied this tool that does some security-related thing. And it's a GUI tool, and every single time you would have to open it up, you'd have to click the same two boxes, they'd have to say, yes, secure this chip, close it again, repeat, wait for another one to arrive at your workstation. And if you can automate it again with a wrapping tool, nobody need even be involved at all. Part of your production process is you wrap it, you fire up the tool, you click the two buttons programmatically, you hit go, and you close it again and repeat. And again, I personally have encountered situations where that's useful and I'd like to, I would imagine I'm far from alone in it, so I just thought I'd mention these things do exist. I suspect Lots of people do use them, but for people who don't know they're there, very useful things to be able to do.

19:01 Wrapping GUIs is a bit tedious up front because often these tools aren't very well written.

19:07 So you'll have checkbox 1, checkbox 4, checkbox 27, checkbox 295, and no obvious naming consistency with what they do or how they work.

19:15 But once you've figured it out, let the computer worry, let the script worry about what those checkboxes do.

19:20 I've seen the backside of that code where you're like looking at some event handler and it's like, If checkbox 24 checked, then do this like what in the world?

19:31 Like who exactly didn't want to name this 'cause they got a program against those names.

19:35 That's insane.

19:36 Well, they just do one at a time when you're working on exactly it.

19:39 Yeah, yeah.

19:40 So you're working on one feature and you go, oh, I need a checkbox.

19:42 Oh, the default is checkbox 24.

19:45 Then you look for the you do the callback handling and you just did it.

19:49 So, you know, it's 24.

19:51 So I don't want to bother changing it.

19:53 That's cool.

19:53 - Brian, does this automation have a place in your world?

19:56 - Yeah, so there's, like Kim said, there's places where tools that don't necessarily have a user interface.

20:04 The thing that this doesn't, I don't think these do like web stuff, the web automations, other tools.

20:10 - Well, I presume you could automate a browser, but I mean, by the time you're doing that, you might as well be using the tools designed for it.

20:17 - Yeah, Selenium or something.

20:18 What I really hope is anybody that has any sort of tool that they're writing in in on a web.

20:24 So web frameworks often get internal tools get written web frameworks and and then people forget to throw IDs in things.

20:32 So yes, the best way to automate a web stuff is to have an ID that you can grab onto.

20:36 But often they're just these in these nested div nightmares.

20:40 But anyway, yeah, there's a couple tools that we've used by Win Auto for that are pretty nice.

20:47 Yeah, very nice.

20:48 Yeah, it seems like if you're building a GUI app, you could test it with this, right?

20:52 sort of full-on integration tests from the outside.

20:55 And also I was talking to somebody and they were like, well, this app that I work on, it doesn't have like a concept of a back button.

21:01 So you drive into the menu, hit a thing, go, and then it'll take you back home.

21:05 It's like 10 steps, right?

21:07 I could definitely see a little toolbar thing, you press a couple of buttons, like get me to this scenario and I'll put the last thing in.

21:14 Get me to that scenario, like do the nine steps, I'll do the 10th.

21:17 >> Exactly.

21:18 >> Yeah.

21:19 >> In many ways, the way I've mainly encountered it has been that the first scenario laid out not so much actually automating the full running of the tool, but setting the tool up so that it is in the right state for what the company needs without having somebody have to either consult a document and risk getting it wrong or not know which of the settings they should have, because that piece of paper isn't with the computer anymore, all that kind of thing.

21:39 It shouldn't happen, but it does.

21:41 And it's much easier to have this kind of, to have the computer worry about what the settings should be.

21:45 Ideally the program should remember that, but you know, they don't, they don't.

21:48 You know, it's not much you can do to change that off of the fact.

21:50 It's like external intelligence for a bad app.

21:52 That's right.

21:54 - Well, there's also like API stuff that people forget about.

21:56 Like I've got a device that I need to automate connecting it to Windows and getting the device set up or something every time I plug one in.

22:08 And just automating that that works sometimes too.

22:12 So anyway. - Oh yeah.

22:13 - Absolutely.

22:14 All right, Brian, over to you.

22:16 - Thanks.

22:19 I saw this, Brett Cannon wrote an article called a reverse chronological, a reverse chronology of some Python features.

22:27 And I really love this article.

22:29 It's pretty simple.

22:31 One of the things I like about it is just 'cause we cover so much and we've been covering Python releases for quite a while.

22:37 I kind of forget which releases I got which feature in.

22:41 So a really brief, you know, rundown of some of the different features is nice.

22:47 Like last week we were talking and saying, well, if you're on 3.7, why would you wanna move forward?

22:54 And I can't remember which features and which.

22:57 So having a quick bullet list, like in 3.10 we got the match statement, of course, we've talked about that recently, but also better error messages.

23:06 And I'm gonna pause a little bit, Brett brings up in the introduction discussion that if you're kind of one of those people that think Python's kind of getting bloated and they're throwing too much stuff in it.

23:20 And I wish that we had the good old days where you could just think about all Python in your own head.

23:25 Well, you kind of throw everything out.

23:28 He recommends going down this list and picking the first feature that you don't think you could live without.

23:34 And everything before that led to that.

23:38 So you can't throw that stuff out either.

23:40 It all kind of goes together.

23:41 And one of the examples is the match statement or the, what are they, pattern matching.

23:48 That was sort of controversial, but the code to get that to work involved, or the process involved, even like making a new parser for Python, or using a new parser for Python.

24:03 And, but with that new parser, then things like better error messages are possible.

24:08 So if you like better error messages, which I do, That means 310 and everything below kind of has to stay.

24:15 But anyway, it's kind of funny.

24:19 Moving on, like I forgot what the dictionary support for like the or and or equal, that came in in 3.9.

24:27 So if somebody's thinking, well, why should I upgrade?

24:33 This is a good list to take a look at.

24:35 - Nice, all right, I did the little exercise.

24:37 I've decided 3.7.

24:38 - 3.7 for you.

24:39 So what was the thing in 3.7 that you can't live without?

24:42 >> So the dictionary preserving order stuff is really nice for like reading and writing files and making sure that they don't diff hard.

24:51 You know what I mean?

24:52 >> Yeah. >> If you try to, so they're in the order you put them there.

24:55 All the other stuff I'm not hating on it.

24:56 Like I like the walrus operator.

24:58 I like some of the other things.

24:59 I like the lowercase list bracket int rather than importing types.

25:03 All those are great.

25:04 I'm not knocking them.

25:05 I'm just saying like, where would I go?

25:07 It starts to hurt where?

25:09 It really starts to hurt for me at three, seven and below.

25:11 - Well, I was trying a Jupyter, like an interactive Jupyter system the other day, looking at some data science stuff and it was already set up.

25:19 And I tried to throw in this, the fstring value equal thing to be able to quickly debug an item and it didn't work.

25:28 - You said, what the heck?

25:29 - And it turned out it was using 3.7 and not 3.8.

25:33 And apparently I'm very used to that.

25:35 And I don't think I could live without it.

25:38 But and then a reminder also that 3.11, when it comes out in a year, it's just gonna have a lot of speed ups.

25:45 So--

25:46 - Yeah, if that comes up with a lot of the performance stuff then like that's my new number.

25:50 Kim, where are you?

25:51 - If you forced me to roll back, I would refuse to go further than 3.6 because I must have those f-strings.

25:57 - Yeah.

25:58 - 'Cause they're basically so much, they just make your code so much more attractive.

26:02 That said, while I don't necessarily use everything that comes in the new versions, I don't particularly have any problem with them being there.

26:09 I'm quite happy to just use the parts of Python I want.

26:11 What really happens to me is that I don't necessarily know I can do something until two versions later.

26:16 I probably only started doing that val= on 3.9, for example.

26:20 Mainly because that's probably the first time I needed it more than anything else.

26:24 I don't particularly rush forward and use the new features when they're available, but I'm glad they're there when I do ultimately want them.

26:30 Yeah, 3.6 is an interesting example you bring up because it's got fStrings.

26:34 It's got a whole bunch of other stuff too, but really, we can stop with f-strings.

26:39 - Pretty much. - Yeah.

26:41 And then the debugging stuff, Sam, the audience says, "Yes, F curly bracket name equals is indispensable for debugging." Oh, yeah, I'm with them. As I say, I hadn't used it when it first became available, but I would really not want to not have it available now.

26:54 - Yeah. - I'm a caveman print debugger.

26:58 - Yeah. - Kim, I like your take on it.

27:01 Like, it's not going to hurt me if I don't care about it.

27:03 I think one of the powers of Python is that you can be very successful with Python with a partial, quite partial understanding of what it even is.

27:12 You don't need to know what a generator is, what a yield is, like what an expression is, what a class is, maybe not even how to create a function.

27:19 Just write the code top to bottom and it'll probably still do something for you.

27:23 And so you can sort of bring these in when it makes sense.

27:27 Yeah, I would definitely still not teach match statements to beginners.

27:31 - It's unnecessary. - No.

27:32 - Exactly. - Yeah.

27:34 - Totally agree. - Whereas I would use if strings, for example, for a beginner because it's just so much more readable than the other stuff is.

27:39 But you're right, you don't have to magically, you don't have to use it all because it's there.

27:43 Yeah. I'm sure there's people out there who feel like, "I gotta use it, it's here." But no, I agree with you.

27:49 - Alright, so how about we talk-- - I don't think I've ever written a - walrus operator, for example. Sorry, you're saying. - Yeah.

27:53 I actually took down a Talk Python website, or the training website, one of them with the walrus operator.

27:59 because I put the walrus operator in a utility script that's not actually used by the site, but the site scans all the files trying to figure out where the handlers, the view methods are, and it killed it because I forgot that this is way back when it was still running 3.7.

28:15 So that was my first really, oh my gosh.

28:17 But yeah, now I use it.

28:18 It's good.

28:19 All right, so I want to talk about something that I've actually personally been working on lately.

28:23 This is a follow-up to a Talk Python episode I did where I interviewed Mike Bayer, came on and did a great job, talked about SQLAlchemy2 and so on.

28:33 And I mentioned that, just the way that Python's GC is set up is it's somewhat hostile to things like ORMs where they have to create a bunch of objects and return them to you in one batch.

28:48 And what do I mean by that?

28:49 Well, if I'm gonna do a query and it's gonna return a thousand records, the best case scenario is it has to create a thousand classes, SQLAlchemy models, and give them back, right?

29:00 If I'm asking for them as a list.

29:01 Well, the way the GC in Python works, not the reference counting, but the garbage collector is, after 700 allocations of container types, classes, dictionaries, lists, et cetera, that do not get cleaned up, 700 surviving over the cleanups over a period of time, that's gonna trigger a garbage collection.

29:19 And so I said, "Ah, you know, like, "is there something you could do?

29:22 "Is there something we could like, "kind of think about with ORMs?" This is not at all specific to SQLAlchemy.

29:27 This happens, I have an example here called Pythons GC and ORMs as a app and a little conversation on GitHub.

29:34 And I said, is there something we maybe can do or have you guys thought about it?

29:37 'Cause I don't really sure what the answer is.

29:39 And said, not so much sure, but here, check this out.

29:43 So I created this app.

29:44 It creates a thousand records in both a SQLite database and a MongoDB database.

29:49 We have like two really different examples.

29:51 and then you run a query that returned 20,000 records.

29:54 It's probably a lot.

29:55 - But it's not like it makes a hundred thousand records.

29:58 - Yeah, if I didn't say that, a hundred thousand records in the database and it gets 20,000 of them back.

30:03 Okay, it's probably a little extra, but for example, if you go to, you go over to the Talk Python Training site, over here we've got a site map and in this site map, there are many, many, holding down the page down arrow and you can barely see it.

30:20 We've got to get like 5,000 records, 6,000 records just to like list out the number of the pages that contain transcripts for the sitemap, right?

30:29 So it's not entirely unreasonable that you would get a bunch of records back and then do something like render a page with it, right?

30:35 Well, under this scenario, if you just run straight Python, that single query results in 1,859 garbage collection runs just to get one answer back.

30:48 Is that insane?

30:49 None of which is garbage.

30:50 Yeah, it's not garbage yet because it's just being realized from the database.

30:55 Right?

30:55 Like it, it hasn't even come into existence all the way yet.

30:58 And it's just like garbage, garbage, garbage, garbage, garbage.

31:01 And it takes a 900 milliseconds.

31:04 If you go and you tweak it in a way that I described here, which you may or may not want to do, but if you did, if you tweak the garbage collector, it will go from 1800 collections to 29, 64 times less, the speed of the program is 23% faster. Okay, but it also uses less memory.

31:24 Okay, less garbage collection.

31:27 Less, less garbage collection. And it's not just 1800 versus 29. Python has this 100 to 10 to one ratio of Gen 0, Gen 1 and Gen 2 collections. And Gen 0 collections are pretty cheap because it just touches new memory and looks at it.

31:44 Gen one looks at like stuff that's only been inspected once and Gen two inspects the entire memory space.

31:50 Well to see right.

31:51 So this one this one will also trigger.

31:54 Uh what is that?

31:56 Um 185.

31:58 Yeah 185 Gen one.

32:00 So 18 Gen twos right.

32:03 So it's not just oh there's fewer.

32:04 There's also like this this other 29 here.

32:07 This is zero Gen two collections very likely right.

32:09 So it's not just the number.

32:11 they're also like cheaper than doing that.

32:14 So this is pretty interesting.

32:16 What do you got to do?

32:18 You just say you run less frequently on allocations and then leave everything else alone.

32:23 Does it make a lot of sense for absolutely everything?

32:25 Probably not.

32:26 There's probably some scenario with lots of cycles that this is a problem.

32:29 But anyway, this is an interesting thing to sort of consider if you were doing some kind of API or a website or something that queries a lot of data, over 700 records basically.

32:41 you're going to absolutely encourage GC when you know it's not garbage, right?

32:47 So I don't know.

32:49 I thought this was interesting.

32:50 I'll put it out there for people to play with and get some feedback.

32:53 Should be fun to hear about it.

32:55 - I think this is very interesting.

32:57 And I'm going to, I plan on playing with the garbage collection myself.

33:02 So I'm glad you have this little sample app thing up to start playing with it.

33:07 One of the things that you can do that a lot of people don't mess with too much is not slowing down the frequency, but you can disable it and enable it.

33:17 And I'm not sure, I'd like to play with that a little bit more to see if you can kind of kick it off or something like that, because...

33:24 You can disable it and you can call GC collect if you need to.

33:28 So like it's there.

33:30 I'm not sure if it makes sense to do it, but the switches are there.

33:34 Yeah.

33:34 I mean, there's times where, I mean, you're not going to get real time with But you can get, there's times where you know that you're not doing anything else, so garbage collection's fine.

33:44 And there's times where you're doing an event and you really want to get done with this as fast as possible.

33:49 So it might make sense to turn off GC.

33:52 - Sure, and for people who are not super focused on this, turning off garbage collection or altering garbage collection only affects a very small portion of Python's memory because the primary way is reference counting.

34:05 So reference counting, things stop referring to it, that goes away only in the case where there are cycles, does GC even apply, right?

34:12 So that's actually, unless you've got really interesting algorithms that are super focused on that kind of stuff, you know, you probably don't even have cycles or very rarely do you.

34:20 - Yeah, interesting.

34:21 - It's not a one size fits all solution, but where it does fit, it's a pretty simple thing to do that really makes a heck of a difference.

34:28 - Yeah, it's quite interesting.

34:30 So my musings was, well, maybe someday Python will have an adaptive GC where it runs a certain number of times and says, "Oh, I ran, but I didn't actually find any garbage, "any cycles, so let me back off that threshold "by a factor or two." And then I didn't find any garbage again, so I'll back it off.

34:47 And then I'll go, "Look, I found a bunch, "so now we gotta start doing this more frequently." And I can see like an adaptive garbage collector turning these numbers, but until then, I just cranked it up.

34:57 Yeah.

34:58 - Interesting. - All right.

34:58 Yeah.

34:59 Kim, you wanna take us out of here for our main topics?

35:01 - Sure.

35:03 The other topic I was gonna talk about is a tool called Docker Slim, which basically--

35:08 - It already sounds good, I don't know what it does, but it's opposite of Docker Slim.

35:12 (laughing)

35:13 I want my Dockers to be slim, let's do it.

35:15 - It's effectively, as far as I can tell, well, not quite magic, but it certainly seems like it.

35:20 I use Docker quite extensively at work, and because I use a fair amount of it at work, I started using it for a lot of personal stuff as well, and websites I deploy in my own write, and little things running my own systems are all in Docker containers.

35:33 And unless you take a lot of care about it, your Docker images can end up quite large.

35:38 If you start with just a Python in an Ubuntu base, for example, you're probably looking at about a gig of Docker image before you get anything done.

35:46 Now, the way Docker works, unless you have just one of those things, if you've got more than one, you start to benefit from shared layers.

35:52 So you're not having a gig and another gig and another gig, et cetera, but still it all kind of adds up.

35:56 Docker Slim is a tool to basically look at your existing images, do some analysis, and give you back a much smaller and in many ways, much more secure image.

36:05 I have run this, I ran it earlier today just to kind of check that I wasn't misremembering from the last time I used it.

36:12 And I fed it an image I had, which was an incredibly simple, small little Flask API app I had written.

36:19 It had one job.

36:20 It basically, whenever you sent anything to an endpoint, it printed out what that was.

36:24 I forget exactly why I needed that.

36:26 I think I was having trouble figuring out some suppliers.

36:29 that it wasn't documented how some suppliers web book was going to work.

36:32 So basically I set this up and I said, talk to me and then looked at what it said.

36:35 Exactly.

36:36 Side note.

36:37 That's way better than trusting their outdated, crappy, inconsistent documentation.

36:42 It's just, all right, why don't you just call it?

36:44 We'll just print out the JSON and then we'll go from there.

36:47 Yep.

36:48 So yeah, as a side note, that was quite an easy thing to do, but that was, I just put that into a an Ubuntu-based container running, I forget exactly what, presumably I was using fast API.

37:00 So it would have been Python and Ubuntu and fast API and et cetera, and that was about a gig of image.

37:05 I fed that to Docker slim and I ended up with 48 megs and it still worked.

37:10 It did everything it was supposed to do.

37:11 Granted, I fed the simplest thing I had.

37:13 I mean, it had one end point and so forth.

37:15 - I have-- - There's a lot of dependencies.

37:18 There's Python, there's Flask, maybe there's even micro-WSGI or something running there, who knows, but yeah.

37:23 Well, exactly. What it has done is it's closed down all sorts of other angles of attack makes it sound a bit dramatic, but all sorts of ways that you could interface with the container that you don't necessarily need. It no longer has, for example, a bash is no longer available in it. You can't run it in interactive mode and talk to it, which is not necessarily a 100% positive thing. It makes debugging a bit harder, but they do have some solutions for how you can do that with side containers and talk to it in other ways and the like.

37:51 If you go through their documentation, effectively, they're doing all the security stuff and the app armoring stuff and all sorts of things that I know are important, but I don't know enough about to do right.

38:00 I don't trust myself to do those things correctly. I can basically follow someone's suggestions, but I have absolutely no way of knowing if the suggestions I'm following are valid.

38:07 I'm not immersed enough in this world to know what the best thing is to do.

38:10 So I'm much happier to have somebody come along and say, "We've written this tool. We get this stuff.

38:15 We'll do the best we can to make it more secure." Even if it isn't 100% secure, it's far better than I was going to achieve on my own.

38:22 And I haven't used it enough to get a 100% recommendation that this will fit every use case.

38:29 I'm sure every tool has things it does well, there's things it doesn't do well, there's some use cases where it's maybe not so suited.

38:34 But just from a little bit of experimentation with it, it looks like something I'm going to be inserting into my toolchain where I can, because the smaller the images are, the better, really.

38:43 Especially if we're all working from home, putting these things down from servers that aren't actually in the building that you're in anymore.

38:50 And if you're doing a continuous deployment, which means pushing those actual images, then you want to move that quicker. Yeah, cool. Very nice.

38:59 Yeah, one of the things that Docker's used for that I think a lot of web people don't think about is cross compiling. That's one of the places where Docker shows up.

39:09 And it's one of the places I use it is to compile on a machine that I don't have access to.

39:14 so I can have a Docker image like I can have a Windows machine with Linux Docker image or something. And I can do compiling in there. So slimming that down speeds up my compiles, or I conceptually would. So I think this is something that definitely to try if you're using using that. Exactly. You've reminded me of in a similar vein, Docker is the basis of our continuous integration systems. And the ultimate end result is built inside a Docker container with with all the bits we need.

39:44 That can take quite a while because it can be quite large.

39:47 You can slim that down as well.

39:48 You know, the faster you see I is the better for you really.

39:50 - Yeah, always.

39:52 - Yeah, absolutely.

39:52 All right, well, Brian, I think that might be it.

39:55 Time for some extras.

39:56 Oh, I do want to do a quick follow up.

39:57 I thought these were extras, but they're actually not.

39:59 They're things that I do want to point out really quick.

40:04 I actually gave a talk on this whole memory thing.

40:05 If that GC conversation sounds interesting to you over at the Python web conferences here.

40:10 So people can check that out and also have a talk Python class that like dives into a whole bunch of this stuff.

40:15 - Nice.

40:16 - I meant to include that in the before thing.

40:18 Now we're at the extras.

40:19 Let's talk about that.

40:20 What do you got?

40:21 - The only thing, one of the things I wanna shout out is to everybody that supported the pytest book.

40:28 So at Pragmatic, if you just go to the main page, there is a best sellers link that has had Python testing with pytest on it for many weeks now in the top six.

40:44 And I just wanted to thank everybody that supported the book and helped the success of this.

40:50 Also the feedback that I got of the technical reviewers and plus many other people going through and submitting a RADA is gonna make this a really solid book and I'm really just happy to be part of a community to put this together, so thanks.

41:03 - Yeah, congratulations, that's awesome.

41:05 Kim, you got anything extra you wanna throw out there?

41:07 - A couple of small things I was hoping to mention we had at the time. I see we've actually got Mess with DNS up on screen. This is a good place to start. I just wanted to mention this little website, messwithdns.net, which Julia Evans, who on Twitter is Bork, and produces a variety of excellent webzines and so forth.

41:26 I think you've actually discussed her Git learning webzines before.

41:30 Oh, blank Git.

41:32 That's the one, yeah. And I think there's an HR-friendly one whose name I can't remember because we all remember the memorable one.

41:39 Oh, something like that.

41:41 Something like that, yeah.

41:42 She released messwithdns.net recently as effectively a way to play with DNS without breaking your actual website, which isn't something I'd ever thought to look for, but now that it's around, it's actually a brilliant idea.

41:55 There are some hard-to-understand things based into DNS.

41:59 What is a record and a CNAME?

42:01 And if your TTL is a three-digit number versus a five-digit number, what's the difference? Or for that matter, what does TTL mean?

42:07 And it's not necessarily an explainer for all these things, but it is a way to make these settings and see what they do without actually breaking a real website.

42:15 So effectively, she's spun up a sub domain with a assigned name.

42:20 This one I happen to be on is goblin61messwithdns.com.

42:23 The worst you can do is break goblin61.messwithdns.com and that will then just go away when the next person comes along.

42:28 So it's actually a really smart, really clever idea.

42:31 And typical to Julia's thoroughness, she's got a series of experimental suggestions on the side.

42:36 Here are some things you can try, here are some tutorials, how about making a CNAME?

42:39 Or here are some weird things you can try.

42:41 What happens if you've got a very long TTL?

42:43 Or you convince three different DNS servers that your subdomain has three different IPs?

42:47 Why you would do that is a mystery to me.

42:49 But you know, what would happen if you did is something you can explore with this site without actually breaking your real website.

42:55 And this seems like a very useful learning tool.

42:57 Yeah, absolutely.

42:58 Cool, I love it. That's fantastic.

42:59 There were two other small things I just wanted to mention.

43:03 one just because I use it all the time and I don't know how common knowledge it is. It is possible in Python, and I don't have a web page to open for this, to run a small little web server. If you do python-m-http.server, I've gone blank on which it is now, to be honest.

43:21 >> Dot server. >> Dot server.

43:23 >> Yeah, yeah. I'm reading your notes. I don't actually...

43:26 >> I'm just going back to the notes to have a look myself.

43:28 >> That effectively fires up a web server in the directory you open it in and serves up the files that are there or the sub directories that are in there.

43:36 And there's no security, there's no attractiveness, there's no styling, there's anything of the sort.

43:39 You wouldn't serve this to the public.

43:41 But if you wanted to get a file off the machine, and I do this quite a lot to get files onto my phone, for example, firing up a web server there and then and just pointing by that script or your own, you know, just to send your browser to your, the local host with the port you gave it and just download the files from there. It's a useful thing to be able to do.

43:59 Yeah, that's a cool trick.

44:00 It's like directory browsing, basically, yeah.

44:03 Exactly. And then the final little extra I just wanted to talk about, and this is a little more tongue-in-cheek somewhat, in both last week's Python Bytes and on recent Talk Python episodes, you have been speaking a little bit about different ways of doing Git.

44:16 You were discussing doing all your Git on the CLI, and I think one of your audience members at the last Python Bytes suggested the way they do Git is just mash all the buttons they can find in VS Code.

44:27 There is, I just want to put out there, there is a middle ground that you could be looking at.

44:32 There's a tool called Magit, M-A-G-I-T, which is effectively, if you're an Emacs user and you don't know Magit, you should change that immediately.

44:41 Magit is effectively a brilliant way of doing, to me, a brilliant, indispensable way of doing Git inside Emacs.

44:48 Granted, it doesn't mean you need to learn Emacs, but in just a couple of short years after that, you should be an expert at, you should find Magit indispensable.

44:56 It'll take you a couple of years to learn Emacs. I'm not disputing that.

44:58 But once you've got the Emacs down, Magic really is an excellent option to look at doing your Git with.

45:04 So if you're tired of doing it on the CLI, just set some years aside, learn yourself some Emacs, turn to Magic, and then wonder how you ever did anything else.

45:12 Set some years aside.

45:13 I don't think that's fair to Emacs, but just a little bit of it.

45:20 Too much.

45:21 I'll concede Emacs is a much longer learning curve than VI, but it's not gears, Scott.

45:26 And I say this, I mean, yeah.

45:29 Yeah, and Mario and the audience is taking credit for the VS Code button matching.

45:33 Right.

45:35 Right on. Cool, yeah, that's a great recommendation.

45:37 - Yeah. - All right, is that it for your extras?

45:40 I should just point out in terms of it being unfair to Emacs, I've been using it for more than 20 years, and I find it almost impossible to use anything else, but I'm sure it didn't take me years to learn, it's just been a long time.

45:49 That's right.

45:51 - Cool, all right, I got a few throughout there, actually just one.

45:55 I made a comment, I think on the last show, Brian, about using emojis in my code.

46:01 - Yeah.

46:02 - So I wanted to bring that example up.

46:03 So here's like a little CMS thing that I got going on.

46:05 And if you return a collection, like themes are represented by these little tags in the CMS.

46:10 And if you return a collection, the comment has a list of emojis.

46:14 And if you return, if they're just like processing a single thing, you get that emoji.

46:19 or pages you get a list of page emojis and so on.

46:23 Anyway, that's what I had in mind when I talked about that.

46:25 - That's pretty cool to use.

46:26 - Yeah, you can sort of just scan through, oh look, there's a list of these, this must be to a bunch of stuff, or I don't know, I could probably come up with something like a modifying, I'm gonna change a theme versus read a theme or something like that.

46:36 - Yeah.

46:37 - Anyway, well, that brings us to the laughs and I hope you all enjoy schadenfreude because it's bad this time.

46:44 (both laughing)

46:46 Thank you, Log4j.

46:47 - Okay, so let's see.

46:50 First of all, this is not shot in 4K.

46:51 This is just something about the cookies.

46:53 My daughter yesterday gave me this candle.

46:55 It has a website.

46:56 "We use cookies to improve our performance." And then me, same, I just eat cookies.

47:01 I thought that was really just funny for like a tech candle that she found.

47:05 - It should be a tan of cookies, though.

47:07 - I know it should.

47:08 It absolutely should.

47:09 At least it should smell like cookies.

47:12 It says scented.

47:12 I have no idea what scent it is, but it better smell like cookies.

47:15 - Does it smell like websites?

47:16 Maybe.

47:17 - Baby.

47:18 - And then I just want to point out more practically, I have this add-on you can get for all the browsers.

47:21 I don't care about cookies.

47:22 And if it sees one of those cookie warnings, it'll try to click it and just accept it.

47:26 - Oh, this is indispensable.

47:28 That's brilliant.

47:29 - Absolutely.

47:30 And then Brian Skin starts us off with the log4j stuff.

47:35 So if you remember, if you're aware, log4j, the problem with log4j is if you try to log a piece of text, even as an argument, if that text has J and D I colon L A D P L A L D A P colon slash slash to some Java library, instead of logging it, it will execute that Java stuff.

47:57 Even if it's remotely on the internet, then it'll output the result of that.

48:01 Like you're hacked or whatever, right?

48:03 So we've all heard a little Bobby tables, right?

48:06 Here's the modern day one.

48:08 Hi, this is your son's school.

48:10 We're having computer trouble.

48:12 Oh dear, did he break something?

48:14 Well, in a way, did you really name your son, Curly, you know, dollar curly J and D I colon L D A P colon slash slash evalcorp, parenthesis, parenthesis Bobby.

48:25 Oh yes. Little Bobby Jindy we call him.

48:27 We've got our servers crypto locked.

48:32 I hope you're happy.

48:33 I hope you've learned to synthesize your log for J inputs.

48:36 Isn't that fantastic?

48:39 - Yeah. I have a feeling this is going to go on.

48:43 It'll be the next, it isn't log for J.

48:45 It'll be something else next year.

48:47 It's yeah.

48:47 And well, I mean, it's been there for 10 years.

48:50 Exactly.

48:51 It's not, it's not a new thing.

48:52 Unfortunately, it's not even a vulnerability.

48:54 It's just.

48:54 Exactly.

48:55 You can actually do that on purpose.

48:57 And Brian helpfully suggests this actually came from log for J memes.com.

49:05 So we got to go there for a second.

49:06 And of course that exists.

49:07 Of course.

49:08 And Oh my gosh, like, look at this picture.

49:11 So Brian, will you describe this person for me on the screen?

49:13 There's a person in a saying next to him.

49:15 Old white guy.

49:16 to me, he looks like a perfect sort of grandpa sort of character, right?

49:21 Getting up there probably 70.

49:23 You know, nothing wrong with a guy, but it says upgrading log for J three times.

49:27 It wasn't that stressful.

49:28 Dave, 28 years old.

49:30 What else have we got in here?

49:34 We've got, I wish that was outrageously funny and not just kind of truish.

49:37 But yeah, I know.

49:38 So here's like a 1940s looking picture, like a dad and some kids hanging around.

49:42 Daddy, what did you do during the Great War?

49:45 The Log for Shell incident.

49:48 Let's see.

49:49 There's a few of you going here, like there's the how many days since such and such accident?

49:55 Zero days without log for JCVE.

49:57 And there's like Homer running around with like a nuclear glowing stick.

50:01 You can just spend, you can spend some time in this place.

50:04 It's probably unhealthy.

50:06 There's like a grim reaper, just going through taking out technology.

50:10 And it has a log for J on the grim reaper, you know.

50:13 Let me see if I can find one more that there's, there's some really good ones.

50:18 This one is probably good.

50:19 There's a picture of a guy in a tuxedo says, vendor not vulnerable to log for J, but there's a mirror and you see the back of him.

50:26 His clothes are just all God.

50:27 It says he uses EOL.

50:29 - Yeah.

50:30 - Yeah, that one's pretty gross.

50:31 I want to get that on the screen.

50:33 But yeah, these are just fantastic here.

50:37 So anyway, people can check out the memes.

50:39 Thanks, Brian, for sending that in.

50:40 Brian Skin.

50:41 - Yeah, I have to say, I am reminded, I did see one the other day, I don't know that I could put it up now, but it's effectively that, I've just seen it in various other means, a chap receiving an award from probably his manager, saying, you know, me receiving an award from the manager for not being vulnerable to the log4j vulnerabilities.

50:56 And inside thinking, that's mainly because I chose not to log in, I completely forgot to log anything.

51:00 (both laughing)

51:01 - Exactly.

51:02 - Yeah, here's a tweet.

51:04 Today, Java runs on billions of devices.

51:07 It's not a statement of pride, but a statement of pure terror.

51:10 (both laughing)

51:13 All right, well, I don't wanna hit on Java too hard, but the Log4J, I just cannot believe somebody thought it's a fantastic idea to execute remote code that you cannot escape.

51:24 - From a logging system.

51:26 - Yeah, in a logging system.

51:27 It's just, what did you think you would get?

51:29 So, here we are.

51:32 with log4jmemes.com if you want to scroll through it.

51:35 - Let's back up and say somebody thought writing an application in Java was a good idea.

51:40 No, sorry.

51:41 (both laughing)

51:44 I'll get hate mail for that one.

51:46 - Yeah, don't mail Brian.

51:49 Don't email Brian, he knows.

51:50 All right, well, so Brian, that's it for the year, isn't it?

51:53 I mean, this is the last episode.

51:55 We're gonna take a little bit of time off.

51:57 - Yeah, some well-deserved time off.

52:00 - Yeah, absolutely.

52:00 So thank you everyone for listening.

52:03 Kim, thanks for coming to join us this time.

52:05 Brian, as always, thank you.

52:07 - And we'll see everybody next year.

52:09 - Yeah, see you next year.

52:10 - Thank you for having me, guys.

52:11 That was brilliant.

52:12 - Yeah, you're welcome.

52:13 And if you're out there and you still haven't filled out that form and given us our feedback, let us know.

52:17 The Google Form link is at the top of the show notes.

52:20 All right, bye.

52:21 - Cheers.

52:23 - Thanks for listening to Python Bytes.

52:24 Follow the show on Twitter via @PythonBytes.

52:27 That's Python bytes as in B y t s. Get the full show notes over at Python bytes.fm. If you have a news item we should cover, just visit Python bytes.fm and click Submit in the navbar. We're always on the lookout for sharing something cool. If you want to join us for the live recording, just visit the website and click live stream to get notified of when our next episode goes live. That's usually happening at noon Pacific on Wednesdays over at YouTube.

52:54 On behalf of myself and Brian Aukin, this is Michael Kennedy.

52:58 Thank you for listening and sharing this podcast with your friends and colleagues.

Back to show page