WEBVTT

00:00:00.001 --> 00:00:04.920
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to

00:00:04.920 --> 00:00:11.040
your earbuds. This is episode 173, recorded March 12th, 2020. I'm Michael Kennedy.

00:00:11.040 --> 00:00:12.100
And I am Brian Okken.

00:00:12.100 --> 00:00:16.560
And we have one of our favorite sponsors, Datadog, sponsoring the show. Check them out

00:00:16.560 --> 00:00:21.420
at pythonbytes.fm.datadog. Get a cool t-shirt, get some cool software. Tell you more about that

00:00:21.420 --> 00:00:25.780
later. You know, I think people who, when they're getting started, Brian, they write basic code,

00:00:25.780 --> 00:00:30.660
but they realize that Python is so easy to use because you can just do something like

00:00:30.660 --> 00:00:35.480
request.get. And hey, you have a website already. Like you've already downloaded like something from

00:00:35.480 --> 00:00:41.620
an API or you downloaded something, some HTML or a file. And then it's easy to forget that

00:00:41.620 --> 00:00:45.640
maybe there's more to it. Yeah, I actually totally forgot there was more to it. And

00:00:45.640 --> 00:00:51.420
we know of requests as being both powerful and really easy to use. And there's just about a

00:00:51.420 --> 00:00:56.800
million tutorials on how to put something together quickly with requests. So I was really thrilled to

00:00:56.800 --> 00:01:04.680
come across this article by, I think it's Danny Hadovic, titled Advanced Usage of Python Requests.

00:01:04.680 --> 00:01:11.580
He covers timeouts, retries, hooks, and more. And kind of that comment is it's easy to be immediately

00:01:11.580 --> 00:01:16.580
productive with requests. But there's some really cool things that you can do that I had no idea you

00:01:16.580 --> 00:01:21.700
could do this stuff. So some of the cool tricks that he runs down, actually all the tricks he runs

00:01:21.700 --> 00:01:29.500
down, there's a hooks thing, you can attach a hooks to a session. And so you can use hooks to call

00:01:29.500 --> 00:01:36.520
raise for status on every call. So raise for status is a way you can say, well, if when I request for

00:01:36.520 --> 00:01:43.320
something, if a certain status comes back, then call this other function. But like a 404, there's certain

00:01:43.320 --> 00:01:47.880
wildcard ones that you might want to like all the error ones you might want to always call

00:01:47.880 --> 00:01:50.840
something. So there's a way to hook that up. That's pretty cool.

00:01:50.840 --> 00:01:52.120
Oh, yeah. Nice.

00:01:52.120 --> 00:01:58.900
Base URLs. I had no idea you could do this. This is so neat. Instead of doing like the full path to a URL

00:01:58.900 --> 00:02:06.320
for every if you're doing a whole bunch of them, you can use a set up a base URL that essentially gets

00:02:06.320 --> 00:02:08.040
prepended to everything else later.

00:02:08.040 --> 00:02:14.020
Yeah. And this comes from request tool belt, which we covered before. So it like wraps and adds on to

00:02:14.020 --> 00:02:15.100
requests, which is pretty awesome.

00:02:15.100 --> 00:02:16.160
Oh, does it? Okay.

00:02:16.160 --> 00:02:16.700
Yeah. Yeah. Yeah.

00:02:16.700 --> 00:02:16.940
That's cool.

00:02:16.940 --> 00:02:23.180
Yeah. And this is something I do all the time when I'm writing code that talks to consumes APIs or talks

00:02:23.180 --> 00:02:28.100
to APIs or whatever is it's like, here's the base URL we set. And there's usually an if statement,

00:02:28.100 --> 00:02:33.540
like, are you in development mode? Do this. Are you in production? Use this other URL as the base.

00:02:33.540 --> 00:02:37.600
And then, you know, just do a slash, whatever it gets. But for me, it's always been.

00:02:37.600 --> 00:02:38.960
Oh, that's a great use of base.

00:02:38.960 --> 00:02:44.780
Yeah. For me, it's I've always been like, well, okay, get base URL plus whatever that I'm like.

00:02:44.780 --> 00:02:49.140
Oh, yeah. Does it have the slash on the end or does it not have the slash on the end? Do I need

00:02:49.140 --> 00:02:53.860
to put the slash on that? You know what I mean? And it's super clear here how that works. So I really

00:02:53.860 --> 00:02:57.220
like this. Like I could totally have made use of this and I haven't been so I should.

00:02:57.220 --> 00:03:04.760
And then he covers things like retries on failure, timeouts, timeouts with retries, a little bit of

00:03:04.760 --> 00:03:07.820
testing and mocking of requests. But there's, you know, there's a lot about that.

00:03:07.820 --> 00:03:13.840
Yeah. I'm looking at the section here on timeouts. I feel like, do you think people could get frustrated

00:03:13.840 --> 00:03:17.100
about this or something? What's up with this guy in this card game, man?

00:03:17.100 --> 00:03:17.820
I'm not sure.

00:03:17.820 --> 00:03:21.980
There's like this, like under setting default timeouts. There's like a giphy of a guy just

00:03:21.980 --> 00:03:27.800
beating a card table to death, right? Because he lost. It's playing Settlers of Catan and I'm

00:03:27.800 --> 00:03:31.880
guessing he lost. Anyway, it's a great, great giphy to go along with it.

