Transcript #102: Structure of a Flask Project
Return to episode page view on github00:00 Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
00:05 This is episode 102, recorded October 30th, 2018. I'm Michael Kennedy.
00:11 And I'm Brian Ockin.
00:12 Hey, Brian. How are you doing?
00:13 I'm doing great.
00:13 Are you frightened to be recording this on the day before Halloween? Or is it all okay?
00:17 Yeah, it's okay.
00:18 It might release on Halloween, but I think it's still going to be okay.
00:22 Yeah, that'd be neat.
00:23 Actually, it would be cool.
00:24 You know what is neat is that DigitalOcean is sponsoring the show like they are all of our shows for the rest of the year.
00:30 So check them out at pythonbytes.fm/DigitalOcean.
00:33 You'll get $100 credit if you're a new user there.
00:36 We'll come back, tell you more about that later, some cool stuff they got going on.
00:39 Brian, what's the first cool thing that you found?
00:41 Quanticon, or Quanticon, however you say that.
00:45 Didn't we cover like economics, somebody getting a Nobel Prize in economics.
00:50 Was that last episode?
00:51 That was last episode, yeah.
00:52 The guy who won the Nobel Prize, one of the guys who won the Nobel Prize in economics is all about Jupyter.
00:58 And I was very much an advocate for it.
01:00 Yeah, and we did a shout out then saying, hey, if anybody knows other economic stuff, we'd like to hear about it.
01:06 And somebody did.
01:07 Somebody let us know.
01:09 I really should have wrote their name down, but thank you.
01:12 Gave us a pointer to this site called Quanticon.
01:16 And it's quanticon.org.
01:18 It says open source code for economic modeling.
01:21 Quanticon is a num-focused, fiscally sponsored project dedicated to developing documentation for modern open source computational tools for economics, econometrics, econometrics?
01:33 I don't know.
01:33 And decision making.
01:35 Anyway, it's an educational resource for people wanting to do economics and stuff like that with Python and other programs.
01:43 I guess it does Julia also.
01:44 But it's got a bunch of lectures and a bunch of workshops and seminars that are taped and upcoming ones.
01:50 And then some Jupyter notebooks and some cheat sheets.
01:54 This is really cool what you found here.
01:55 Like, if I cared about economics, this would be a massively cool resource.
01:59 Yeah, you could just sit here all weekend and learn all sorts of stuff on this.
02:04 It's pretty great.
02:05 And yeah, it says fiscally responsible.
02:07 And looking at the bottom, it's even got Sloan Foundation support.
02:13 So that's pretty cool.
02:14 There's a whole bunch of stuff here.
02:16 Yeah, it's great.
02:17 It's all part of the NumFocus thing, which is really cool.
02:19 So, like, NumFocus is sort of the umbrella that sponsors things like NumPy and stuff.
02:24 And this is one of the areas of open source where, like, legitimate money is going to these projects.
02:30 Remember we covered a while back, like, multi-million, like, $3 million going to the SciPy, NumPy world?
02:38 That's really, really great.
02:40 It'd be cool to see that in some other areas of Python as well.
02:42 But it's great to see it here.
02:43 Yeah, it's neat.
02:44 And yeah, maybe I'll check it out also.
02:47 Yeah, it says there's a – it's basically a high-performance library.
02:52 It comes in the form of Jupyter Notebooks if you want it.
02:55 And it has a whole series of lectures.
02:57 And what's cool is, you know, you can pick the Python version, the Julia version, and you just, you know, get started watching the lectures.
03:03 It's pretty great.
03:04 And it has an area for if you want to contribute to it where they'd like some help.
03:09 And yeah, it's good.
03:10 Yeah, so that's a good find.
03:11 I like it.
03:12 I'm sure people will enjoy having it.
03:13 So I think we've talked about how you structure packages in Python a lot.
03:19 It's kind of one of our themes, right?
03:20 Yeah.
03:22 So this next one that I want to cover is about structuring Flask projects and also treating them as packages as well, which is kind of interesting.
03:30 So I think Flask is one of those things where it falls over itself to show you how simple it is.
03:38 And then it doesn't have much opinionated ways of sort of telling you now do this and that, right?
03:45 So you're kind of left to your own devices to figure out how to structure your Flask program.
03:49 So there's a cool article called Structure a Flask Project.
03:52 And it says, you know, look, it seems really easy to get started.
03:56 But when you're new, like as your app grows, you're going to find you start running the challenges with circular references and other things like that.
04:03 So he actually, the person who wrote this, has a couple of different structures.
04:09 And you can take the ones that feel best to you and run with it.
04:13 So one of it is to have like your project and then have a models folder sub package.
04:18 They call them routes.
04:20 I think it should probably be called views or controllers or something.
04:23 But routes, templates, services, things like that.
04:26 So like if you're going to have some code that sends mail for you, put that in a separate thing in a services folder.
04:32 Don't cram that all into just one giant file, which kind of Flask encourages.
04:36 So I really, really love it.
04:37 And I think it's nice.
04:39 What do you think?
04:39 I like it.
04:40 And actually, when you structure things in packages, then you have the dot notation in your code.
04:47 It separates the different parts of your system a little bit better.
04:50 Yeah, absolutely.
04:51 The one thing I would add here is some kind of concept of a view model, which is a class whose job it is to exchange the data between the HTML template and the view or controller method.
05:04 And just do all that validation instead of trying to cram that into your view.
05:09 Usually, the validation is more code than the operation you're trying to do with the data anyway.
05:13 So I'll throw that one in there.
05:16 And those are easier to test, right?
05:17 You test your validation separate.
05:18 Yeah.
05:19 So I threw this little question for you.
05:21 I see you already caught it quickly.
05:22 What's missing from this structure?
05:24 Tests.
05:25 Yeah.
05:25 There's no tests in this layout.
05:27 I mean, there is a dot, dot, dot somewhere.
05:28 So maybe in the dot, dot, dot there's some tests, but probably not.
05:32 Also, this is sort of a zoom in on the project.
05:34 And in a lot of projects that I've seen that are Flask applications, there's a test directory like at the top level.
05:41 So it might be parallel to this top level project directory.
05:45 Right, right, right.
05:46 Cool.
05:46 Yeah, there's another structure that they propose as an alternative called the app-based structure.
05:53 And it takes all the models, the view methods, the templates and everything, and puts it under the different categories.
05:59 So maybe you've got a blog subpart of your app.
06:02 You've got authentication.
06:02 You've got a store.
06:04 And it sort of replicates this structure underneath all of those.
06:08 I don't know how I feel about that.
06:09 I kind of like the first one better personally.
06:11 But it's more Django-like.
06:12 Yeah.
06:13 There's a couple of options here, which I thought was a nice tradeoff to show how different people were doing it.
06:18 And then also, I would like to just give a shout-out to Flask Blueprints, which is part of Flask.
06:23 This is nothing like extra.
06:24 It's just built in.
06:25 But it's kind of challenging the way Flask works to easily and clearly share or spread your view code across different files so it's not into one giant file.
06:38 And Flask Blueprints is really a great way to break one big file with all your view methods up into a whole bunch of little ones that are grouped by what they do.
06:47 They're easier to test because they're more focused.
06:49 Things like that.
06:49 And is this, the Blueprint, something you could use with either, any of these project structures?
06:55 Yeah, I think so.
06:56 Okay.
06:56 It just lets you take one big file.
06:58 Instead of trying to figure out how to, you know, in Flask, you create the app dynamically at runtime.
07:03 Then you say app.route.
07:05 That makes it tricky to share that thing without being circular or things like that.
07:10 So, this lets you do the reverse.
07:12 You create a Blueprint for each of your separate files.
07:15 And you say blueprint.route.
07:17 And then you just register the Blueprints with the app at the main startup.
07:20 And you're all good.
07:20 Oh, nice.
07:21 It's really a nice thing.
07:22 I haven't seen it used a lot, but it's great.
07:24 I learned it from the court guys.
07:26 All right.
07:26 So, anyway, I think that puts a nice structure on the Flask world.
07:31 And people should check that out if they're doing Flask.
07:32 What you got next for us?
07:33 I've got an article from Trey Hunter that's overusing Lambda expressions in Python.
07:40 And I actually kind of love Lambda expressions.
07:43 However, I've, so where I often use them is in like ID functions for test cases.
07:51 So, if I've got a test parameterization, you can rewrite the ID function to take all the parameter data and spit out an easier to read string.
08:01 And this is something that where Lambda expressions are often used.
08:07 However, I do have some of them that are kind of getting big and they're hard to read.
08:11 So, this is a good time to read Trey's article.
08:16 So, it starts out talking about some of the differences between Lambda expressions and just defined functions.
08:22 And some of the things I guess I didn't realize, I mean, it's obvious if you think about it, but I didn't really think about it,
08:28 is that one of the things is there's no doc string.
08:31 You can't have a doc string for a Lambda expression.
08:33 And the representation also is a little weird.
08:37 So, if you're stepping around or if you assign a Lambda expression to a variable, if it gets passed in somewhere,
08:43 the value of it is going to be something ugly that you can't, if you're debugging, it's going to look bad.
08:50 And you might have trouble figuring out where that came from.
08:53 Whereas, if you just define a function, it's easier to figure out.
08:57 So, basically, this is an argument on that it doesn't really save you a lot in a lot of places and perhaps even just use normal functions.
09:07 Then, the other thing is he talks about some misuses.
09:11 And some of them are, I've seen this before, is having a Lambda expression calling a single function with a single argument.
09:19 Well, that function that you're calling, you could just pass that instead of the Lambda expression that you're passing.
09:26 Right. Like, so, for example, if you have a sort function and you'd like to take the number and sort by the absolute value of it,
09:34 you could have a Lambda that takes the N and it says returns ABS of N, or you could just pass ABS.
09:40 Right? And this is basically the same thing.
09:42 You're just putting a layer of function calls in between them, make them slower.
09:46 And then, actually, I didn't know about this module before, so I'm glad I read this.
09:51 Defining little custom Lambda expressions for operators that happen to exist in the operator module.
09:57 There's an operator module that comes with Python and it has a whole bunch of things that you might have wanted to create a Lambda expression for.
10:08 Yeah, this is interesting. I didn't know about this either.
10:10 But you can say, like, operator.add, operator.truth, and so on.
10:15 Yeah, these are supposed to be high-performance, little efficient functions. Quite cool.
10:18 The last thing is, I've seen this before also, is used to be using Lambda expressions for map and filter, but just useless comprehensions instead, nor other kinds of comprehensions.
10:29 Yeah, that's a good one. Certainly, the comprehensions, set comprehension, dictionary comprehensions, all that kind of stuff, is better than a Lambda function, generally, right?
10:40 Yeah, it's more readable.
10:40 I think they might even be more efficient in terms of performance. I'm not 100% sure, but I think so.
10:44 But anyway, these are all good things.
10:48 Yeah, and I think there's a lot of good guidance here.
10:50 You know, for example, it says you can't have a doc string.
10:54 Well, if your Lambda expression requires a doc string, you're probably doing it wrong, right?
10:59 It's probably too complicated, right?
11:00 The value of the Lambda is, I'm going to take such ridiculously simple code instead of moving it way far somewhere else into a function that then I have to document so I know what the heck it does.
11:10 I could just put it right here, right?
11:12 Like, you know, ABS of a number type of thing.
11:15 I do think, I personally love Lambda expressions.
11:18 I feel like Trey's a little harsh on them.
11:20 I find that I more often see code that should be using the Lambda than is overusing Lambdas.
11:27 So, grain of salt there.
11:29 But I think there's a lot of good advice, too.
11:30 Yeah, I guess there's some times where you see a little tiny function that is only used once, and it's small, and maybe it could have just been a Lambda.
11:40 Right, it's probably badly named and not documented either, so.
11:45 Yeah, doc string.
11:47 What doc string?
11:47 Exactly, exactly.
11:49 So, anyway, yeah, people check it out.
11:51 It's a good article.
11:52 It's kind of a long one.
11:53 It really is in-depth.
11:54 We've got a couple of good, solid, long articles I covered this week.
11:58 Now, before we get on to another one that I think is really interesting because it introduces a lot of structure around features introduced two versions ago, two dot versions.
12:09 So, we'll get to that.
12:11 But before we do, I just want to tell everyone about DigitalOcean.
12:14 If you're not familiar with them, check them out at pythonbytes.fm/DigitalOcean.
12:17 They've got all sorts of cool stuff going on.
12:19 One of the things that I want to highlight this time that's cool, I've talked about a few times before, is the ability to bring your own custom images.
12:25 So, you can go to DigitalOcean and create a droplet.
12:27 That's what they call their virtual machines.
12:28 And say, I want Ubuntu 18 or, you know, CoreOS or whatever.
12:34 And you get those stock images.
12:36 They even have little app, pre-built apps like give me a MongoDB server or give me a ghost server, things like that.
12:42 But if you want exactly the machine that you'd like to run there and you want to create that locally, you can upload your own images.
12:48 All right.
12:49 And that's super easy.
12:50 Once you've registered them and uploaded them, you can just click start my own image and off it goes.
12:55 It's really cool.
12:56 So, check them out.
12:57 They're doing us well and I'm sure they'll do you well as well.
13:01 So, if you wrote some code, Brian, and it used the word async, all lowercase, and that was working just fine in Python 3.4.
13:12 And then Python 3.5 comes along and it introduces two new keywords, async and await.
13:19 Do you think there's going to be some problem with your 3.5 code?
13:22 Yeah, probably.
13:23 Well, there should be, right?
13:25 Like, there's a new keyword and you can't use the word class.
13:29 You can't use other core keywords, right?
13:33 You can't use def as like a variable name.
13:35 But it turns out, for whatever reason, I don't know really why they chose this, but async and await were valid, like parameter names and stuff in Python 3.5 and 3.6.
13:47 But they're not in Python 3.7.
13:49 Okay.
13:49 So, if you've got some sort of package and it uses the word async for a variable or a parameter or something like that, you're all of a sudden going to have your package or the one you're using no longer running.
14:04 That's big, right?
14:06 Yeah.
14:06 Yeah.
14:06 That's not good.
14:07 Yeah.
14:07 So, there's actually, I saw this article.
14:10 This is from Chris Medina called AsyncIO and Python 3.7.
14:14 And I thought, oh, okay, well, it's going to talk about this keyword thing, maybe a little bit, something else.
14:18 Oh, no.
14:19 This is like a series.
14:21 There are so many changes to asyncIO and async and await in Python 3.7.
14:26 Like, pages and pages of changes.
14:29 So, there's really quite a bit of new stuff.
14:32 And if you cared all about this, you should go check it out.
14:34 And you might not care at all about it, but you still maybe should check it out, at least for the fact that, like, parameters called async and parameters called await no longer work.
14:44 And if you have a library like that, it won't run on 3.7.
14:46 That's, yeah, it's definitely concerning.
14:48 Yeah.
14:50 So, I kind of feel like this maybe should have been the way it was done when 3.5, like, soon as those keywords appear in the language, they should be officially keywords.
14:58 But, anyway, here we are, three years later.
15:01 Now, async and await are enforced as keywords, the reserved words.
15:05 Okay.
15:06 So, we definitely want to heavily test your applications as you shift to 3.7.
15:12 Yeah.
15:12 Maybe using something like Docs or something like that, right?
15:14 Test across the different versions.
15:16 Yeah.
15:17 Oh, yeah.
15:17 That's a great idea.
15:18 So, there's a couple of other things I'll go through really quick here.
15:21 Like I said, check out the article.
15:22 There's tons there.
15:23 One of the challenges with async.io is it, like, simulates parallelism by slicing up all these different methods and running them, running the other ones while one of them is waiting.
15:36 But what's interesting is you can no longer have thread local variables because even though it feels like you're doing concurrency, it's actually all the same thread.
15:44 So, there's no mechanism to distinguish across threads, right?
15:48 That's sort of how Flask works, for example.
15:50 They've got the request as a thread local variable.
15:54 But it doesn't work in async.io.
15:57 So, there's this new concept called context variables that are like thread local variables but for coroutines.
16:03 So, they can have different values on the same thread, which is kind of crazy.
16:07 There's a bunch of stuff around how that works.
16:09 There's a new async.io.run function.
16:12 You still have to get a hold of the loop and call that.
16:14 Simpler task management, simpler event loop management.
16:18 You can call async.io.getrunningloop from within a library to see if you're already being run asynchronously or if you have to kick that stuff off.
16:27 A cool decorator to turn async functions into async context managers.
16:33 Remember, context managers are things you can put in a with statement, right?
16:37 Like with open file name as fin, right?
16:40 There's a new part of the language that will let you say async with.
16:45 So, it will like allow concurrency and you sort of do waiting type of work on those context manager enters.
16:53 Now, there's a really cool decorator you just add to your function and it automatically implements this async-able, async-enabled context manager, which is pretty awesome because that sounds complicated, doesn't it?
17:05 Yeah.
17:07 And then there's a bunch of performance improvements.
17:09 Async.io.get event loop is 15 times faster.
17:13 That's good.
17:14 Gathers 15%.
17:16 Sleep is twice as fast for not really sleeping.
17:18 Future is faster.
17:20 All sorts of good stuff.
17:21 There's tons and tons here.
17:22 So, go check out Chris's article.
17:23 I'm just blown away at how much new stuff Async.io got in 3.7, actually, when you see it all put together like that.
17:30 Yeah.
17:31 Wow.
17:31 That's great.
17:32 I like seeing it all together like that.
17:34 Yeah.
17:34 It's like, wow, there's still a lot of stuff happening here.
17:36 That's good.
17:37 I feel like we should say, you know, thanks to all the people that work on it.
17:41 That'd be awesome.
17:42 Yeah.
17:43 I think we should.
17:44 Like with an email or how do you propose this?
17:46 Well, there's a proposal in PIP.
17:49 So, this is a proposal from, oh, Bskin, Brian Skin.
17:56 Brian Skin.
17:57 Yep.
17:57 Yep.
17:58 And he sent us a heads up on this.
17:59 And he sent us a heads up on this that he submitted it just this morning.
18:04 And it's a proposal to add a sub-command thank to PIP.
18:08 So, you got pip install.
18:10 You got pip uninstall.
18:12 And so, another one would be like pip thank requests or pip thank seek welcoming, something like that?
18:17 Yeah.
18:18 Yeah.
18:18 This other proposal is to add that and then also to change install.
18:23 So, the install, if you install a bunch of stuff at the end after everything's installed, if there's the right metadata in the modules that you've installed,
18:33 add a little information that says, hey, if you'd like to thank the contributors, run pip thank on pip thank requests or pip thank something.
18:45 And the idea is to look in the metadata for the project for URLs, specific like thanks tag in the metadata or donate, possibly.
18:58 It's still kind of a little bit in flux as to what would be in there.
19:03 But there's already some information.
19:04 Apparently, it's all the info's there.
19:06 A lot of it is.
19:07 And there's a way to possibly just print that out and say, hey, if you want to say thanks, this is how you can do it.
19:12 I think it's a simple thing.
19:14 It's not going to be very intrusive.
19:15 And I think it's cool.
19:17 I think it's cool.
19:18 There's a lot of conversation happening on GitHub around this.
19:20 I like it.
19:21 Well, well done, Brian, for coming up with Brian Skin for coming up with this idea and, you know, actually putting it out there as a proposal.
19:27 Yeah.
19:28 And I don't know if it'll happen, but why not?
19:30 There's so much negativity in the world, a little bit of positivity.
19:33 It's a good thing.
19:34 Yeah, I agree.
19:35 Yeah, quite cool.
19:35 So I feel like I kind of snuck this last item from you because this one belongs in your realm, but I grabbed it.
19:43 So this one is an article, a booklet.
19:46 Should I call it a booklet?
19:47 I don't know.
19:48 I'll tell you why in a second.
19:49 On RealPython called Getting Started with Testing in Python by Anthony Shaw, friend of the show.
19:55 So this is not just a little quick tutorial on getting started testing.
20:00 This is like a little bit of a mini book type of thing.
20:04 I threw it into Instapaper and Pocket, and they both said it's a 33-minute read.
20:08 So that's a serious little write-up.
20:10 Yeah.
20:10 Yeah.
20:11 It's an interesting read.
20:13 I heard about this before it went through.
20:16 And one of the things that highlights is some of the process around RealPython articles.
20:23 They treat it like a magazine, and there's a review process and stuff.
20:27 So that's pretty cool.
20:28 Yeah.
20:28 Dan Bader and crew over there definitely creating some serious articles and things over at RealPython.
20:34 And so this is Anthony Shaw's.
20:36 I'm just going to touch on some of the topics covered in there because, like I said, 33 minutes.
20:40 It's like I can't really go into too much detail, but it covers things like automated versus manual testing.
20:45 It's really for people getting started, I think, but it's pretty interesting for everyone.
20:49 Unit tests versus integration tests.
20:52 It does a comparison of unit tests, nose and nose two, why there's actually two noses, and pytest and which one you should use.
21:00 Do you have an opinion on that, Brian?
21:01 Do you care about which one you use?
21:02 Yeah.
21:03 Use pytest.
21:04 It also talks about things like writing your first test, where to write it, how to structure tests, how to write assertions, the dangers, the side effects, testing in PyCharm and VS Code.
21:15 PyCharm is pretty straightforward.
21:16 VS Code has that command palette thing, which is cool, but you've got to figure out how to do it.
21:21 So that's kind of nice.
21:22 It also talks about testing web frameworks like Django and Flask, advanced testing scenarios, and even testing for security flaws in your app.
21:29 So there's a bunch of cool stuff here.
21:31 Like the testing security flaws, like that's new to me.
21:34 So yeah, I don't think it's really that much of a beginner article.
21:37 It just starts at the beginning.
21:38 Well, okay.
21:39 Yeah.
21:40 But it's a lot of these, I like that he touches on a lot of this stuff, but a lot of these things are touches on them.
21:48 There's not, like testing some of the web applications.
21:51 It's a kind of a pointer to, yes, you can do it in here.
21:54 Go read about it in other places.
21:56 Right.
21:56 But I do like it.
21:57 And that, like you said, the security flaws, that needs highlighted more.
22:01 And I think that's a great thing to add to people's tool belt.
22:05 Yeah.
22:05 Just to know that this is the way you can test for it, right?
22:08 There's even tools and whatnot.
22:09 So are you telling me that this could be a book?
22:14 Yeah, I think it could, but I think it would be a lot bigger book.
22:17 Yeah, somebody should write it.
22:18 I'm just kidding.
22:19 People should check out your book if they want more than 33 minutes worth.
22:22 I'd also like to add, so it does talk about PyCharm and VS Code, and it's a little bit that I don't see a lot of opinion.
22:29 But the testing story in PyCharm right now is a lot stronger.
22:33 And I'm not just saying that because I like PyCharm.
22:36 It's just true.
22:38 The VS Code team has something on there.
22:41 I think they're going to address some of the testing shortfalls in the upcoming years, and I hope they do.
22:47 But for right now, if you want to test within an IDE, do it in PyCharm.
22:52 Yeah, it's definitely nice in PyCharm.
22:53 Awesome.
22:54 All right, so those are our main items.
22:56 I have a few other things I want to throw in here because I don't feel like they really warrant a whole thing to be covered, but they're fun.
23:03 Anything you want to cover first, Brian?
23:05 I will just say that speaking of testing, I'm ramping up testing code episodes.
23:11 And doing them actually more frequent than one a week, not up to two a week, but I'm going to get a lot of episodes out.
23:18 And there's a couple recent ones on flaky tests.
23:23 Yeah, speaking of Anthony Shaw.
23:25 Yeah, Anthony Shaw is there talking to me with flaky tests.
23:31 And then I talked with the Automation Panda about feature tests.
23:36 Yeah, that's really cool.
23:37 Great to hear you doing more.
23:38 I've seen those coming out.
23:39 I have a few that I would like to throw out here, a few quick, simple ones.
23:43 First is just this fun project from Vicky Boykus.
23:47 See where it says hack your name in our notes, Brian?
23:49 Click that.
23:50 So the idea here is that you've got a startup.
23:53 You're trying to come up with a name.
23:56 And it seems like there's all these silly names are often talked about on Hacker News, which is from Y Combinator.
24:02 So why not just take the words from Hacker News, break them into syllables, and generate new words, which can be the name of your new cool startup.
24:12 And so you go to this URL, hack your name, urname.com.
24:17 And it has just one big button.
24:18 And it says pivot me, bro.
24:20 So I get guys to back.
24:24 Let's see.
24:25 If you click it a few times, you'll get some pretty good ones.
24:27 I got your chair.
24:28 Yeah.
24:29 I had Shy Fox the other day.
24:30 I'm pretty happy with Shy Fox.
24:32 So why is this interesting?
24:33 I mean, it's funny, obviously.
24:35 But it also is an open source project that is written in Python that does all the download from Hacker News and does all the work in words and stuff.
24:44 So it's kind of cool.
24:45 You can check it out.
24:46 I'll link to the GitHub repo as well.
24:47 Oh, so it's a good example project.
24:49 Yeah, exactly.
24:49 It's a pretty simple one, but it's pretty fun.
24:51 So if you are doing a startup, like seriously, click that thing like 20 times.
24:56 You'll probably find your name right there.
24:57 All right.
24:58 The other one, just some quick news, Python 371 and 367.
25:03 So modern Python, last two versions, got a new release.
25:07 And there's actually a decent amount of little bug fixes and stuff, at least in 371.
25:11 So check that out.
25:13 Yeah.
25:13 Neat.
25:14 Yeah.
25:14 Links there for that.
25:15 Not a lot to say more about that one.
25:17 And then the last one is we were talking with Tom Baker on Twitter about a project that's a command line interface app that he's converted over to Python.
25:29 And he used click.
25:30 And he wanted to propose a new acronym.
25:32 We've got TDD, right?
25:35 Test-driven development.
25:36 We've got BDD for behavior-driven development.
25:39 He wanted to propose CDD for click-driven development.
25:42 So you use the Python click package to mock up your suite of commands.
25:46 You put little print functions in there to show what's supposed to be happening.
25:49 And then you just start filling out the placeholders.
25:52 Take away the print functions and make it start working.
25:54 And so there you have CDD.
25:56 Sure.
25:58 Yeah.
25:59 Why not, right?
26:00 Yeah.
26:01 We always have a shortage of acronyms in the programming world.
26:05 So why not?
26:05 Yeah.
26:06 I think CDD may have been taken already, but I don't remember what it was for.
26:10 Yeah.
26:10 Well, I'm not sure how well it's going to actually take off, but there it is.
26:13 CLDD?
26:15 I don't know.
26:16 I don't know.
26:17 I do love click.
26:17 Click is cool.
26:18 Yeah, it's pretty cool.
26:19 All right.
26:19 Well, that's all of our news for this week.
26:22 Brian, thanks for being here and sharing with everyone.
26:24 Yeah, thank you.
26:25 Yep.
26:25 Bye.
26:25 Bye.
26:27 Thank you for listening to Python Bytes.
26:28 Follow the show on Twitter via at Python Bytes.
26:31 That's Python Bytes as in B-Y-T-E-S.
26:34 And get the full show notes at pythonbytes.fm.
26:37 If you have a news item you want featured, just visit pythonbytes.fm and send it our way.
26:42 We're always on the lookout for sharing something cool.
26:44 On behalf of myself and Brian Okken, this is Michael Kennedy.
26:48 Thank you for listening and sharing this podcast with your friends and colleagues.