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


Transcript #102: Structure of a Flask Project

Return to episode page view on github
Recorded on Tuesday, Oct 30, 2018.

00:00 Hello and welcome to Python Bytes where we deliver Python news and headlines directly to your earbuds. This is episode 102 recorded October 30th 2018. I'm Michael Kennedy, and I'm Brian Okken. Hey Brian, how you doing?

00:13 I'm doing great. Are you uh frightened to be recording this on the day before Halloween? Or is it all okay?

00:17 Yeah It might release on Halloween, but I think it's still gonna be okay. Yeah, that'd be neat actually would be cool You know, what is neat is that Digital Ocean is sponsoring the show like they are all of our shows for the rest of the year, so check them out at pythonbytes.fm/digitalocean.

00:33 You'll get $100 credit if you're a new user there.

00:35 We'll come back and tell you more about that later, some cool stuff they've got going on.

00:39 Brian, what's the first cool thing that you found?

00:41 Quanticon, or Quant-e-con, however you say that.

00:45 Didn't we cover, like, economics?

00:47 Somebody getting a Nobel Prize in economics.

00:49 Was that last episode?

00:51 That was last episode, yeah.

00:53 The guy who won the Nobel Prize, one of the guys who won the Nobel Prize in economics, about Jupyter as 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, somebody let us know, I really should have wrote their name down, but thank you, gave us a pointer to this site called Quanticon, and it's quanticon.org.

01:19 It says, "Open source code for economic modeling.

01:22 "Quanticon is a NUM-focused, fiscally-sponsored project dedicated to developing documentation for modern open source computational tools for economics, econometrics, econometrics? I don't know. And decision making. Anyway, it's an educational resource for people wanting to do economics and stuff like that with Python and other programs. I guess it does Julia also. But it's got a bunch of lectures and a bunch of workshops and seminars that are taped and upcoming ones. And then some Jupyter notebooks and some cheat sheets.

01:54 This is really cool what you found here.

01:56 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 Yeah, it says fiscally responsible.

02:09 Looking at the bottom, it's even got Sloan Foundation support.

02:14 That's pretty cool.

02:15 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:20 This is sort of the umbrella that sponsors things like NumPy and stuff.

02:25 And this is one of the areas of open source where like legitimate money is going to these projects.

02:31 Remember we covered a while back like multi-million, like $3 million going to the SciPy, NumPy world.

02:39 That's really, really great.

02:40 It'd be cool to see that in some other areas of Python as well, but it's great to see it here.

02:45 Yeah, it's neat.

02:46 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 Comes in the form of Jupyter Notebooks if you want it, and it has a whole series of lectures.

02:57 And what's cool is you can pick the Python version, the Julia version, and you just 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, 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:14 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:22 Yeah.

03:23 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:31 So I think Flask is one of those things where it's, it falls over itself to show you how simple it is.

03:38 then it doesn't have much opinionated ways of sort of telling you now do this and that right so you're kind of left to your own devices to figure out how to structure your flask program so there's a cool article called structure a flask project and it says you know look it seems really easy to get started but when you're new like as your app grows you're gonna find you start running the challenges with circular references and other things like that so he actually the person who wrote this has a couple of different structures 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 are they call them routes I think it's probably called the views or controllers or something but routes templates services, things like that.

04:27 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, don't cram that all into just one giant file which kind of flask encourages. So I really, really love it. And I think it's nice. What do you think?

04:39 I do. I like it. And actually, when you structure things in packages, then you have the dot notation to separate in your code.

04:47 It separates the different parts of your system a little bit better.

04:51 Yeah, absolutely. 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 the viewer controller method 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:19 Yeah, so I threw this little question for you.

05:21 I see you already caught it quickly.

05:23 What's missing from this structure?

05:24 - Tests.

05:25 - Yeah, there's no tests in this layout.

05:27 I mean, there is a dot, dot, dot somewhere.

05:29 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:42 So it might be parallel to this top level project.

05:45 - Right, right, right, cool.

05:47 Yeah, there's another structure that they propose as an alternative called the app-based structure.

05:54 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 sub part of your app, you've got authentication, you've got a store, 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, but it's more Django-like.

06:13 There's a couple of options here, which I thought was a nice trade off 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, 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 like one big file with all your view methods up into a whole bunch of little ones that are grouped by what they do, they're easier to test 'cause they're more focused, things like that.

06:49 - And is this, the Blueprints something you could use with either any of these project structures?

06:55 - Yeah, I think so.

06:56 - Okay.

06:57 - 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 run time, 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 and you say blueprint.route, and then you just register the blueprints with the app at the main startup and you're all good.

07:21 - Oh, nice.

07:22 - It's a really 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, so anyway, I think that puts a nice structure on the Flask world, and people should check that out if they're doing Flask.