00:03:31.880 --> 00:03:37.240
I'm not sure why that is relevant to here, but it's funny. It's a funny little video.

00:03:37.240 --> 00:03:43.500
Why is it relevant? This is irrelevant to the podcast, but how is this relevant?

00:03:43.500 --> 00:03:48.480
Well, it says it's great that stuff will just wait, but it can really frustrate you when someone's

00:03:48.480 --> 00:03:51.940
forgot to set a timeout and it halts a program in production. So I'm guessing this

00:03:51.940 --> 00:03:58.700
is an expression of being frustrated because production's lagged. Yeah. Yeah. Yeah. Anyway,

00:03:58.700 --> 00:04:03.080
the one that I also thought was interesting, the base URL is cool, is the retry on failure is pretty

00:04:03.080 --> 00:04:03.920
neat actually.

00:04:03.920 --> 00:04:08.840
Yeah. And then you can even customize it to say, well, not, don't retry everything, but certain

00:04:08.840 --> 00:04:10.740
things you want to make sure you retry.

00:04:10.740 --> 00:04:14.120
Yeah, for sure. And how many times and whatnot. That's a great feature.

00:04:14.120 --> 00:04:18.520
Yeah. And then this is kind of clever. The last one that I thought was clever was the,

00:04:19.200 --> 00:04:23.900
if you're, you want to mimic being different browsers by adjusting the user agent header

00:04:23.900 --> 00:04:29.000
request information, because, you know, sometimes you want to make sure that you're,

00:04:29.000 --> 00:04:32.960
whether or not you're testing your stuff, you want to make sure that you can, deal with

00:04:32.960 --> 00:04:38.580
different user agents. Or if you want to try to, if some people have, have a security stuff

00:04:38.580 --> 00:04:43.160
on where they, they only allow certain user agents cause they don't want bots coming in. Well,

00:04:43.160 --> 00:04:46.520
you can write your bot to be a different user agent then.

00:04:46.520 --> 00:04:50.020
Yeah, absolutely. You could lie to them. Tell your, tell them your internet explorer six,

00:04:50.020 --> 00:04:51.080
see what they think about that.

00:04:51.080 --> 00:04:52.760
Yeah.

00:04:52.760 --> 00:04:57.240
So this next item that I want to cover, I ran across last week and I thought it was really

00:04:57.240 --> 00:05:02.500
cool. And I'm like, I've been looking for something like this for a while. So have you

00:05:02.500 --> 00:05:05.940
heard of this library for testing? It's called pytest. Have you worked with it?

00:05:05.940 --> 00:05:07.000
Yeah, a little bit. Yeah.

00:05:07.080 --> 00:05:12.700
Awesome. So pytest is super clean and great. And you know, the way you express the assertions and

00:05:12.700 --> 00:05:18.000
whatnot is you would, you want to assert something's not none. You would assert the thing is not none.

00:05:18.000 --> 00:05:24.180
And like literally you write that code. And that's really cool for simple stuff like is not none.

00:05:24.180 --> 00:05:30.820
But if you have to test multiple aspects of a thing, like it's not none, it is a number and it's

00:05:30.820 --> 00:05:35.880
greater than zero, or it's between some range that can be a little bit tricky and you've kind of got to

00:05:35.880 --> 00:05:41.960
write some code and it's not, not as descriptive or as expressive, right? That is one of the things

00:05:41.960 --> 00:05:47.720
that I was kind of looking for is like a library that has more complex tests built in. Like, is this

00:05:47.720 --> 00:05:54.320
thing a subtype of that? Or is this string parsable as an integer? I'd like to know that beforehand,

00:05:54.320 --> 00:05:58.860
you know, like something like that. And I don't want to have to do the little, like the complicated,

00:05:58.860 --> 00:06:02.800
small, but still somewhat complicated and non-obvious code in these assertions, right?

00:06:02.800 --> 00:06:08.880
I'm also a big fan of fluent APIs. And what do you mean by fluent? I would love to see more fluent

00:06:08.880 --> 00:06:15.140
APIs in Python, the standard library. So what I mean is a function or property that you can call

00:06:15.140 --> 00:06:21.360
that returns the same object. Oh, okay. Sort of functional. Yeah, a little bit. So if I had say a

00:06:21.360 --> 00:06:30.640
list, I could say list.sort.someotherlistoperation. If sort would return a list, the list that it was

00:06:30.640 --> 00:06:36.440
called on, right? And maybe it had an order by, or I guess that's sort. If it had a filter and then you

00:06:36.440 --> 00:06:40.440
could say dot, right? Transform or something like that, right? You could sort of chain these together

00:06:40.440 --> 00:06:46.340
without doing multiple lines. Yeah. Right? So that's the fluent API. And so this thing I want to talk

00:06:46.340 --> 00:06:51.920
about is something called fluent assertions. And I ran across this from Dean Egan and he was talking

00:06:51.920 --> 00:06:57.460
about it on Twitter. And basically the idea is it has all these checks, like tons and tons of checks

00:06:57.460 --> 00:07:05.080
built into it. I'm not sure how many, I would guess 50 different checks. Is that number complex? Is it not

00:07:05.080 --> 00:07:11.500
complex? Is a value between these two things? Is this set? Is it a set? Is it non-empty? Does it contain

