WEBVTT

00:00:00.001 --> 00:00:05.340
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.

00:00:05.340 --> 00:00:09.640
This is episode 41, recorded August 30th, 2017.

00:00:09.640 --> 00:00:13.880
I'm Michael Kennedy, and yes, I'm back from vacation.

00:00:13.880 --> 00:00:17.380
Thank you, Brian Aachen, for covering and all of our guest co-hosts.

00:00:17.380 --> 00:00:23.440
And it's time to immediately start repaying Brian for his keeping things rolling while I was gone.

00:00:23.800 --> 00:00:30.280
He's in Germany for some work business, and we have a new guest co-host.

00:00:30.280 --> 00:00:31.780
Welcome, Miguel Greenberg.

00:00:31.780 --> 00:00:35.480
Hello, and thank you for having me, Michael. Happy to be here.

00:00:35.480 --> 00:00:41.160
Yeah, I'm happy to have you here. It's going to be fun to talk about the items you've chosen for the week and what I've got as well.

00:00:41.160 --> 00:00:47.360
So let's just kick it off first by saying thank you to Rollbar, who's bringing you this episode.

00:00:47.360 --> 00:00:52.620
So check them out at pythonbytes.fm/rollbar and get some good monitoring for your app.

00:00:52.700 --> 00:00:53.600
We'll talk more about that later.

00:00:53.600 --> 00:00:56.400
But let's jump to your first item, lolviz.

00:00:56.400 --> 00:00:58.300
I would like to call it lolviz.

00:00:58.300 --> 00:01:02.300
But actually, this is not anything to laugh about.

00:01:02.300 --> 00:01:10.820
So this is a Python package that generates graphical representations of very commonly used Python data structures.

00:01:10.820 --> 00:01:15.100
So far, they support five different structures.

00:01:15.100 --> 00:01:20.740
And one of them is a list of lists, which gives the lol name to the package.

00:01:21.220 --> 00:01:25.980
But they also support dictionaries, lists, linked lists, and binary trees.

00:01:25.980 --> 00:01:35.460
And what they do is basically they use GraphBiz, which you need to install on your machine to generate these graphical representations.

00:01:35.460 --> 00:01:39.460
And one of the coolest things is that it integrates with Jupyter.

00:01:39.460 --> 00:01:48.040
So if you're doing this from a notebook in Jupyter, then it'll render these graphical representations right in your prompt.

00:01:48.040 --> 00:01:55.260
So it's super cool, especially, I imagine, for you and for me, people who used to teach Python.

00:01:55.840 --> 00:01:59.140
I'm having tons of ideas to use this myself.

00:01:59.140 --> 00:02:00.120
Yeah, so am I.

00:02:00.120 --> 00:02:05.440
I'm like, this can definitely be used to help people who are new to these data structures and new to these ideas.

00:02:05.440 --> 00:02:10.060
And honestly, new to the concept of pointers and reference types at all.

00:02:10.060 --> 00:02:11.980
I think it's really a great way to learn it.

00:02:12.400 --> 00:02:21.320
The linked list one is particularly interesting to help people who are not familiar with pointers to visualize how that works.

00:02:21.320 --> 00:02:28.020
One thing I need to mention is that if you try to pip install this in Python 3 today, it's going to fail.

00:02:28.440 --> 00:02:34.500
I submitted a bug and the author told me that a fix is coming pretty soon with additional features.

00:02:34.500 --> 00:02:40.140
So I'm glad to hear that he's responsive and that he's working on making more improvements.

00:02:40.140 --> 00:02:41.900
Yeah, this thing came out really recently.

00:02:41.900 --> 00:02:46.500
I don't remember how old it is, but it's all quite new, like a couple of days.

00:02:46.500 --> 00:02:49.420
And it's already got 200 stars on GitHub.

00:02:49.420 --> 00:02:50.680
And it looks like it's going well.

00:02:50.680 --> 00:02:52.140
Yeah, it's going pretty well.

00:02:52.140 --> 00:02:54.000
Yeah, I see a bright future for it.

00:02:54.000 --> 00:02:54.740
I do as well.

00:02:54.740 --> 00:03:00.280
So if you're out there teaching Python and you're trying to help people understand pointers, data structures,

00:03:00.280 --> 00:03:02.420
and even if you're not teaching it,

00:03:02.420 --> 00:03:09.920
I think looking at some of the different representations of these data structures that it draws is probably helpful for people

00:03:09.920 --> 00:03:11.920
who just haven't really thought a lot about it as well.

00:03:11.920 --> 00:03:13.300
So definitely worth checking out.

00:03:13.300 --> 00:03:14.180
All right.

00:03:14.180 --> 00:03:19.280
So moving from visualizing different data structures to transforming data structures,

00:03:19.280 --> 00:03:22.340
the thing I want to cover first this week is Odo.

00:03:22.480 --> 00:03:27.700
So this is a user or listener recommendation, as was LOLViz.