07:33 What you got next for us?

07:34 - 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, 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:02 And this is something where lambda expressions are often used, however, I do have some of them that are kind of getting big and they're hard to read.

08:12 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:23 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, is that one of the things is there's no docstring.

08:31 You can't have a docstring 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, or if it gets passed in somewhere, the value of it is going to be something ugly that if you're debugging, it's going to look bad.

08:51 And you might have trouble figuring out where that came from.

08:54 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:08 Then the other thing is he talks about some misuses 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.

09:27 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, you could have a lambda that takes the n and it says returns a b a b s of n, or you could just pass a b s.

09:41 Right?

09:42 And this is basically the same thing.

09:43 You just put 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:52 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, but you can say like operator.add, operator.truth, and so on. 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 use list 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:39 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:47 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 docstring.

10:53 Well, if your lambda expression requires a docstring, you're probably doing it wrong, right?

10:58 It's probably too complicated.

10:59 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:09 I could just put it right here, right?

11:11 Like, you know, ABS of a number type of thing.

11:14 I do think, I personally love lambda expressions.

11:18 I feel like Trey's a little harsh on them.

11:21 I find that I more often see code that should be using a lambda, than that is overusing lambdas.

11:27 So, grain of salt there, but I think there's a lot of good advice too.

11:30 Yeah, I guess there's sometimes 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:43 Yeah, docstring, what docstring?

11:48 Exactly, exactly.

11:50 So anyway, yeah, people check it out.

11:52 It's a good article. It's kind of a long one. It really is in-depth.

11:54 We've got a couple of good solid long articles 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, 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 pythonbysetfm/digitalocean.

12:18 They've got all sorts of cool stuff going on.

12:20 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, that's what they call their virtual machines, and say I want Ubuntu 18 or CoreOS or whatever, 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 wanna create that locally, you can upload your own images, 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:55 So check them out.

12:58 They're doing us well, and I'm sure they'll do you well as well.

13:02 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 and then Python 3.5 comes along and it introduces two new keywords, async and await.

13:19 Do you think there's gonna be some problem with your 3.5 code?

13:22 - Yeah, probably.

13:24 - Well, there should be, right?

13:25 Like there's a new keyword and you can't use the word class.

13:30 You can't use other core keywords, right?

13:33 You can't use def as like a variable name, 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, but they're not in Python 3.7.

13:49 - Oh, okay.

13:50 - 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:05 That's big, right?

14:06 - Yeah, that's not good.

14:08 So there's actually, I saw this article, this is from Chris Medina called AsyncIO in Python 3.7, and I thought, oh, okay, well, it's gonna talk about this keyword thing, maybe a little bit something else.

14:19 Oh no, this is like a series, there are so many changes to AsyncIO and Async and Await in Python 3.7, like pages and pages of changes.

14:29 So there's really quite a bit of new stuff, and if you cared all about this, you should go check it out.

14:35 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:49 Yeah. 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, so I definitely want to, we definitely want to heavily test your applications as you shift to 3.7.

15:11 Yeah, maybe using something like Doxer or something like that, right?

15:15 Test across the different versions.

15:16 Yeah, 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, there's tons there.

15:24 One of the challenges with async IO is it's like simulates parallelism by slicing up all these different methods and running them, running the other ones while one of them is waiting. 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. So there's no mechanism to distinguish across threads, right? That's sort of how Flask works, for example. They've got the request as a thread local variable, but it doesn't work in async I/O. So 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:08 There's a bunch of stuff around how that works.

16:10 There's a new asyncio.run function.

16:12 You just have to get a hold of the loop and call that.

16:14 Simpler task management, simpler event loop management.

16:19 You can call asyncio.getrunningloop from within the library to see if you're already being run asynchronously or if you have to kick that stuff So you can start off a cool decorator to turn async functions into async context managers.

16:34 Remember, context managers are things you can put in a with statement, right?

16:38 Like with open file name as fin, right?

16:41 There's a new part of the language that'll let you say async with, so it will like allow concurrency and you sort of do waiting type of work on those context manager enters.

16:54 Now there's a really cool decorator.

16:55 to your function and it automatically implements this asyncable, async enabled context manager, which is pretty awesome 'cause that sounds complicated, doesn't it?

17:06 (laughing)

17:07 - Yeah.

17:07 - And then there's a bunch of performance improvements.

17:10 Async.io get event loop is 15 times faster.

17:13 That's good.

17:14 Gathers 15%, sleep is twice as fast for not really sleeping.

17:19 Future is faster, all sorts of good stuff.

17:21 There's tons and tons here.

17:22 So go check out Chris's article.

17:24 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, that's great.

17:32 I like, 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, 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 Would like with an email or how do you propose this?

17:46 well, there's a, there's a proposal in pip.