00:07:11.500 --> 00:07:15.920
spaces? Does this string contain spaces? Is it shorter than this? Right? So you could say things

00:07:15.920 --> 00:07:23.420
like, given an object, is it a string that contains no spaces? That is all lowercase. You could do that

00:07:23.420 --> 00:07:29.840
as like one line, just like really clearly in this fluent API. And it throws assertion errors,

00:07:29.840 --> 00:07:35.280
which are the same thing that you would get if you failed in assert directly. So it integrates really

00:07:35.280 --> 00:07:40.360
well into things like pytest. That's pretty cool, right? Cool. Yeah. Yeah. So the example,

00:07:40.360 --> 00:07:45.360
there's an example in the show notes here, and I took this from their docs. It basically says,

00:07:45.360 --> 00:07:49.820
if you wanted to test something like given two parameters, I want to check that the value is not

00:07:49.820 --> 00:07:54.800
none. It's an, that it's a float, that it's between zero and one, and you're given an object and it's not

00:07:54.800 --> 00:07:59.320
none. And it's a type of something, right? That's kind of complicated. Or you can go to their API and say,

00:07:59.320 --> 00:08:06.140
check n dot is not none dot is float dot is between. And I thought this idea is really cool,

00:08:06.280 --> 00:08:11.920
but I don't like it so much. There's like too many words, right? So I've been working on a PR and it's

00:08:11.920 --> 00:08:17.340
basically accepted. The guys running the project said, sure, this looks great. They've reviewed it.

00:08:17.340 --> 00:08:23.360
And it's a simpler one and it uses properties a lot of the time. So it's a little more English,

00:08:23.500 --> 00:08:32.500
less function he called. So you can say, is n dot not none dot float dot between parentheses zero and

00:08:32.500 --> 00:08:38.000
one close parentheses. So the things that assert like, I guess, properties about it, like whether

00:08:38.000 --> 00:08:42.020
it's a float or not none are just properties. And the stuff that takes arguments would be still

00:08:42.020 --> 00:08:48.500
function calls. So I think it's a really clean way to write these test assertions in nice,

00:08:48.500 --> 00:08:52.280
simple ways, especially if you're testing like a couple aspects, like it's not none and it's a float.

00:08:52.280 --> 00:08:56.800
Yeah, I'm on the fence. I know that that a lot of people like this sort of a style. I like your

00:08:56.800 --> 00:09:02.400
updates to it. I hope that goes in because that's a lot cleaner. It's a lot easier to read. So good

00:09:02.400 --> 00:09:09.480
luck with that. I'm perfectly a fan. That sounded harsh. But no, I'm a fan of just the straight

00:09:09.480 --> 00:09:14.920
asserts myself there. I think they're easy to read. But I think having a couple ways to do it,

00:09:14.920 --> 00:09:15.560
that sounds neat.

00:09:15.560 --> 00:09:19.580
What I like about it is it packages up some of the more complicated types of tests,

00:09:19.580 --> 00:09:24.340
like the character only has, like the character, the string has some characters,

00:09:24.340 --> 00:09:30.200
which are spaces or things like, like it's not as obvious if you've write the actual code that does

00:09:30.200 --> 00:09:34.560
the test some of the times, right? I don't know. Anyway, that's what I like about these kinds of

00:09:34.560 --> 00:09:39.740
APIs is the sort of English telling me what you're looking for more than the code of checking for it.

00:09:39.740 --> 00:09:43.120
Yeah. And also you're fitting a whole bunch of stuff on one line. It's kind of nice too.

00:09:43.220 --> 00:09:46.460
Yeah. Yeah. This is a way that you can have multiple assertions on one test without

00:09:46.460 --> 00:09:51.060
people like, say, hey, you're doing more than one test. Well, sort of. Anyway, that's,

00:09:51.060 --> 00:09:54.600
people can check that out. It's a pretty cool library. If that sounds useful to you,

00:09:54.600 --> 00:09:59.120
it's already working for the check API and probably will for the is later. Cool. Cool. Now,

00:09:59.120 --> 00:10:03.740
before we move on to the next, I want to tell you about Datadog because they're sponsoring this episode,

00:10:03.740 --> 00:10:07.440
as they have been great supporters of the show. Let me ask you a question,

00:10:07.880 --> 00:10:11.920
dear listener. Do you have an app in production that is slower than you like,

00:10:11.920 --> 00:10:16.300
or its performance is all over the place? Sometimes it's fast, but sometimes it's slow

00:10:16.300 --> 00:10:20.780
and you don't really know why. That's the most important thing is why is your app behaving this

00:10:20.780 --> 00:10:26.440
way? Do you know what's causing it to be slow or to be kind of all over the place? And if you have

00:10:26.440 --> 00:10:31.860
Datadog, you'll know. You can troubleshoot your app's performance with Datadog's end-to-end tracing,

00:10:31.860 --> 00:10:37.120
use their detailed flame graphs to identify bottlenecks and latency in that finicky app of yours.

00:10:37.120 --> 00:10:42.320
So be the hero that got your app back on track at the company and get started with a free trial at

00:10:42.320 --> 00:10:48.320
pythonbytes.fm/Datadog. Very nice. Yeah. Thank you, Datadog. Good stuff. Also good stuff,

00:10:48.320 --> 00:10:53.600
GitHub. Yeah, GitHub and GitHub Actions. I don't know how long they've been out of beta,