00:03:27.700 --> 00:03:32.200
So Odo migrates data between all these different formats.

00:03:32.200 --> 00:03:41.400
And it knows how to read, let's say, a Panda data frame and then convert that to a MongoDB table or collection and save it just like that.

00:03:41.400 --> 00:03:45.120
And it's literally one line like, Odo, here's your data frame.

00:03:45.120 --> 00:03:46.060
Go to that database.

00:03:46.060 --> 00:03:48.060
Or here's your Postgres.

00:03:48.060 --> 00:03:49.760
Go to CSV or reverse.

00:03:49.760 --> 00:03:58.200
So if you find yourself pulling in data from one source and trying to convert it or save it more or less in the same shape over to another source,

00:03:58.200 --> 00:04:00.120
then check out this thing called Odo.

00:04:00.120 --> 00:04:07.480
I wonder if it takes a list of lists, an LOL, and writes a CSV file.

00:04:07.660 --> 00:04:11.800
That would be something that I could find useful tons of times.

00:04:11.800 --> 00:04:12.700
Yeah, absolutely.

00:04:12.700 --> 00:04:14.040
That would be really, really cool.

00:04:14.040 --> 00:04:16.740
And it does take lists and transform them.

00:04:16.740 --> 00:04:17.240
It only does, right.

00:04:17.380 --> 00:04:21.120
So I'm not entirely sure how flexible it is in that regard.

00:04:21.120 --> 00:04:22.700
But I think there's also extensions.

00:04:22.700 --> 00:04:23.820
So you can write extensions.

00:04:23.820 --> 00:04:25.300
So just to give you the rundown, let's see.

00:04:25.300 --> 00:04:32.540
It'll work with Panda data frames with a list with JSON files, CSV files, Postgres.

00:04:32.540 --> 00:04:37.640
Yeah, so you could take a CSV file, load it into Postgres or Postgres into JSON.

00:04:37.640 --> 00:04:42.980
Or it even works with converting into MongoDB, like I said, so like Pandas to Mongo or reverse.

00:04:42.980 --> 00:04:48.660
So not a whole lot more to it than that, but it seems really handy if that's the problem you're trying to solve.

00:04:48.660 --> 00:04:49.780
Yeah, very nice.

00:04:49.780 --> 00:04:51.660
Yeah, so tell us about concurrency.

00:04:51.660 --> 00:04:57.700
You chose this item, and it's not exactly new, but it's certainly something we haven't covered and is really amazing.

00:04:57.700 --> 00:05:03.560
And I agree with you that this is one of the really interesting things to cover in concurrency.

00:05:03.560 --> 00:05:04.200
Right.

00:05:04.200 --> 00:05:09.860
So this is a PyCon talk from a couple years ago from the one and only Dave Beasley.

00:05:09.860 --> 00:05:10.860
I mean, who else, right?

00:05:12.060 --> 00:05:20.260
And the interesting thing, as a speaker, I find it interesting, not only the content, but also the way he presented this talk.

00:05:20.260 --> 00:05:22.980
This is a live coding session.

00:05:22.980 --> 00:05:26.080
The entire thing, it's Dave's terminal.

00:05:26.080 --> 00:05:33.680
There are no slides, and he's speaking while coding and starts from an empty file, actually codes everything in the talk.

00:05:33.680 --> 00:05:36.400
I think he just fires up Emacs and says, let's do this, right?

00:05:36.760 --> 00:05:37.560
Right, yeah.

00:05:37.560 --> 00:05:44.660
Just two or three terminal sessions, one with Emacs and the other two with Bash, and it's done all there.

00:05:44.960 --> 00:05:59.340
And he goes to cover concurrency, the different ways he can do concurrency with threads, with processes, shows all the problems with both approaches, how the global interpreter log messes, you know, all this and complicates things.

00:05:59.340 --> 00:06:16.600
And then in the second portion of the talk, he goes and builds an asynchronous framework, pretty much like asyncio, a small version of it, a minimal version, using Python generators without any other additional libraries, all in Python standard code.

00:06:16.960 --> 00:06:20.120
So it's pretty amazing, and it's only 45 minutes.

00:06:20.120 --> 00:06:24.120
The amount of knowledge that's in those 45 minutes, it's unbelievable.

00:06:24.120 --> 00:06:25.800
Yeah, and I really love the style.

00:06:25.800 --> 00:06:26.640
Like, well done, David.

00:06:26.640 --> 00:06:30.740
So certainly the style of, we're going to build this up from scratch.

00:06:30.740 --> 00:06:35.560
I'm not going to just show you a bunch of slides and talk about it, but I'm going to just show you how it's built.

00:06:35.560 --> 00:06:36.840
It really makes it feel accessible.

00:06:36.840 --> 00:06:39.900
You're like, well, if he could literally do it from scratch in 45 minutes.