17:50 So this is a proposal from, oh, Brian Skin.

17:55 - Brian Skin, yep.

17:58 - Yep, 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 subcommand thank to pip.

18:09 So that--

18:09 - So you got pip install, you got pip uninstall.

18:12 And so another one would be like pip thank requests, or pip thank SQLAlchemy, something like that?

18:17 Yeah, 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, 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." 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 There's a little bit in flux as to what would be in there.

19:03 But there's already some information apparently, it's all the info is there, a lot of it is, 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." I think it's a simple thing.

19:14 It's not going to be very intrusive.

19:16 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 done, Brian, for coming up with, Brian Skinn, for coming up with this idea and 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.

19:32 A little bit of positivity is a good thing.

19:34 - Yeah, I agree.

19:35 Yeah, quite cool.

19:36 So I feel like I kind of snuck this last item from you, 'cause this one belongs in your realm, but I grabbed it.

19:44 So this one is an article, a booklet, should I call it a booklet?

19:47 I don't know, I'll tell you why in a second, on real Python 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 with testing.

20:01 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, yeah, it's an interesting read.

20:13 I heard about this before it went through.

20:16 And it's sort of, one of the things that highlights is the, some of the process around real Python 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, Dan Bader and crew over there definitely creating some serious articles and things over at real Python.

20:35 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, it's like, I can't really go into too much detail, but it covers things like automated versus manual testing.

20:46 It's really for people getting started, I think, but it's pretty interesting for everyone.

20:50 Unit test 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 You care about which one you use?

21:03 Yeah, use pytest.

21:05 It also talks about things like writing your first test, where to write it, how to structure how to write assertions, the dangers of side effects, testing in PyCharm and VS Code.

21:15 PyCharm is pretty straightforward.

21:17 VS Code has that command palette thing, which is cool, but you gotta figure out how to do it, so that's kinda 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, 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, yeah, 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, it's kind of a pointer to, yes, you can do it in here, go read about it in other places.

21:56 But I do like it.

21:57 And like you said, the security flaws, that needs highlighted more, and I think that's a great thing to add to people's tool belt.

22:05 - Yeah, 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:12 - Yeah, I think it could, but I think it would be a lot bigger book.

22:17 Yeah, somebody should write it.

22:18 - No, 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, I don't see a lot of opinion, but the testing story in PyCharm right now is a lot stronger, and I'm not just saying that because I like PyCharm.

22:37 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:48 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:54 Awesome, all right, so those are our main items.

22:57 I have a few other things I want to throw in here, 'cause 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 and doing them actually more frequent than one a week, not up to two a week, but I'm gonna 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 (laughing)

23:26 - Yeah, Anthony Shaw's 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:39 I've seen those coming out.

23:40 All right, 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:48 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, you're trying to come up with a name, and it seems like there's all these silly names that 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, hackyourname.com, and it has just one big button, and it says, "Pivot me, bro." So I get guised back.

24:24 Let's see, if you click it a few times, you'll get some pretty good ones.

24:28 - I got your chair.

24:29 - Yeah, I had Shy Fox the other day.

24:31 I'm pretty happy with Shy Fox.

24:32 So why is this interesting?

24:33 I mean, it's funny, obviously, but it also is a 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, 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, it's a pretty simple one, but it's pretty fun.

24:52 So if you are doing a startup, like seriously, click that thing like 20 times, you'll probably find your name right there.

24:58 All right, the other one, just some quick news, Python 3.7.1 and 3.6.7, 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 3.7, 3.7.1.

25:12 So check that out.

25:13 Yeah, neat.

25:14 Yeah, link's 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:33 We've got TDD, right, 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:43 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:50 And then you just start filling out the placeholders, take away the print functions, and make it start working then.

25:54 So there you have CDD.

25:56 (laughing)

25:58 - Sure, yeah.

25:59 - Why not, right?

26:00 - Yeah.

26:01 We always have a shortage of acronyms in the programming world, so why not?

26:06 - Yeah, I think CDE may have been taken already, but I don't remember what it was for.

26:10 - Yeah, well, I'm not sure how well it's gonna actually take off, but there it is.

26:14 CLDD, I don't know.

26:16 - I don't know, I do love Click.

26:18 Click is cool.

26:18 - Yeah, it's pretty cool.

26:19 All right, 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, bye. - Bye.

26:26 - Thank you for listening to Python Bytes.

26:29 Follow the show on Twitter via @PythonBytes.

26:31 that's Python bytes as in B Y T E S and get the full show notes at Python bytes dot fm.

26:38 If you have a news item you want featured, just visit Python bytes dot fm and send it our way. We're always on the lookout for sharing something cool on behalf of myself and Brian Okken. This is Michael Kennedy. Thank you for listening and sharing this podcast with your friends and colleagues.

Back to show page