00:10:53.600 --> 00:10:57.440
but GitHub Actions, I think, are available to everyone now. And these are different than their

00:10:57.440 --> 00:11:03.780
webhooks, right? These are more automation workflow inside GitHub. Yeah. And GitHub's sort of by part of

00:11:03.780 --> 00:11:11.180
the Azure Pipelines sort of stuff. I mean, GitHub's associated with Microsoft now. So Azure Pipelines

00:11:11.180 --> 00:11:17.920
are one way to do actions on a, when you commit something or actions at an event time within GitHub.

00:11:18.180 --> 00:11:25.380
But GitHub Actions are a way also. They're more of a lightweight pipeline thing. But for a lot of Python

00:11:25.380 --> 00:11:31.240
projects, I think they're a very good, clean way to go because a lot of our Python projects are not.

00:11:31.240 --> 00:11:37.480
You know, if you're building a package, they're kind of perfect. So there's an article called Python and

00:11:37.480 --> 00:11:46.480
GitHub Actions. And it's by Hynik. And it's sort of really cool. He says he's currently recommending that

00:11:46.480 --> 00:11:53.380
people use GitHub Actions for Python stuff. It's simple, easy integration. So how you do that?

00:11:53.380 --> 00:11:57.480
And that's what this article is about. And he goes through running your tests through Tox,

00:11:57.480 --> 00:12:04.140
using coverage, testing against multiple Python versions, and shows you the YAML that you have

00:12:04.140 --> 00:12:08.940
to set up to configure GitHub Actions to do that right. And you also have to put a little bit of a,

00:12:08.940 --> 00:12:14.600
make a change to your Tox.ini file to make sure this all works. And then I think it's good.

00:12:14.600 --> 00:12:19.840
He was reminding people that if you've got an open source project, it's kind of nice to clean up

00:12:19.840 --> 00:12:25.360
your old stuff. So if you've, if you are switching from some other CI system to GitHub Actions,

00:12:25.360 --> 00:12:30.500
make sure to clean up the old stuff. And then he even goes through and tells some other things like

00:12:30.500 --> 00:12:37.380
changes you want to make to make sure that you're hooked up to the CodeGov system and some other stuff.

00:12:37.380 --> 00:12:42.180
And then making sure it builds on multiple operating systems, the sort of stuff you'd want to do with

00:12:42.180 --> 00:12:48.660
continuous integration. Most of it is available through Azure or not Azure through GitHub Actions.

00:12:48.660 --> 00:12:50.160
So that's kind of cool.

00:12:50.160 --> 00:12:54.760
I love that it's all part of GitHub now. That's great. You know, it's, if you're already there,

00:12:54.760 --> 00:12:58.980
it can be a pain to integrate these other systems. You can just push a few buttons or

00:12:58.980 --> 00:13:00.780
few files and just make it run there.

00:13:00.780 --> 00:13:01.120
Yeah.

00:13:01.240 --> 00:13:06.880
Kind of the secret sauce is that they're really the same thing. I think the Azure Pipelines and the

00:13:06.880 --> 00:13:12.140
GitHub Actions are all running on the same system, but the GitHub Actions is a little simpler interface

00:13:12.140 --> 00:13:18.720
for people that aren't. I mean, Azure Pipelines is, and the Azure Workflow is powerful, but it is,

00:13:18.720 --> 00:13:21.380
it is quite overwhelming when you get into it.

00:13:21.380 --> 00:13:21.880
Yeah.

00:13:21.880 --> 00:13:26.280
That whole system is pretty much all of Azure's overwhelming to me. I go there, I'm like,

00:13:26.340 --> 00:13:30.180
why are there 400 things here? There's so many things. Like, I don't care about most of these.

00:13:30.180 --> 00:13:30.880
What is this place?

00:13:30.880 --> 00:13:31.480
Yeah.

00:13:31.480 --> 00:13:33.180
Yeah. Yeah. Going back to digitalization.

00:13:33.180 --> 00:13:38.380
Okay, cool. This next one I want to talk about touches on a sort of a similar topic as the request

00:13:38.380 --> 00:13:45.260
one that you covered. As also the assertion one that I did. So one of the challenges of testing

00:13:45.260 --> 00:13:51.980
your code can be when you're talking to external systems, right? I want to call the Stripe API and I got

00:13:51.980 --> 00:13:56.880
to provide it all this information. And if you call it more than once with the same token,

00:13:56.880 --> 00:14:00.960
it'll say, sorry, you can't do that. That token's used. So you got to go get a new token. And there's

00:14:00.960 --> 00:14:06.160
just a lot of stuff. And if you necessarily want to be calling real live APIs inside your test,

00:14:06.160 --> 00:14:09.240
that's going to make it quite slow potentially. And so on, right?

00:14:09.240 --> 00:14:10.080
Yeah.

00:14:10.080 --> 00:14:15.940
You can get charged. Like we use a geolocation service on the training site to figure out which

00:14:15.940 --> 00:14:20.100
server to serve the video from. And that one, it's not super expensive, but we have to pay

00:14:20.100 --> 00:14:25.400
per use. So I don't want to hammer it in continuous integration and pay more. So there's this cool

00:14:25.400 --> 00:14:27.940
project called VCR.py. Have you heard of this?

00:14:27.940 --> 00:14:28.300
Yeah.

