Python Bytes - #10 Dismissing Python's Garbage Collection, PyPI Name Reservations, and Hackers Exfiltrate US Government Data to Save Itself
Episode Date: January 23, 2017See the full show notes for this episode on the website at pythonbytes.fm/10...
Transcript
Discussion (0)
This is Python Bytes, Python headlines and news delivered directly to your earbuds.
It's episode 10, recorded Monday, January 23rd, 2016.
This is Michael Kennedy. I'm here with Brian Ocken.
Hey, Brian. You ready to talk about Python for the week?
I'm very ready, yes.
Yeah, we got some really cool stuff, and we have a pretty interesting data story
to wrap things up where people are out rescuing data with Python, I'm pretty sure.
So, let's save that for the end end and let's get started with time.
We had mentioned in episode seven that Matplotlib 2.0 was coming out,
and it is.
It's official now as of January 17th.
And there's an article from a website called BlackArbs
called Advanced Time Series Plots in Python. And I thought it was a nice
focused tutorial. Matplotlib does a whole bunch of stuff and it's a little bit overwhelming if
you only use it once in a while. So this is a focused tutorial. It's good. It uses Pandas,
NumPy, Matplotlib, of course, and a library called Seaborn that I had never heard of before.
It's a statistical data visualization add-on, I think, for Matplotlib.
Looks good.
But the article goes on with, starts with an empty XY chart and gets some financial data from Yahoo and does some manipulation of it to plot it out.
But then, now, the defaults aren't ever exactly what
you want. So this, uh, the tutorial goes through how to add like shaded areas for, um, in, in this
example, it was for, uh, area times where there were recessions. If there's something special
about part of your data, you want to highlight that there's a way to do that. Adding chart titles and axis labels and styling the legend.
I never knew you could do this, the different formatting for the XY tick labels.
And if like this chart had both positive and negative numbers,
and if you want to draw a zero line or a line anywhere that's a horizontal line,
shows how to do that.
Turning on data points.
And one of the things I didn't even know you could do, a couple things, were to put chart
annotations to describe specific plot points and then put arrows pointing to that piece
of the data.
And then adding logos and watermarks over the top.
And it's a nice, short, concise tutorial.
I like it.
Yeah, it's really nice.
And it's super approachable.
It just shows you, like, here's the code steps from here to there to there.
Get some financial data from Yahoo and do some graphs.
And, yeah, if you need to graph stuff, right, Python is getting better and better.
So, very, very nice.
Yeah.
Speaking of pictures, Instagram has a lot of pictures.
Yeah. Yeah. And they actually run a significant amount of traffic through Django and through
Python. They use a pretty interesting way of configuring their servers. It's not at all
unlike the way I do for my TalkPython websites as well, in fact, Python Bytes as well. And so let me just quote from their little article here,
and it says, how we run our web server.
Instagram's web servers run Django in a multi-process mode
with a master that process it forks itself a dozens of times
to create worker processes that actually handle the requests.
And they're doing that with MicroWhiskey in a pre-fork mode
so they can leverage shared memory across the
master and the 2050 whatever worker processes that it controls because they're all kind of running
the same code for the most part so why do you need you know 20 copies of python loaded into memory
and things like that right so they're thinking about how can they get their code to run faster
how can they run more of these forked processes and basically add more concurrency per server?
And so they came up with a pretty radical idea.
They said, what if we just turn off garbage collection in Python?
That seems bad, right?
It does seem bad, yeah.
So they wrote an article called Dismissing Python Garbage Collection at Instagram.
What they did is they had a thing where they would monitor the memory of the worker processes
and I believe restart them if the memory got too out of control.
I don't know why they're doing that, but for whatever reason they did.
And I think that they found that the shared memory was much, much less shared than they
expected.
So they said that each worker process was like 225 megs of memory usage,
and they're only sharing like 140 megs,
even though they're basically all doing the same thing.
So they went to look and sort of do some profiling,
and they thought that there was some Linux copy-on-write
behaviors happening due to reference counting.
So they said, all right, let's turn off reference counting.
That seems like really bad,
because for those of you guys who don't know,
Python's GC, or sort of of memory management works in two modes. There's a direct reference counting
deterministic thing that when the last reference to an object goes away, it's typically deleted
instantly. But the problem with reference counting for garbage collection and memory
management is you can get cycles. So there's a GC that manages cycles.
Okay.
And so what happened is they tried turning off reference counting.
That didn't help.
They said, all right, well, let's turn off GC.
And they said when they turned off garbage collection,
they were still able to run about the same,
only like accepting sort of memory leaks from cycles, I guess.
And they said they successfully raised the shared memory from 140 megs to 225.
I guess I was quoting a little bit the wrong number,
but they dramatically increased the shared memory.
And they were able to drop the memory usage per server by 8 gigs.
And they saved 25% RAM on their entire Jenga fleet.
And in fact, they actually got it to run 10% faster
due to the way the rearranged memory done by garbage collection
actually lines up with CPU caches and things. So they wrote this really detailed article with
lots of stats and the commands you can run to do these things. And they said, actually, for us,
for our weird, ultra high performance, ultra heavy load servers, it makes sense to turn off Python's garbage
collection and basically set up a custom shutdown thing that doesn't collect too much memory on the
way out the door. Isn't that interesting? It's very interesting. I didn't even know you could
turn off the garbage collection. There's apparently a way that you can do it, but it's not simple.
Yeah. And they ran into problems, like they turned it off
and other libraries would ensure that it was on
and turn it back on and things like that.
They're like, no, I want it off.
And so I think they had to like recompile some things.
You know, it's not like a flag, but anyway.
It's definitely an interesting story.
Yeah, it's a thing that questions some assumptions
about how things work.
And it sometimes definitely does not sound pretty.
But, you know, maybe you're optimizing that last 10%, 20%.
It's not going to be pretty, but this is a pretty interesting look at what Instagram is doing.
I just like to look at these large-scale deployments and people handling tons of requests, what they're doing.
It's always interesting.
Yeah.
And also somebody else out there might be thinking, Hey, maybe we could turn it off
and try to learn from Instagram.
Yeah, absolutely.
They detailed it out there.
They have a nice engineering blog.
They put interesting stuff up there frequently.
But Brett Cannon, no, I forget where Brett Cannon works, but.
Brett Cannon works with Dino veland over at microsoft uh i think the azure
data science team and their brett cannon is a python core developer yeah and he's we he's we've
got learned a lot of interesting things from brett but the um he's got a blog called snarky.ca
and he put up my experience with type hints in MyPi. I was attracted to this article because I've sort of been watching this type hint thing with a little skepticism.
So I'm not really sure if it's going to help, how it can help me.
So I was interested in reading this. that he supports, and then used both MyPy and TypeHints to try to, who's hoping to improve the quality of it.
And it's kind of an interesting project.
I didn't even know what CLA was.
So it's a CLA enforcement bot for the Python Software Foundation, and that's the Cont license agreement. So the idea is if somebody pushes or submits a pull request into one of the Python projects,
this robot goes out and makes sure that the person that is requesting the pull request has assigned CLA.
Sounds like it's obvious why this is needed.
But it's a small enough project to run
this experiment on of adding type hints. And it's not a very long article, but he points to his pull
request for this, the changes he made, and the lessons learned. I didn't know what MyPy was
before, so MyPy is a static analysis tool that makes sure
your, I think it just makes sure your type hints are correct or uses the type hints for linting.
Yeah, I think so. And you know, the PEP that you talked about, originally, I think that was all
Python 3 stuff. I'm pretty sure that that all works on Python 2 now, at least with some of
the tooling, that the type hint ideas are now, at least with some of the tooling,
that the type in ideas are being backported with the idea being that if we can take a lot of this legacy Python code, give it some static type definitions, and then use tooling
more intelligently with more information to check the upgrade to Python 3.
So actually, it can provide some structure to the older code, actually.
So I always thought of type hints as being this thing that only Python 3 gets, and it's
kind of this new deal.
But it may turn out to be most important in crossing that Python 2 to Python 3 chasm,
which is pretty interesting.
It'd be an interesting benefit.
You know what else is interesting?
The second largest,
the second most active contributor to this MyPi project,
Guido van Rossum.
Oh, really?
Yeah.
He's really doing a lot with this.
There was a couple hiccups that he ran into.
Apparently there's some of the three, six isn't fully supported,
but I'm sure that'll get supported fairly quickly.
What I really wanted to highlight was, I'm going to quote from his conclusion.
After this experiment, he asked himself, would he bother using typing and static typing in
new Python 3 code?
And essentially, he said yes.
Once it supports F strings, apparently at the time it doesn't,
I don't know if it's fixed yet.
Yeah, I think it only supported Python 3.5
and F strings, of course, 3.6,
which is shiny new.
But he says,
when I design an API,
I already have to think about
what type of objects would be acceptable.
So quickly writing down my assumptions
doesn't hurt anything.
It's relatively quick
and it benefits anyone having to work with my code.
But I also wouldn't contort my code to fit within the confines of type hints.
For example, if type hints force me to write cleaner code, then that's great.
But if something is so dynamic that it can't have type hints, then that's fine.
And I'll happily use typing.any as an escape hatch. In the end,
I view type hints as enhanced documentation that has tooling to help verify that the documentation
about types is accurate, and for that use case, I see type hints worth doing and not at all a burden.
And he also mentions that it didn't make his code less readable. It only enhanced the
readability. And since I'm all for making your code more readable, this article actually gives
me a more positive light on using types. Yeah, that's cool. I do periodically put type hints in
my Python 3 code. And I find that I usually do it when I'm looking at a function. I'm like,
you know, I don't really remember the context in which this is called and what is being passed in here.
So let me make it really explicit at the function signature level.
And then the tooling can, of course, tell me if we're doing it wrong somewhere else.
But it's kind of a reminder to me if it's not obvious what's going on.
But I don't do it, like, universally.
It's more, like, in those places where I'm knowing the type is going to really help.
Yeah, and I'm still spending, I guess, too much time straddling the legacy Python,
Python 3 world that I'm still having trouble with that chasm.
Yeah, sure.
Well, the MyPy works on Python too, so there you go.
You know what else is quite pervasive throughout Python?
Underscores. The underscore is special in Python. Is it special? It is special. It's, you know,
there's a lot of things that are special or, you know, maybe a more common way to say it would be
idiomatic, right? Or Pythonic. I think the use of the underscore is one of these symbols that shows
up a lot and they actually have meaning, but people coming from other languages
don't necessarily know all the nuanced behavior
of the underscore, or not behavior,
meaning of the underscore.
And so there's this article called
Understanding the Underscore of Python,
which is kind of a cool title.
It gives you some examples.
It says, if you write,
if you come across some Python code, you might see something like for underscore in range 10 or under in it
self, things like that. You see it all the time, but these underscores have meanings. And they said,
look, there's basically five cases with some sub cases thrown in about when you might have
special meaning with this underscore. The first one is if you're in the REPL,
if you're in just the, you know, just type Python,
go into the REPL, whatever you type,
the last value is always underscore, right?
So if you call a function and you forget to store its value,
you can just say underscore,
and that's whatever that function returned, for example.
I didn't know that before reading this article.
That's pretty cool.
Yeah, yeah, it's really handy. If you did something that took like 20 seconds, you're like,
oh, I forgot to put that in a variable. You can just, you still have it. It's called underscore.
That's cool. But that's not really in code, right? The first example I gave you for
underscore in range of 10, that's kind of the, I don't care. I have to put something here, but
I want to explicitly make the point that I don't care about
this variable. So there's interesting places where that might come up, right? This four underscore is
an example. Maybe I just want to do a loop 10 times. I don't actually care about the number.
I just want to do it 10 times. So that's one way to do it. If you have a...
So that's just a convention, right? So what's happening there is the underscore is just a character, which is a valid variable name?
Yes, exactly.
Except for the linters, the linting tools know about it.
Oh, okay.
So, for example, like in PyCharm, if you have a function that takes a parameter and you're not using that parameter,
then it'll make it gray and give
it a little squiggly saying, here's an unused argument. Examples come to mind in the Dunder
init in Pyramid. There's like a sort of startup thing that passes a configuration settings thing.
And if you don't care about the configuration settings thing, well, what are you going to do?
Well, you can just put an underscore and then you don't get warnings that that variable is unused.
Let's see.
If you're doing tuple unpacking and you've got a tuple of five things, you want the first and the fourth or whatever.
You can put some underscores in there to make it unpack correctly all over the place.
So you have this I don't care variable and the lenders actually will not warn you that underscore is not used.
Okay, cool.
That's cool.
And then you have like giving meaning to variables.
Underscore variable is like a,
some people say private.
I think of it more of as a protected variable.
So if I've got a class that has a field or attribute
like underscore name or whatever, right?
It's hints to consumers of that class.
They should leave it alone,
but technically it's still accessible.
I think that more is protected, right?
It still leaves it accessible to derived classes, but it does tell people stay away.
Yeah.
I also think of that as like, I don't make any promises that I might not change this
behavior.
Yes.
Yeah.
Yeah.
Yeah, exactly.
All right.
And you can have double underscore in a class, which will actually rename it.
So it is much harder to get ahold of like name mangling.
So that's like real private.
And if you have a conflicting thing, you can have private and uh if you have a conflicting thing you can have like if you have a variable you want to call
it in well there's a keyword called in like key in dictionary you can just say in underscore
sql alchemy has like and underscore or underscore in underscore so it can have things that look very
similar to restricted keywords but you, you know, avoids
them.
And then you have the whole Python data, data model with like dunder init, dunder new, dunder
representation, string, so on, like all the magic methods.
And then there's a few that I didn't really know about.
Well, one, I guess in the internationalization of strings, there's some special meaning
there.
It's kind of complex.
I'm not going to go into it.
And then in Python 3.6, you can use it as like where you would have commas for separating,
for digit grouping. You can have underscore. So like one underscore zero zero zero underscore
zero zero zero is a million in Python 3.6. Yeah. And this is good also just for reading
other people's code to understand how they're using it. Yeah. Because you might just think,
oh, that's a weird naming convention that that person used here. But like they're trying to communicate something very specific by using
underscore in all these circumstances. So I think it's good to like bring it up. People maybe come
from other languages. Yeah, especially people that come from Perl, because Perl has a very special
meaning for underscore. So it's good to know that it isn't that. Yeah. You know, one of the things
that I think is frustrating is if there's like a super old PyPI package, it hasn't been updated in five years, but it's got like that
perfect name. There should be some active project that could sort of inherit its name.
There was a pep that came out on the 12th by Donald Stuffed and it's in draft status currently,
but I'm sure that with probably a few tweaks by people that are really in the
Python core people, it'll probably go through. But it's called package, it's PEP 541 package
index name retention. And it's basically just like what you said is given a package name in the index
is it's a flat namespace. The unique names are a finite resource. So as the package index is it's a flat namespace. The unique names are a finite resource. So as the package index
is growing and growing older, we need to have a way to deal with things like old packages that
aren't updated anymore. Somebody that just like squatted on it, but hasn't done anything with it.
Or, you know, there's other various things or, or, or conflict of two people that legitimately
want to use it. How do we resolve
those conflicts? Yeah, like an example comes to mind for me is there's a cool package for kind
of a crummy problem called suds. So consuming soap web services in Python is not pretty because
they have all their namespaces. It's just like SOAP is like a big gnarly XML format for web services
that's like preceded or was sometimes more popular within enterprises
than JSON HTTP services.
So there's a cool package called SUDS that has like a really great API
for consuming those on the client side.
But it's kind of old and outdated.
It only supports Python 2. So a guy whose username is Jerko created,
no reflection on him personally,
created a project called suds-jerko.
So if you wanted to have,
and the package name and code is just suds,
but it's like basically that thing upgraded for Python 3.
And he couldn't use suds
because even though it was not being maintained,
it still owned it on PyPI.
Yeah, that's a tough one, though.
And even if something's not updated, it's hard to know if people are using it or not.
Some of the stuff that was addressed in this proposal is things like checking out other uses of the word, like on CPAN or NPM or GitHub.
And so if it's a very popular GitHub repository,
maybe we should let it go through or something.
I actually wanted to put in a package name to expect in.
It was already used by somebody else, but then I went out and
looked and it was legitimate. There's a lot of other tools that were more like that tool than
what I wanted to use. So it would have been bad for me to try to throw a hissy fit and grab that.
Yeah. It's interesting. It's cool that they're proposing a way to look at prior art
and existing things. I'm actually a little surprised it didn't already exist but i'm glad it's happening so yep it's definitely
definitely a good thing i mean we're about to come up on a hundred thousand pi pi packages like
the naming is starting to become something scarish right all right so did you ever read
william gibson books like um neuromancer and some of these crazy futuristic cyberpunk type books no yeah i kind
of feel like we're living in in this this sort of sci-fi future in a weird way there was the
craziest article that i saw i've seen in a while come out and i'll just read you the title hackers
downloaded u.s government climate data and stored it it on European servers as Trump was being inaugurated.
So here's the deal. There's, you know, I'm going to try to make this as politically neutral as
possible. I just want to talk about the data side of this in a pretty interesting way. Like,
who owns and controls data, right? Does the president, does the country, does the world own this data? Like the U.S. has
an incredible amount of data about the world at the Environmental Protection Agency, at NASA,
Department of Energy, and so on. And there had been some rumors that when Trump took office,
he was going to reduce, cut back, or even fire some people that worked on climate change.
People knew this a few months before, maybe a month before there, where people are looking
around saying, you know, these websites, like the EPA, for example, has a bunch of data
on it.
And they're like, what if that gets deleted?
There was actually a meeting of 60 programmers and scientists at the Department
of Information Studies at UCLA. And their goal was to find as many of these websites with government
data on it and start to scrape it and download it and exfiltrate it from the country.
Isn't that crazy? So what they did is they all got together and they
were working like 22 hours a day for like the four or five days leading up to the inauguration.
And they were just downloading, they had like a huge spreadsheet of hundreds of sites
where they'd go in and they'd try to get the data and they would pull it off. So examples include
like web pages dedicated to Department of Energy solar project initiatives or the Energy
Information Administration stuff about fossil fuels compared to renewable energy and fuel cell
research and those kinds of things. And it turns out there's actually these sort of what they call
volunteer data rescue events in Toronto and Philly and Chicago and Indianapolis and Michigan over the
last weeks trying to scrape hundreds of thousands
of pages off the internet.
So you might say, people are being crazy.
Come on.
But it turned out exactly at noon as Trump was sworn in and UCLA was actively working,
that group was working, all the climate change related data on whitehouse.gov disappeared.
But they had gotten a lot of it.
And so there's this company called Page Freezer, and I think they're a Canadian company,
and they basically create snapshots of web pages, a little bit like an internet archive
or the Wayback Machine, and it's actually a commercial service.
So these guys started to participate, and they're storing all of this data somewhere in Europe.
The reason for storing it in Europe,
because there'd be not a way for the government
to force it to shut down or something?
Yeah, exactly, exactly.
So I thought that was like,
that's the craziest headline around programming
I've seen this week.
Yeah.
And I wanted to include that.
Definitely.
Now, I do know that there's,
so again, to try to include that. Definitely. Now, I do know that there's,
so again, to try to not be too political on this, but aren't there legacy versions of the old versions of the White House website? I mean, probably on the Wayback Machine and stuff,
but it could be that it doesn't necessarily store the data linked in it. You know what I mean? Like the 100 meg CSV file or whatever.
And that was the kind of stuff they were actually going after.
Well, it's good to have it saved.
It's good to have it saved.
So we'll see where it goes.
But I just thought this was really interesting.
And I'm sure Python played a pretty key role in a lot of screen scraping initiatives with
Beautiful Soup and Scrapey and things like that.
Yeah.
All right.
So I think we're going to leave it there for this week.
That's a lot of cool news for everyone, Brian.
Definitely cool.
All right.
Well, thanks for talking to me this week.
You bet.
Thanks for sharing the stories and I'll catch you next time.
Thank you for listening to Python Bytes.
Follow the show on Twitter via at Python Bytes.
That's Python Bytes as in B show on Twitter via at Python Bytes. That's
Python Bytes as in B-Y-T-E-S. And get the full show notes at PythonBytes.fm. If you have a news
item you want featured, just visit PythonBytes.fm and send it our way. We're always on the lookout
for sharing something cool. On behalf of myself and Brian Auchin, this is Michael Kennedy.
Thank you for listening and sharing this podcast with your friends and colleagues.