00:06:39.900 --> 00:06:41.560
Like, I saw everything that went into it.

00:06:41.560 --> 00:06:42.460
It was pretty understandable.

00:06:42.460 --> 00:06:44.840
It really is well done.

00:06:45.700 --> 00:06:50.860
Yeah, if people are, you know, thinking about Python concurrency or generators or asyncio and all these things.

00:06:50.860 --> 00:06:55.100
It's actually even good for networking because he builds a little server.

00:06:55.100 --> 00:06:58.260
He doesn't even use, you know, nothing like Flask or Django or anything.

00:06:58.260 --> 00:07:04.860
He builds a little server using the, he calls it the socket framework, just using network sockets.

00:07:04.860 --> 00:07:06.440
Yeah, that was like part of the demo.

00:07:06.440 --> 00:07:08.300
It was just like part of it, right?

00:07:08.300 --> 00:07:08.880
Right.

00:07:08.880 --> 00:07:10.320
Yeah, it's super awesome.

00:07:10.320 --> 00:07:10.840
Yeah.

00:07:10.840 --> 00:07:14.860
Yeah, so certainly this is, if this sounds interesting to you, be sure to watch that video.

00:07:14.860 --> 00:07:15.380
It's on YouTube.

00:07:15.380 --> 00:07:16.560
We'll link it to it in the show notes.

00:07:16.560 --> 00:07:21.720
And it's, you'll learn a bunch, especially conceptually what's going on in all this asyncio stuff.

00:07:21.720 --> 00:07:22.860
Super cool.

00:07:22.860 --> 00:07:26.420
So before we move on to the next segment though, let me tell you about the sponsor for the show,

00:07:26.420 --> 00:07:26.940
Rollbar.

00:07:27.200 --> 00:07:43.060
So Rollbar lets you basically just type pip install Rollbar, type a few commands either in your config file or encode in your web app, and it will continuously monitor your site, your web application for any sorts of errors.

00:07:43.360 --> 00:07:46.520
And not just tell you something happened, but capture all the details.

00:07:46.520 --> 00:07:50.420
What was the logged in user when they ran into an error?

00:07:50.420 --> 00:07:52.400
So who is your customer who's having this problem?

00:07:52.400 --> 00:07:54.480
What's the call stack?

00:07:54.480 --> 00:07:56.620
What other errors have you experienced like this?

00:07:56.620 --> 00:07:59.360
What are the local variables passed to the function when it failed?

00:07:59.360 --> 00:08:03.040
Like you can probably fix the error without even debugging it or running your code.

00:08:03.040 --> 00:08:04.740
You just look and go, oh, I see what's wrong.

00:08:05.220 --> 00:08:06.860
So I use Rollbar a lot.

00:08:06.860 --> 00:08:07.260
Love it.

00:08:07.260 --> 00:08:11.100
If you want to check it out, check it out at pythonbytes.fm/Rollbar.

00:08:11.100 --> 00:08:12.380
All right.

00:08:12.380 --> 00:08:16.680
So next up, I want to talk about some optimizations.

00:08:16.680 --> 00:08:28.900
This concurrency stuff that you brought up is certainly a sort of a form of optimization, but this is kind of the future trying to push CPython, the main default Python implementation, further.

00:08:29.660 --> 00:08:37.200
And this is an article on Medium by a friend of the show, Anthony Shaw, covering work that Victor Stinner has done.

00:08:37.200 --> 00:08:39.240
And Victor Stinner, have you been following what he's doing?

00:08:39.240 --> 00:08:40.960
He's like killing it on performance.

00:08:40.960 --> 00:08:41.900
He is.

00:08:41.900 --> 00:08:42.900
Yes, absolutely.

00:08:42.900 --> 00:08:46.920
I've been to his talk this past PyCon as well.

00:08:46.920 --> 00:08:47.660
Yeah.

00:08:47.660 --> 00:08:50.380
So there's just so many things that he's doing that are amazing.

00:08:50.380 --> 00:08:53.340
And he did give some good docs at PyCon as well.

00:08:53.340 --> 00:08:57.660
So this project is called Fat Python, the next chapter in Python optimization.

00:08:57.940 --> 00:08:59.820
So like I said, article by Anthony Shaw.

00:08:59.820 --> 00:09:06.400
And he basically highlights this Fat Python project that was started by Victor Stinner back in 2015.

00:09:06.400 --> 00:09:14.440
And the idea was, let's try to make it possible to apply better static optimizers for Python.

00:09:14.440 --> 00:09:20.380
So one of the big challenges that you have with optimizing Python is it's super dynamic.

00:09:20.380 --> 00:09:24.680
You can't necessarily just look at the code and say, well, it has this structure.

00:09:24.680 --> 00:09:31.020
So we're going to change it around because you could go and dynamically add methods, functions, variables, whatever.

00:09:31.020 --> 00:09:31.340
Right?

00:09:31.340 --> 00:09:32.660
Yeah.