00:14:28.300 --> 00:14:33.200
Yeah. VCR.py is really cool. I heard about this from Tim Head, who was on Talk Python recently

00:14:33.200 --> 00:14:38.340
for the binder project. And that's going to be out shortly. But the idea is that this simplifies

00:14:38.340 --> 00:14:44.860
testing things that make HTTP requests as well as speeds it up. So all you got to do is the first

00:14:44.860 --> 00:14:50.420
time you run it, you decorate the function. And what it's going to do is going to basically

00:14:50.420 --> 00:14:55.660
instrument and record all the HTTP interaction, what gets sent out and then what comes back.

00:14:55.660 --> 00:15:01.100
And it'll save that into a YAML file hanging around, which is called a cassette. Do you like

00:15:01.100 --> 00:15:01.340
that?

00:15:01.340 --> 00:15:02.160
Yeah.

00:15:02.160 --> 00:15:03.440
Plug the cassette to the VCR, right?

00:15:03.840 --> 00:15:09.000
And the next, the second and third and fourth time that you run the test, if it finds that

00:15:09.000 --> 00:15:13.120
cassette file and the same inputs, it's like, well, you asked for this and here's your answer. And it

00:15:13.120 --> 00:15:14.760
just replays it back to you.

00:15:14.760 --> 00:15:15.580
Yeah. It's pretty clever.

00:15:15.580 --> 00:15:22.240
Yeah. It's super clever. You don't have to worry about if the system is maybe slow or you've got to

00:15:22.240 --> 00:15:26.000
set things up just right to call it because once it has that little cassette file, it's good to go.

00:15:26.540 --> 00:15:31.900
So it lets you test these external service, test your integration with these external services

00:15:31.900 --> 00:15:37.800
in a semi-realistic way because you're really playing back at least snapshot in time, real data

00:15:37.800 --> 00:15:42.660
that you got from it without any effort on your part. Let's you work offline. Your tests are

00:15:42.660 --> 00:15:46.480
completely deterministic. If it passes once, it's always going to pass because you always get the

00:15:46.480 --> 00:15:51.480
same data back. You know, definitely speed up the execution speed because it's just throwing back

00:15:51.480 --> 00:15:56.380
JSON that it has in a file rather than hitting an external service and all that. And if you decide,

00:15:56.500 --> 00:16:00.880
you know what, this request is stale and out of date, all you got to do is delete that cassette

00:16:00.880 --> 00:16:04.940
file, run your test once, it'll hit the real system and then it'll go back to playing the

00:16:04.940 --> 00:16:05.260
new cassette.

00:16:05.260 --> 00:16:06.200
Yeah. Nice.

00:16:06.200 --> 00:16:11.160
Yeah. Yeah. Pretty cool. And then for people who do like pytest, there's a cool little plugin

00:16:11.160 --> 00:16:17.800
called pytest-VCR. And then all you got to do is for your tests that might use something

00:16:17.800 --> 00:16:26.460
like URL open or request or something, you just say pytest.mark.vcr for the test. And then that's

00:16:26.460 --> 00:16:27.680
it. Magically, it works.

00:16:27.680 --> 00:16:30.180
Yeah. Okay. Nice.

00:16:30.180 --> 00:16:30.540
Yeah.

00:16:30.540 --> 00:16:34.760
I don't know if it's really magical. I think it's very useful when it can be useful.

00:16:34.760 --> 00:16:35.100
Yeah.

00:16:35.100 --> 00:16:40.080
I personally don't have the experience, but I'm going to lean on somebody that does. On

00:16:40.080 --> 00:16:45.960
episode 102 of Testing Code, I talked with Harry Percival. And part of that, we're talking

00:16:45.960 --> 00:16:50.880
about how to set up testing an application that has external dependencies through, you know,

00:16:50.940 --> 00:16:57.860
APIs and stuff. He does talk about both good experience with things like bcr.py and some

00:16:57.860 --> 00:17:04.500
difficulties. Like if there needs to be timestamps or different, if you call an API twice and expect

00:17:04.500 --> 00:17:05.720
to get something different back.

00:17:05.720 --> 00:17:06.040
Right.

00:17:06.160 --> 00:17:10.680
Well, this isn't going to help you. But so I recommend if you're running down this route,

00:17:10.680 --> 00:17:18.020
then also listen to the half hour of episode 102 with Harry Percival. It'll help a lot.

00:17:18.020 --> 00:17:20.140
Yeah. Super. We should put a link in the show notes for that.

00:17:20.140 --> 00:17:20.380
Yeah.

00:17:20.380 --> 00:17:26.300
To me, one of the things that I really like about this is I could go pip install Stripe or

00:17:26.300 --> 00:17:31.020
pip install MailChimp or some other thing that I'm integrating with that who knows what kind of

00:17:31.020 --> 00:17:36.640
complicated badness it's doing on the inside to make all of its stuff work. You know, and I don't have

00:17:36.640 --> 00:17:41.600
to think about how am I going to mock out their internals? And if their internals change, how's that

00:17:41.600 --> 00:17:47.580
going to affect my tests? And I can just say, I'm going to grab this higher level API that somewhere

00:17:47.580 --> 00:17:53.820
deep in its guts does network traffic, throw this at it, and then it'll be reproducible. And to me,

00:17:53.820 --> 00:17:55.360
that's the big appeal.

00:17:55.360 --> 00:18:02.320
Yeah. And also speed. So like, even if you're using a test server and not incurring the, all the overhead

00:18:02.320 --> 00:18:09.520
costs of, of the actual server, even with the test server, it's time and it's latency and you can speed

00:18:09.520 --> 00:18:14.260
things up by caching the return values. So it's a cool idea.

00:18:14.260 --> 00:18:17.420
Well, glad you like it. I know it's probably not something you do as

00:18:17.420 --> 00:18:22.180
much in the hardware world, but yeah, it's a cool one. What else is cool? What else you got?

00:18:22.180 --> 00:18:27.300
I got eight cool things. I'm a sucker for listicles. If there is actually good information.

00:18:27.300 --> 00:18:35.420
And so Jeremy Grifsky wrote the eight coolest Python programming languages features. And I was just

00:18:35.420 --> 00:18:40.080
smiling the whole time I was reading this. It's a quick article, but it talks about a whole bunch

00:18:40.080 --> 00:18:45.040
of features. I was reading it thinking, man, this is why I love Python. And I really miss all this stuff

00:18:45.040 --> 00:18:51.960
when I'm writing C++ code. So there's code examples of course, in, in this, in this article, but

00:18:51.960 --> 00:18:57.200
we've got list comprehensions. And that's something that when you first learn about comprehensions,

00:18:57.200 --> 00:19:02.560
it's like, Oh my gosh, this is so cool. We also have, dictionary comprehensions and

00:19:02.560 --> 00:19:08.820
other comprehensions. Now you can have, there's all sorts of stuff. Generator expressions are nice

00:19:08.820 --> 00:19:15.080
and really helpful. Slice assignment. I sometimes forget that we can do this. So you can take like

00:19:15.080 --> 00:19:20.200
part of a list and assign, like if you have a three values or something, you want to stick in the middle

00:19:20.200 --> 00:19:25.140
of a list, you can assign those with slice assignment. It's pretty, pretty powerful.

00:19:25.140 --> 00:19:31.600
Iterable unpacking. So if you've got a tuple and you want to unpack that and pass that to a function,

00:19:31.600 --> 00:19:37.000
but as separate values, you can do that. Negative indexing. I mean, you want to grab the last thing

00:19:37.000 --> 00:19:42.300
off of an array. You can say minus one or minus two. I love negative indexing so much. That's a

00:19:42.300 --> 00:19:49.520
really clever feat. It's so simple. And yet it's really nice to just go, I want the thing minus one

00:19:49.520 --> 00:19:55.180
bracket minus one. Give me that. That's the one I want. I sort of, I want minus one. I've tried to do

00:19:55.180 --> 00:20:02.920
this in C++. It's a bad idea. So negative indexing school chaining comparisons. So one is less than X is

00:20:02.920 --> 00:20:08.620
less than five to make sure X is between one and five. That's not something you can do in most

00:20:08.620 --> 00:20:14.060
languages. And it's just, it's how we talk. It's how we do math and Python has it. It's nice.

00:20:14.060 --> 00:20:21.520
He finalizes it out with f-strings, which we love f-strings. And then a whole bunch of a big list of

00:20:21.520 --> 00:20:26.900
honorable mentions. And I was thinking as I was reading this, like this entire thing, plus his

00:20:26.900 --> 00:20:31.140
honorable mentions at the, at the other stuff of like things I could have also talked about,

00:20:31.140 --> 00:20:37.400
that would be a really great, just like a, an introduction to Python course of just like,

00:20:37.400 --> 00:20:41.040
here's a half an hour of why I think Python's awesome. So it's good.

00:20:41.040 --> 00:20:45.820
I agree. I think that would be awesome. Let's see. As I look through this, f-strings definitely stand

00:20:45.820 --> 00:20:49.960
out as something that's awesome. Negative indexing already riffed on that. That's cool.

00:20:49.960 --> 00:20:56.520
Feeding comparisons, list comprehensions, and I'll throw all the expressions and other comprehensions

00:20:56.520 --> 00:21:04.080
in there. I love them, but I wish they did a little bit more. Like why can't I sort a list expression,

00:21:04.080 --> 00:21:09.600
list comprehension, or something like that? There's just a few things where it's like, oh man,

00:21:09.600 --> 00:21:14.420
if I could just, I find myself a lot of times, here's the comprehension. And then here's the

00:21:14.420 --> 00:21:18.060
little bit of things that I wish it could still support. I got to do afterwards. Anyway,

00:21:18.060 --> 00:21:18.840
it would be nice.

00:21:18.840 --> 00:21:19.500
Interesting.

00:21:19.500 --> 00:21:25.640
Like for example, paging, right? I would like to be able to skip. So if I'm on page five of groups

00:21:25.640 --> 00:21:33.800
of 20, I would like to be able to skip four times 20, take 20 with this clause sorted by that and have

00:21:33.800 --> 00:21:39.780
the sorting happen before the paging. Like that would be so nice. And it's just, you know, it's on the

00:21:39.780 --> 00:21:43.640
cusp. So half the time I'm like, God, I love these, but why can't I, you know, whatever.

00:21:43.640 --> 00:21:47.660
Or the little thing that I wish I could extend it a little more database and memory type of

00:21:47.660 --> 00:21:51.620
behavior, but still great, great stuff. I would totally miss them if they weren't there. That