00:09:32.780 --> 00:09:35.260
So that makes it a big challenge.

00:09:35.260 --> 00:09:44.940
So there's actually three PEPs, Python enhancement proposals, that chain together to try to make things a little bit better that Victor is working on as part of this project.

00:09:44.940 --> 00:09:50.820
So one is PEP 511, which is a proposal to add a process to optimize ASTs.

00:09:51.280 --> 00:09:59.220
So ASTs or abstract syntax trees are basically what Python pulls up before it starts to execute your code, right?

00:09:59.220 --> 00:10:01.060
It can pull up and...

00:10:01.060 --> 00:10:05.560
It's basically a, right, a tree representation of the code that you write.

00:10:05.560 --> 00:10:05.820
Right.

00:10:05.820 --> 00:10:08.160
In a form that's easier to be interpreted.

00:10:08.160 --> 00:10:08.460
Right.

00:10:08.500 --> 00:10:12.980
Like an object-oriented representation of what your code's going to do, not just the text.

00:10:12.980 --> 00:10:22.400
The idea is it's possible, it could be possible to have an optimizer look at that AST and say, okay, this looks like Panda's code.

00:10:22.400 --> 00:10:26.200
And you're applying this, you're doing this particular anti-pattern that is slow.

00:10:26.200 --> 00:10:29.640
So maybe we could change things around behind the scenes.

00:10:29.640 --> 00:10:33.120
You don't even know it to optimize or to fix that, right?

00:10:33.120 --> 00:10:36.580
Maybe people run linters that say, you're doing this thing that's not amazing.

00:10:36.920 --> 00:10:39.760
What if we could have an optimizer that would just make it fast?

00:10:39.760 --> 00:10:40.220
Right.

00:10:40.220 --> 00:10:41.860
It would just make the change for you.

00:10:41.860 --> 00:10:42.440
Exactly.

00:10:42.440 --> 00:10:47.960
The proposal is to basically create some kind of hook for creating these optimizers.

00:10:47.960 --> 00:10:49.520
And this might be built into CPython.

00:10:49.520 --> 00:10:56.500
It might even be something you pip install, like pip install the NumPy optimizer or whatever for my runtime, which is really, really cool.

00:10:56.500 --> 00:10:59.500
So that also brings us to PEP 509.

00:10:59.500 --> 00:11:04.400
Like I said, this makes it really hard to optimize because everything is mutable at runtime.

00:11:04.980 --> 00:11:13.180
And there's these things called guards that verify like the last time it's sort of processed this bit of the structure that it hasn't changed.

00:11:13.180 --> 00:11:20.820
PEP 509 is a process to add a private version of dictionaries that implement a different type of guards that are much faster.

00:11:21.040 --> 00:11:29.160
We have 5.10, which proposes a public API to CPython for specialized code with guards for a function.

00:11:29.160 --> 00:11:31.060
So the idea is you put it all together.

00:11:31.060 --> 00:11:31.960
You take this optimizer.

00:11:31.960 --> 00:11:34.760
It generates a new high-performance version.

00:11:34.760 --> 00:11:40.080
It replaces the code that would normally run with this optimized version.

00:11:40.780 --> 00:11:45.160
And as long as it doesn't change, it can run that optimized code or fallback.

00:11:45.160 --> 00:11:50.100
So taking together all three of these create this fat Python thing, which is really great.

00:11:50.100 --> 00:11:51.780
So you can download this and run it.

00:11:51.780 --> 00:11:55.800
You have to compile CPython, like a special branch of it, to make it work.

00:11:55.800 --> 00:11:56.980
But the article talks about it.

00:11:56.980 --> 00:11:58.680
But the results are really good.

00:11:58.680 --> 00:12:04.940
So, for example, a basic function that just you call it returns a string, 24% faster than Python 3.6.

00:12:04.940 --> 00:12:14.480
I was skimming through the article and the PEPs, and I could not find for this implementation what are the gotchas, if there are any.

00:12:14.480 --> 00:12:16.960
It doesn't look like there are, which is great.

00:12:16.960 --> 00:12:20.460
But I was wondering if any code can run or...

00:12:20.460 --> 00:12:21.600
I think it would...

00:12:21.600 --> 00:12:26.060
I guess the gotchas would probably be like, can the optimizer deal with it?

00:12:26.060 --> 00:12:32.240
And are you 100% sure the optimizer is not going to make a change that has a behavioral change, right?

00:12:32.240 --> 00:12:32.720
Right.

00:12:32.720 --> 00:12:32.760
Right.

00:12:32.760 --> 00:12:34.120
Yeah.

00:12:34.340 --> 00:12:36.640
That was what I was looking for.

00:12:36.640 --> 00:12:39.180
I mean, are there any cases where it can make a mistake at this point?

00:12:39.180 --> 00:12:39.500
Yeah.

00:12:39.500 --> 00:12:44.120
I think this is basically cracking the system open so that these things could be plugged in.

00:12:44.120 --> 00:12:47.120
But then you'd probably have to look at the gotchas of the optimizers.

00:12:47.120 --> 00:12:47.760
You know what I mean?

00:12:47.760 --> 00:12:48.060
Right.

00:12:48.060 --> 00:12:48.300
Yeah.

00:12:48.300 --> 00:12:49.020
So it was pretty good.

00:12:49.020 --> 00:12:51.600
Like a 24% improvement in function call speed.

00:12:51.600 --> 00:12:54.760
And that's 46% faster than Python 2.7.

00:12:54.760 --> 00:12:56.880
Like, that is a big deal.

00:12:56.880 --> 00:13:00.000
One of the big drawbacks of Python is function calls are really slow.

00:13:00.480 --> 00:13:05.500
And so people don't necessarily break their code into as small functions as they should.

00:13:05.500 --> 00:13:07.580
And so this might really alleviate some of that.

00:13:07.580 --> 00:13:08.060
I think it's great.

00:13:08.060 --> 00:13:08.860
Yeah.

00:13:08.860 --> 00:13:09.420
Yeah.

00:13:09.420 --> 00:13:10.060
Awesome project.

00:13:10.060 --> 00:13:10.580
Yeah.

00:13:10.580 --> 00:13:11.640
Keep up the good work, Victor.

00:13:11.640 --> 00:13:12.440
All right.

00:13:12.500 --> 00:13:14.420
So suppose I'm sitting at a coffee shop.

00:13:14.420 --> 00:13:17.980
I'm sure it's fine if I just, you know, go log into my bank.

00:13:17.980 --> 00:13:18.380
Right.

00:13:18.380 --> 00:13:19.500
Things like that.

00:13:19.500 --> 00:13:20.460
Right.

00:13:20.460 --> 00:13:21.020
Yeah.

00:13:21.020 --> 00:13:29.300
So, I mean, we all hear that it is insecure to go online on a coffee shop or hotel, airport,

00:13:29.300 --> 00:13:30.360
you know, all of those.

00:13:30.360 --> 00:13:30.980
Yeah.

00:13:30.980 --> 00:13:33.800
Hotels and airports scare me way more, especially hotels these days.

00:13:33.800 --> 00:13:34.340
I don't know why.

00:13:34.340 --> 00:13:34.660
Right.

00:13:34.840 --> 00:13:38.740
So, you know, very few people really understand, you know, what's the problem.

00:13:38.740 --> 00:13:45.960
You may think that if you only access sites that are HTTPS, so secure site that you'll find,

00:13:45.960 --> 00:13:48.700
and you're really not completely.

00:13:48.700 --> 00:13:52.820
All the content that you transfer to this site is going to be encrypted.

00:13:53.460 --> 00:13:58.200
But there are other things that happen before you get to a connection that are not encrypted.

00:13:58.200 --> 00:13:59.880
Like, for example, DNS searches.

00:13:59.880 --> 00:14:08.160
So if you're in a coffee shop getting to a lot of sites, it's very easy for someone on the same network to find out what sites you visit,

00:14:08.160 --> 00:14:12.220
even though they cannot see what, you know, what data you transfer to them.

00:14:12.220 --> 00:14:12.560
Right.

00:14:12.560 --> 00:14:17.960
And if somehow they happen to be able to alter that DNS, which probably has no verification because it's unencrypted,

00:14:17.960 --> 00:14:20.220
then they send you to their Google.com.

00:14:20.220 --> 00:14:21.720
They can send you to some other place.

00:14:21.720 --> 00:14:22.040
Right.

00:14:22.040 --> 00:14:22.400
Exactly.

00:14:23.040 --> 00:14:30.260
So, you know, it's very important that you take security when you go on a public Wi-Fi spot, you know, very seriously.

00:14:30.260 --> 00:14:36.720
And I wanted to mention this tool that so many times I talk to people and I mention it and they don't know it.

00:14:36.720 --> 00:14:38.300
And it's super great.

00:14:38.300 --> 00:14:39.300
It's called S-Shuttle.

00:14:39.300 --> 00:14:45.560
And typically the solution that you're told is that you need to pay for a VPN service.

00:14:45.560 --> 00:14:50.800
And S-Shuttle, it proclaims itself as the poor man's VPN.

00:14:51.620 --> 00:14:59.640
And a nice advantage it has over regular VPNs is that it doesn't require any software to be installed on the remote machine,

00:14:59.640 --> 00:15:02.860
the secure machine that you use for your connection.

00:15:03.380 --> 00:15:08.460
So, the way it works is basically you need to have SSH access into a secure machine.

00:15:08.460 --> 00:15:10.960
And in my case, I have it right here in my home.

00:15:10.960 --> 00:15:15.400
I have a little, this is a chip machine that is $9 computers.

00:15:15.400 --> 00:15:18.660
It could be a Raspberry Pi, you know, any of those.