00:21:51.620 --> 00:21:52.900
is for sure. Yeah. Yeah. Cool.

00:21:52.900 --> 00:21:57.980
Actually. So slice assignments, I would, I didn't never even occurred to me that you could do that

00:21:57.980 --> 00:22:02.140
with a language. So it's neat that you can do that, but I probably wouldn't miss them if they

00:22:02.140 --> 00:22:05.420
weren't there because I wouldn't have expected them to be there.

00:22:05.420 --> 00:22:09.140
You shouldn't be able to do that. Yes, exactly. Exactly. I wouldn't miss light assignment at all.

00:22:09.140 --> 00:22:13.660
Although it is neat. You know what I definitely would not miss is bugs in my web app.

00:22:13.660 --> 00:22:16.120
Yeah. Me either. Do you have bugs in your web apps?

00:22:16.120 --> 00:22:21.420
Well, I always think no. And then I learned yes, but not as often, not that often.

00:22:21.420 --> 00:22:21.740
Right.

00:22:21.800 --> 00:22:27.040
So there's this cool project called Bento that I just learned about. Have you heard of Bento before?

00:22:27.040 --> 00:22:28.760
Just the lunch style?

00:22:28.760 --> 00:22:33.080
Yeah, exactly. I do love a good Bento box, but this has nothing to do with that. Maybe the name is

00:22:33.080 --> 00:22:40.760
inspired, but other than that, no. So Bento at bento.dev, this is basically an analysis system that will

00:22:40.760 --> 00:22:48.920
look at your Flask and coming soon, other languages, Django, SQLAlchemy, whatnot. Look at your Flask app

00:22:48.920 --> 00:22:56.660
or your request calls and look for known bugs, especially in the security realm. So you don't

00:22:56.660 --> 00:23:01.560
end up with little Bobby tables. This is your school calling. Did you really name your table,

00:23:01.560 --> 00:23:08.200
your son, dash, dash, semicolon, drop, whatever? Yeah. So what the idea is you can basically

00:23:08.200 --> 00:23:14.760
pip install this thing. You call Bento init. It's going to create a Docker container with the

00:23:14.760 --> 00:23:20.080
analysis tools. And then it's going to run those against your Flask app at the moment. Like I said,

00:23:20.080 --> 00:23:28.360
Django, SQLAlchemy and stuff is coming along. And it'll find things like if you have a missing JWT

00:23:28.360 --> 00:23:36.440
token or you're missing a no opener or the content set, or if you're using requests, if you're sending

00:23:36.440 --> 00:23:42.120
username and passwords over an HTTP, not an HTTPS request, it'll automatically detect that and tell

00:23:42.120 --> 00:23:43.000
you. Oh, very cool.

00:23:43.000 --> 00:23:43.960
Yeah. It's pretty nice, right?

00:23:43.960 --> 00:23:47.540
Yeah. It's very nice. It even does like Jinja template checking and stuff.

00:23:47.540 --> 00:23:52.560
Right. Exactly. So this is open source on GitHub and yeah, you could check it out. It looks pretty

00:23:52.560 --> 00:23:59.020
nice. There's a little Giphy. Thank you guys. Well done on your project. There's a Giphy showing how it

00:23:59.020 --> 00:24:05.620
works right on the page. You can just go to the GitHub repo, scroll down a tad and just watch them

00:24:05.620 --> 00:24:10.980
find a bug, fix a bug and so on. Yeah. Very good. Cool. Cool. Cool. Anyway. So yeah, if people have

00:24:10.980 --> 00:24:15.280
for the moment Flask apps in the future, it looks like they're coming with other things, but yeah,

00:24:15.280 --> 00:24:19.360
you can just run this and it'll check it out. There's also a list of all the checks that they

00:24:19.360 --> 00:24:24.100
have, which I put into the show notes. So a bunch of stuff like, you know, some of the obvious ones are

00:24:24.100 --> 00:24:28.480
like, did you ship Flask into bug mode and stuff, but other things that are not so obvious.

00:24:28.480 --> 00:24:32.240
Yeah. That's it for our main topics, Brian. Do you have anything you want to share with folks

00:24:32.240 --> 00:24:37.860
where we get to the laughter, the hilarity? No, we could use a good laugh, but do you have

00:24:37.860 --> 00:24:43.760
anything extra? We haven't talked about it yet, but I feel like it's all the tech conferences are

00:24:43.760 --> 00:24:49.520
either canceled or they're on coronavirus watch before being cut, right? Like we've had E3,

00:24:49.520 --> 00:24:53.840
the big game one canceled. We have the game developer conference. We had South by Southwest.

00:24:53.840 --> 00:25:00.340
canceled some other ones. Some, I think some Facebook's F8, I think was canceled. Possibly

00:25:00.340 --> 00:25:04.220
Google IO. I'm not sure about the one. I don't remember exactly what they said, but

00:25:04.220 --> 00:25:08.260
PyCon's still on for the moment at the time of this recording. There's going to be an announcement

00:25:08.260 --> 00:25:13.780
tomorrow, which may change things, but just what, I just want to remark, like what a crazy time,

00:25:13.780 --> 00:25:15.960
both for the world, but also for tech.

00:25:15.960 --> 00:25:21.660
Yeah, definitely crazy. I'm curious what it's going to do for, now this is totally self-centered.