00:15:19.340 --> 00:15:22.300
And the only thing you need there is SSH, right?

00:15:22.300 --> 00:15:25.140
So, you get it by default if you install a Linux distribution.

00:15:25.360 --> 00:15:34.640
And then from anywhere you are, you use S-Shuttle to create a secure encrypted tunnel into this secure machine that you have in your home.

00:15:34.640 --> 00:15:41.420
And then everything that you do goes through the tunnel and then it's forwarded into this secure machine.

00:15:41.420 --> 00:15:45.960
And then it happens on your secure machine, including DNS searches.

00:15:46.380 --> 00:15:47.900
So, that's really cool.

00:15:47.900 --> 00:15:55.260
So, if I run a shuttle and I go to like gmail.com, it will actually funnel the traffic through, say, my Raspberry Pi?

00:15:55.260 --> 00:15:55.460
Right.

00:15:55.560 --> 00:16:00.260
On the coffee shop, there's only going to be a connection to your Raspberry Pi.

00:16:00.260 --> 00:16:08.340
And then the Raspberry Pi will make the connection to Gmail and then forward the results back into your connection in the coffee shop through an encrypted channel.

00:16:08.340 --> 00:16:09.420
Oh, that's really cool.

00:16:09.420 --> 00:16:11.640
Everything you do is absolutely private.

00:16:11.640 --> 00:16:13.080
Yeah, that's super cool.

00:16:13.080 --> 00:16:13.900
And it's written in Python.

00:16:13.900 --> 00:16:14.440
Yeah?

00:16:14.440 --> 00:16:15.840
And it is written in Python.

00:16:15.840 --> 00:16:18.160
It recently added support for Python 3.

00:16:18.160 --> 00:16:19.140
Nice.

00:16:19.140 --> 00:16:19.640
That's cool.

00:16:19.640 --> 00:16:23.720
Because that used to be a problem in the past, but now it works on Python 3 as well.

00:16:23.720 --> 00:16:24.000
All right.

00:16:24.000 --> 00:16:24.740
Well, that's really cool.

00:16:24.800 --> 00:16:25.760
I'm definitely going to check that out.

00:16:25.760 --> 00:16:26.060
All right.

00:16:26.060 --> 00:16:32.920
So, last thing is I want to talk about something that initially might surprise people about the topic is I want to talk about Node.js.

00:16:32.920 --> 00:16:42.880
So, Node.js, while, you know, Python developers sometimes or web developers that also play with Node.js, I don't want to talk about it for that reason.

00:16:42.880 --> 00:16:50.780
Mostly, I consider Node.js like a similar new modern ecosystem and environment similar to Python's, right?

00:16:50.780 --> 00:16:51.840
It's very open source.

00:16:51.840 --> 00:16:54.200
There's a lot of people excited and contributing to it.

00:16:54.200 --> 00:16:55.020
Things like that.

00:16:55.020 --> 00:17:00.160
But Node.js has been in the news for the wrong reason this week.

00:17:00.820 --> 00:17:07.600
And basically, a bunch of people who are in charge of the steering committee for Node.js quit.

00:17:07.600 --> 00:17:15.700
Like a third of the committee quit and just said, we're done with this because there's been like a huge rift in the community apparently.

00:17:16.980 --> 00:17:27.160
And so, I kind of want to talk about this community aspect and sort of give thanks for how well things are going at Python and the Python ecosystem relative to Node.js.

00:17:27.960 --> 00:17:31.780
So, basically, there was – I don't want to get into name calling or whatever.

00:17:31.780 --> 00:17:32.600
You guys go read the articles.

00:17:32.600 --> 00:17:38.160
But there was some guy who was on the committee who was making decisions that a lot of people disagreed with.

00:17:38.160 --> 00:17:43.540
He was very much against the code of conduct for reasons that may or may not be valid.

00:17:43.540 --> 00:17:43.900
I don't know.

00:17:43.960 --> 00:17:48.120
But basically, they felt like he was not representing the community well.

00:17:48.120 --> 00:17:56.300
And the way the board worked or the system to enforce the code of conduct worked was they would look at individual things.

00:17:56.300 --> 00:18:02.280
And they would say, is this sufficiently bad, say, to like have this guy removed from being in charge?

00:18:02.820 --> 00:18:06.680
And they said any individual thing was no big – it was not a big deal.

00:18:06.680 --> 00:18:09.120
But it was not big enough to take that action.

00:18:09.120 --> 00:18:13.280
But if you add up like 10 or 20 of these things, like all of a sudden, here's like a –

00:18:13.280 --> 00:18:14.380
There's a pattern, right?

00:18:14.380 --> 00:18:15.280
A pattern.

00:18:15.280 --> 00:18:21.120
A pattern behavior that says, you know, maybe this guy is not representing us as well as we want or something like that.

00:18:21.120 --> 00:18:24.540
And so, they decided not to remove the guy.

00:18:24.540 --> 00:18:25.800
A bunch of people said, that's it.

00:18:25.800 --> 00:18:28.320
We tried for a long time to sort of fix this.

00:18:28.320 --> 00:18:31.200
And we're so fed up with it that we're leaving.

00:18:31.740 --> 00:18:33.060
We're no longer going to be on the committee.

00:18:33.060 --> 00:18:35.200
Some of the people just said, I'm done with Node.js.

00:18:35.200 --> 00:18:38.480
Like these are former like steering community folks on Node.js.

00:18:38.480 --> 00:18:40.900
Like I'm done with Node.js entirely.

00:18:40.900 --> 00:18:45.560
And actually, one of the – maybe the biggest thing that came out of this, not the people on the board.

00:18:45.560 --> 00:18:48.820
But they said moments after the failed leadership vote,

00:18:48.820 --> 00:18:55.560
Kate Marchin pushed the button and created IO.js, a new open source fork of Node.js.

00:18:55.560 --> 00:18:57.820
And this has happened before.

00:18:57.820 --> 00:18:59.920
There was some problem with Node.js in the community.

00:19:00.060 --> 00:19:02.680
And they created this thing called IO.js.

00:19:02.680 --> 00:19:06.240
This is A-Y-O.js, but phonetically, they're the same, right?

00:19:06.240 --> 00:19:11.180
So, you had some pretty interesting insights on this, I thought.

00:19:11.180 --> 00:19:11.740
Yeah.

00:19:11.740 --> 00:19:16.400
One of the things that you said, like, I mean, first of all, just like give thanks that things are working better here.

00:19:16.400 --> 00:19:18.680
And we seem to have like a better balance.

00:19:19.040 --> 00:19:24.800
But you also pointed out that we have a single leader who ultimately decides, right?

00:19:24.800 --> 00:19:25.720
We have Guido.

00:19:25.720 --> 00:19:26.100
Right.

00:19:26.100 --> 00:19:30.760
We have a single person that sets the tone for the community, right?

00:19:30.880 --> 00:19:33.000
And I believe they don't, right?

00:19:33.000 --> 00:19:33.500
Yeah, yeah.

00:19:33.500 --> 00:19:34.900
They vote on things.

00:19:34.900 --> 00:19:35.900
And many people vote.

00:19:35.900 --> 00:19:40.780
And clearly, they're very divided, right, on their roles.

00:19:40.780 --> 00:19:43.820
And some people put technical over community.

00:19:43.820 --> 00:19:47.260
And clearly, some other people, it's the reverse of that.

00:19:47.260 --> 00:19:48.120
So, yeah.

00:19:48.220 --> 00:19:56.520
I think we're lucky that at least, you know, we have a model that we know, you know, that we follow, right?

00:19:56.520 --> 00:19:56.840
Yeah.

00:19:56.840 --> 00:20:03.040
And I think it's really important that, you know, Guido's open to taking feedback from all the folks involved in the community.

00:20:03.040 --> 00:20:04.940
But in the end, he makes the decisions.

00:20:04.940 --> 00:20:06.620
And I think, you know, credit to him.

00:20:06.620 --> 00:20:10.200
He's made a lot of good decisions that keep people engaged.

00:20:10.200 --> 00:20:11.000
Yeah.

00:20:11.000 --> 00:20:11.320
Yes.

00:20:11.320 --> 00:20:12.240
So, yeah.

00:20:12.240 --> 00:20:15.080
Here's a Node.js item for Python bytes.

00:20:15.220 --> 00:20:18.160
And really, the story is just, you know, look at what's going on over here.

00:20:18.160 --> 00:20:20.840
And let's make sure that this doesn't happen to our community as well.

00:20:20.840 --> 00:20:21.680
Let's hope not.

00:20:21.680 --> 00:20:21.940
Yeah.

00:20:21.940 --> 00:20:23.280
All right.

00:20:23.280 --> 00:20:26.860
Well, Miguel, that's the items for this week that we had picked out.

00:20:26.860 --> 00:20:28.680
Anything else that you got going on?

00:20:28.680 --> 00:20:30.840
You just did an amazing Kickstarter, right?

00:20:30.840 --> 00:20:31.400
Yeah.

00:20:31.400 --> 00:20:33.720
That was actually a little experiment.

00:20:33.720 --> 00:20:39.560
I wanted, you know, for many years, I wanted to update my Flask mega tutorial.

00:20:39.560 --> 00:20:42.280
The first tutorial I wrote more than four years ago.

00:20:42.840 --> 00:20:48.860
And the amount of work is so big that I always had to give preference to work, right?

00:20:48.860 --> 00:20:50.400
Got to pay the bills.

00:20:50.400 --> 00:20:51.440
Kids got to go to college.

00:20:51.440 --> 00:20:52.100
Things like that, right?

00:20:52.100 --> 00:20:52.100
Yeah.