00:25:21.660 --> 00:25:26.520
I do want everybody to be healthy, but I also wonder with less people commuting,

00:25:26.520 --> 00:25:29.740
if less people are listening to podcasts, that would be terrible.

00:25:29.740 --> 00:25:34.140
Oh no, they've got a lot of housework. You all folks out there, you definitely got to keep

00:25:34.140 --> 00:25:38.800
listening. Got it. No, that's, that's actually a legitimate question. Whether or not that makes

00:25:38.800 --> 00:25:39.380
sense. Yeah.

00:25:39.380 --> 00:25:43.900
Maybe it does. Here's some of the effects I think are going to happen. I think a lot of companies,

00:25:44.160 --> 00:25:50.220
especially larger companies that believe you must have a meeting every Wednesday and it has to be

00:25:50.220 --> 00:25:55.280
like two hours with this group and an hour of that group. And you must commute every day into the

00:25:55.280 --> 00:26:01.260
office, even though you just work and through GitHub and Slack and email anyway, they're going to realize,

00:26:01.260 --> 00:26:06.520
you know what? We don't actually have to have these big offices and we don't have to have our people

00:26:06.520 --> 00:26:13.480
always come in. We were at least as well off and what's going to be like the work life change that

00:26:13.480 --> 00:26:15.520
comes from that realization.

00:26:15.520 --> 00:26:21.780
Yeah. We made sure, I mean, a year ago today, it was rare for anybody to be, to be working from

00:26:21.780 --> 00:26:28.580
home in our company, even though the work is software for the most part. But now we've made sure that

00:26:28.580 --> 00:26:35.200
everybody, I think we have out of like 80 people, something like that, we've got like only a handful

00:26:35.200 --> 00:26:40.840
of people that are not set up yet to be able to work remotely. I think that's a good change actually.

00:26:40.840 --> 00:26:44.380
I do too. It's going to be really interesting to see the knock-on effects. I think there's going to

00:26:44.380 --> 00:26:48.500
be stuff like that, like, oh wait, we actually could work in this way or we could hire people

00:26:48.500 --> 00:26:52.400
from other places or whatever. It's going to be interesting outside the just, you know,

00:26:52.400 --> 00:26:55.300
the potential chaos of people getting sick and whatnot.

00:26:55.300 --> 00:26:59.240
This has been like talking about the elephant in the room, but it's talking about the virus in the room?

00:26:59.240 --> 00:27:02.960
Yeah. Well, I hope it's not in either of our rooms. Let's just put it like that. Like right now.

00:27:02.960 --> 00:27:06.420
Yeah, definitely not. There's nobody else in my room. I think I'm clean.

00:27:06.420 --> 00:27:09.680
So speaking of mysteries, how about I tell you a joke?

00:27:09.680 --> 00:27:10.400
Oh, please.

00:27:10.400 --> 00:27:16.700
Okay. So let me give you a definition straight out of the dictionary. Debugging. Pronounced

00:27:16.700 --> 00:27:23.100
debugging. It's a verb. Primary definition. Being the detective in a crime movie where you are also the

00:27:23.100 --> 00:27:31.020
murderer. Yeah. That's a good one, right? Yes. You probably get that less since you're

00:27:31.020 --> 00:27:37.460
often coding solo, but there's times where I'm like just hot under the collar, mad about

00:27:37.460 --> 00:27:41.980
some bug in the system and trying to figure out who did this.

00:27:41.980 --> 00:27:46.920
Dude, it's time for some version control blame, some get blame, some version blame.

00:27:47.760 --> 00:27:48.000
Yeah.

00:27:48.000 --> 00:27:49.080
No.

00:27:49.080 --> 00:27:50.620
It was me.

00:27:50.620 --> 00:27:51.780
It was me.

00:27:51.780 --> 00:27:57.080
Yeah. I've been there. I've been there like, oh my gosh. Now, now what do I do?

00:27:57.080 --> 00:27:59.180
Definitely.

00:27:59.180 --> 00:27:59.940
Yeah.

00:27:59.940 --> 00:28:00.260
Love that.

00:28:00.260 --> 00:28:02.820
It's good. It's good for your humility level though, right?

00:28:02.820 --> 00:28:06.620
Yeah. And then you just remember that next time you're mad at somebody else.

00:28:06.620 --> 00:28:07.460
Exactly.

00:28:07.460 --> 00:28:08.820
Or doing something boneheaded.

00:28:10.160 --> 00:28:12.580
Awesome. Well, thanks for being here. Great to chat with you as always.

00:28:12.580 --> 00:28:13.580
Thank you. Bye.

00:28:13.580 --> 00:28:13.840
Bye.

00:28:13.840 --> 00:28:18.760
Thank you for listening to Python Bytes. Follow the show on Twitter via at Python Bytes. That's

00:28:18.760 --> 00:28:25.340
Python Bytes as in B-Y-T-E-S. And get the full show notes at pythonbytes.fm. If you have a news

00:28:25.340 --> 00:28:29.900
item you want featured, just visit pythonbytes.fm and send it our way. We're always on the lookout

00:28:29.900 --> 00:28:34.460
for sharing something cool. On behalf of myself and Brian Okken, this is Michael Kennedy.

00:28:34.460 --> 00:28:37.900
Thank you for listening and sharing this podcast with your friends and colleagues.