00:20:52.100 --> 00:20:55.520
So, I decided to give a Kickstarter a try.

00:20:55.520 --> 00:20:58.700
And basically, I converted that task into work.

00:20:58.700 --> 00:20:59.600
That is really cool.

00:20:59.600 --> 00:21:03.180
So, you have this mega tutorial, this Flask tutorial that you've done.

00:21:03.180 --> 00:21:04.080
And it's really elaborate.

00:21:04.080 --> 00:21:08.800
And you basically ran the Kickstarter and said, look, I want to update this tutorial.

00:21:08.800 --> 00:21:10.760
Who's in on helping me do this?

00:21:10.800 --> 00:21:12.540
And the community really responded, right?

00:21:12.540 --> 00:21:14.900
It responded in a huge way.

00:21:14.900 --> 00:21:21.680
Basically, you know, the modest funding that I set up for Goal was met the first day.

00:21:21.680 --> 00:21:28.260
And then from then on, I decided to start coming up with ideas to expand the tutorial, add more content to it.

00:21:28.260 --> 00:21:29.480
It got funded in one day?

00:21:29.900 --> 00:21:30.300
Yes.

00:21:30.300 --> 00:21:30.780
Yeah, that's good.

00:21:30.780 --> 00:21:33.200
The 100% funding was in the first day.

00:21:33.200 --> 00:21:39.040
But then you got something like, I don't know, maybe 600% funding in the end.

00:21:39.040 --> 00:21:40.460
It ended up pretty good.

00:21:40.460 --> 00:21:51.500
And I have some serious work to do because I have three new, complete new topics to add that I will be working on as part of this rewrite.

00:21:51.500 --> 00:21:52.220
That's really cool.

00:21:52.220 --> 00:21:53.720
So, super excited about that.

00:21:53.720 --> 00:21:54.360
Yeah, that's great.

00:21:54.360 --> 00:21:54.820
Congratulations.

00:21:55.080 --> 00:21:56.900
And how do people find more out about this?

00:21:56.900 --> 00:21:57.960
They can go to my blog.

00:21:57.960 --> 00:22:01.820
And the blog is blog.migaelgreenberg.com.

00:22:02.500 --> 00:22:05.300
And they're going to find a little Kickstarter batch there.

00:22:05.300 --> 00:22:09.960
And from there, they can go to the Kickstarter page and find out what I'm planning to do if they're interested.

00:22:09.960 --> 00:22:10.300
Awesome.

00:22:10.300 --> 00:22:12.140
Yeah, we'll throw the link in the show notes as well.

00:22:12.140 --> 00:22:12.360
Thank you.

00:22:12.360 --> 00:22:13.400
Cool.

00:22:13.400 --> 00:22:15.640
So, I just have one piece of news as well myself.

00:22:15.640 --> 00:22:17.320
Other than, hey, I'm back from vacation.

00:22:17.320 --> 00:22:18.120
That's awesome.

00:22:18.120 --> 00:22:26.920
While I was on vacation, I ended up finding a little bit of time to release my latest course, which is building RESTful APIs with Pyramid.

00:22:26.920 --> 00:22:36.800
And so, it's like an eight-hour course digging into the whole what is REST, like how do you work with HTTP status codes and verbs and all that, and then making this all happen in Pyramid.

00:22:36.800 --> 00:22:37.780
And it was really fun to write.

00:22:37.780 --> 00:22:41.560
So, if that sounds cool to you, check it out at training.python.fm.

00:22:41.560 --> 00:22:44.140
I'll probably put that in the show notes as well.

00:22:44.140 --> 00:22:44.840
All right.

00:22:44.840 --> 00:22:50.080
Miguel, thank you so much for filling in while Brian's having his beer over in Germany.

00:22:50.080 --> 00:22:51.940
Actually, I don't know what he's doing, but I hope he had a beer.

00:22:51.940 --> 00:22:54.080
Yeah, thank you for having me.

00:22:54.080 --> 00:22:54.600
Yeah, it was great.

00:22:54.600 --> 00:22:55.120
Talk to you later.

00:22:56.000 --> 00:22:57.740
Thank you for listening to Python Bytes.

00:22:57.740 --> 00:23:00.300
Follow the show on Twitter via at Python Bytes.

00:23:00.300 --> 00:23:03.200
That's Python Bytes as in B-Y-T-E-S.

00:23:03.200 --> 00:23:06.640
And get the full show notes at pythonbytes.fm.

00:23:06.640 --> 00:23:10.960
If you have a news item you want featured, just visit pythonbytes.fm and send it our way.

00:23:10.960 --> 00:23:13.660
We're always on the lookout for sharing something cool.

00:23:13.660 --> 00:23:17.060
On behalf of myself and Brian Okken, this is Michael Kennedy.

00:23:17.060 --> 00:23:20.680
Thank you for listening and sharing this podcast with your friends and colleagues.

