To make software useful, honestly, to even make it real, you have to ship it.
Building that web app? Then get ready to deploy it. Building a tool set for data scientists?
How are you going to send them that application? Did you manage to get a cool GUI app going in
Python using PySign? It's time to have your users start downloading it. Python is an amazing
ecosystem, but one of the frailer parts of it has been shipping or deploying software,
especially to end users. In this episode, you'll meet Cliff. Join the two of us as we discuss
where we are and where we're going with shipping Python code. This is Talk Python to Me,
episode 127, recorded June 12, 2017. Welcome to Talk Python to Me, a weekly podcast on Python,
the language, the libraries, the ecosystem, and the personalities. This is your host,
Michael Kennedy. Follow me on Twitter where I'm @mkennedy. Keep up with the show and listen to past
episodes at talkpython.fm and follow the show on Twitter via at talkpython. This episode has been
brought to you by Rollbar and Datadog. Be sure to check out what they're offering during their
segments. It helps support the show. Hey, everyone. Two things I want to share quickly before we jump
into the conversation with Cliff. First, when we started talking with him about what he's up to
day to day, at the time of the recording, he couldn't announce the company name or say too much
about what he was doing. But they have since launched, and their name is Pilot. Pilot does
bookkeeping for startups using a combination of expert human bookkeepers and software automation.
It's a software service that does your books, not an app for you to do your own books. So you can find
out more about them by visiting pilot.com. And while you're there, you can imagine that
Glyph has definitely shipped some Python code to it. Next, I have a new course to announce. I just
released RESTful and HTTP APIs in Pyramid. This course will teach you the mechanics of building
amazing APIs in Python, of course. But you also learn the theory of RESTful HTTP services in general,
how to design them, when and how to use HTTP verbs and status codes, content negotiation,
and even a little SQLAlchemy. Check the course out at talkpython.fm/REST. That's R-E-S-T.
Now let's talk about shipping some software. Glyph, welcome to Talk Python.
It's great to be here.
Yeah, it's a real honor to have you on the show. You've done so much cool stuff. And
I'm surprised our paths haven't crossed more, but I'm glad they're crossing today.
Same here. And I gotta say, I know you're always so complimentary of your guests, and it's an
honor to be on the show. But I gotta say, you podcasters do some real good for the Python
community yourselves. I feel like I'm talking to a rock star here, too.
Well, thank you so much.
It's just a great way to access the culture of the elite in the Python community, the luminaries.
I know a lot of people listen to this show and really get a sense of what the culture of the
community is like from it. So we all appreciate what you do for the community.
Thank you so much. I definitely see that as like one of the major services that we provide,
you know, just to get the backstory. Like everybody knows about requests. They know about
Twisted. They know about all these things, but you know, they just know the API. They don't know
the story and the people. So as much as we can share that, that's awesome. Speaking of stories,
how do you get into programming?
Well, that's a very long one. A lot of people, you know, there's a sort of stereotypical story
of like, well, I had an Altair when I was a kid and I learned basic. And so I had a kind of
oddball version of that, which is that my father, who's a fairly prominent software developer himself,
he was an APL programmer when I was a kid.
APL blows me away, by the way.
Yeah. Have you ever actually seen like a full APL program?
I've seen little snippets and it's incredible. Could you just describe what the syntax looks like
to everyone? Cause it's really not standard.
Imagine that you were an astronaut on the moon at an archeological dig and you found a tablet
that was a programming language from an alien civilization. That's what APL looks like. It's
a combination of geometric symbols and Greek letters. And I think there might be some Hebrew letters in
there. It is a very odd sort of programming language in that it comes off this
evolutionary branch that did not have a lot of other languages on it. And it's definitely not
the main one, you know, the sort of algal derived C, C++ type programming languages that we're all
used to these days.
Yeah. It's really a great description, like an alien one. When people ask me to describe it,
I think of it's like, if Egyptians used hero graphics to like program, like this would be APL basically.
Yeah, very much so. so, and of course, when I started learning to program at eight years old,
that was not what I was looking for.
Did you try to learn APL at that age?
Dad tried to teach me. That's might not be the same thing. So I sort of learned a little bit of APL
just enough to, start trying to write a text adventure, Zork style video game.
So, I learned how to do the very first thing, which was variable assignment. So that when you would type
West, it would print out the description of the room to the West. And that's kind of where I stayed
in terms of programming sophistication for the next decade or so. Oh, well, maybe not decade,
maybe around eight years. But I, so I started off trying, I didn't want to learn a program. I just
wanted to be able to do just enough to make these Zork style video games. And I could not, without
learning to code, obviously I couldn't actually get anywhere. So I went from there, which was APL 68K
on the Amiga to HyperCard on the Mac. And, HyperCard was, I don't know, probably some of your
listeners are familiar, but maybe not all of them. HyperCard was a English like scripting environment
where you weren't writing a program, like a textual thing. You would launch HyperCard and you'd start
editing these documents, which were a combination of like buttons and text fields, as well as little
scripts that were attached to each of them. And so I spent a long time very, very tediously kind
of teaching myself to code by accident because I had chosen this environment because it was the one
where you didn't have to know how to code. And finally, after years of resisting this, I discovered
what a variable was. I discovered that you could like have a value that didn't have to be like put
into a text field or stored as a buttons label. Like you could just actually have a abstract notion
of a value. And that sort of blew my mind. But, and one of the reasons I'm telling the story is like,
I feel like that archetype that we have of the kid who learned basic and was programming since they were
like five years old, kind of discourages other people from getting into coding. They feel like,
Oh, I couldn't do this. It takes forever.
I'm too old to get started.
Yeah. Like you have to do this from it's, it's like a language learning. You can only do it when
you're really young. And I, despite having a story where I did learn to code pretty young, I feel like
it's important to emphasize. I screwed it up as hard as I could. And I really like squandered every
opportunity to learn anything useful until I was at least 16. At which point I actually started to
learn to code. I learned some C++, and then I learned some Java and started actually making games
because it was pretty hard to do it without actually knowing how to do any of the coding part of coding.
So I went from there where I was doing a bunch of kind of hobby projects and game development. I got a
job at a small software company in New Jersey and had a terrible, terrible experience writing their
flagship application in Java. We were reporting it from an old legacy, a database system to Java.
And I went wrong with that experience. What didn't go wrong. It was a interesting lesson in depending on
proprietary software you don't pay for. The major thing that went wrong was the Java runtime environment
on the Mac at the time would leak about three quarters of a megabyte of memory every time you opened a
window. And since this was a closed source runtime and our entire application was based around these
windows that would open and close, you would lose just megabytes of memory at a time. And, it was
many like as a cocky 19 year old, I didn't know anything about doing metrics or setting performance targets or
anything like that. So we got several months into the project and I of course had been reassuring
everyone the whole time, like, this is going to go great. This is going to be fantastic. It's going to
be so much better. We got close to what should have been the end date of the project and it turned into
frantic bug hunt, trying to figure out where these problems were coming from in our code. And it turned
out they were coming from the Java runtime.
Oh yeah. And so you're, you're thinking, what are we doing wrong? Let's, let's double check it one
more time and there's nothing you can do, right?
Right. It's never the compiler until one day it actually is the compiler. And then you're in a
really bad situation. So I spent a while trying to debug that. I really, I did like Java as a
programming language, but I left that job shortly thereafter, just because I felt like dying of shame
after convincing everyone this is going to be great. And then, you know, that was a huge disaster.
So as a formative experience that taught me that maybe I should be looking for systems that have an
open source component, that if there's a horrible, horrible bug, I can kind of get down into the
runtime and fix it myself. And that's one of the things that led me to discover Python.
At the time between jobs, I was kind of working on this text adventure. Once again, this is a
recurring theme in my program. I bet you're a fan of muds and these types of things.
Oh yeah. No, I was definitely played one or two in my time.
Nice. Me too.
And so, yeah, so I was developing this thing and I had written it all in Java and it was a giant,
massive multi-threading, like four or five threads per connection. This was, many of your listeners,
I hope will be too young to remember this or will have blanked it out as a traumatic memory.
But this was a time when there were, there was actually a marketing term, massively multi-threaded.
This was like a good thing that you would be proud of that your code would do.
And so this Java thing definitely qualified and it was full of just unfixable race conditions and bugs.
So one of the things that the Python language had, which I didn't have exposure to in Java or any of
my previous C++ work was the select module. And the select module, I discovered it first because we,
one of the people who was helping me out with this was developing a kind of client server protocol.
This was a mud with like a rich text front end so that it wasn't just a console.
Graphics and background patterns and things like that.
And so he was rewriting this communication layer with the client and he was tired of coordinating the five or six threads that got involved in the networking layer.
And so he just wrote it to use the select module to detect which of the operations that we might need to do to the socket were available, read or write or error.
And I had never seen such a thing before. And I thought to myself, that's interesting.
So you could do like two or three things at a time, but without threads.
And that's more or less where Twisted came from was I had started investigating that.
And it ended up being a much simpler, less error prone way to develop apps.
And so I fell in love with Python on many levels simultaneously.
One of them was that it made that whole style of programming possible.
Another was that it sort of was this thin foam padding around C that made it easier to distribute applications.
And this thing's not sharp. It doesn't cut me anymore. Does it hurt?
Exactly. Yes, it was. Physically, it didn't hurt. Actually, I was typing so many fewer lines of code in Python that I wasn't developing serious wrist pain or anything at the time.
But like after a day of coding, I would feel it if I were writing in C++ or Java.
And in Python, like it literally did not hurt me to code. So that was a pretty big upgrade.
That's really good. That's cool. Yeah, that's an unexpected benefit.
So I think this using things like IO ports and completion ports, this type of programming that's sort of asynchronous but not threaded.
That's something that takes a while to run into maybe a little bit less these days.
But certainly, it's really easy to jump into threading straight away and just think I need parallelism. Let's go create threads.
It's kind of interesting how it depends where you come from, like different programming cultures, I think give different exposures to this.
I actually did a PyCon talk a couple years ago called So Simple You Could Even Do It in JavaScript about event-driven programming.
Because if you come from a background, not just of JavaScript, but of any kind of graphical user interface, event-driven programming is very natural.
It just seems like something you do.
Even like VB6 or something like that. Yeah.
Right. Just because it's really clear when you're saying like on click, do X, on mouse down, do Y, right?
Like those types of things make intuitive sense.
The problem is when you're kind of in a back-end environment.
You're talking to a database or you're doing some kind of transaction processing.
And then you have to say on transaction complete.
And you think to yourself, but wait a second, why can't I just block?
Like this is kind of like a function call.
And that's when thread seems really appealing.
And if you've been developing things that way, then it just seems natural to keep developing them that way once you have concurrency.
I do think that it's definitely kind of becoming more popular in that domain.
But there are lots and lots of programmers that you might consider sort of novice or like not really or like non-programmers who can code, who actually take to it very easily.
And so it's kind of an interesting piece of expertise that people pick up in odd ways.
Yeah, I'm sure.
And also the rise of JavaScript, the rise of Node.js, they really put that front and center like it's unavoidable.
Exactly.
And it's that same thing where you just say, you know, on click equals and then some code.
And it intuitively makes sense.
You don't have to explain that that's an event handler and, you know, the cascading model in JavaScript.
You can learn a whole lot about handling events before you hear the word event.
Yeah, for sure.
So what do you do day to day for like professional work?
I work at a startup that is started by one of your previous guests, I believe.
Jessica McKellar.
Okay.
Is one of the founders.
And we do bookkeeping.
Actually, we're a bookkeeping service.
Primarily, I think right now for startups.
But the idea behind the company is there's lots of apps for doing your own bookkeeping like QuickBooks.
We do the work of bookkeeping with software, though.
So we can automatically classify transactions.
And so our product is not software.
It's your books.
So awesome.
Yeah.
That sounds really awesome.
But of course, you know, we have some software behind the scenes.
So since podcasts are a durable cultural artifact and our name is temporary, I will avoid saying our name.
Hopefully we'll have a permanent one soon.
Well, it sounds like a really noble goal.
There are pretty decent bookkeeping bits of software like QuickBooks.
I'm not sure I'm willing to judge it.
FreshBooks, Invoiced, those types of things.
But that doesn't solve the problem of like, hey, I would rather like do something technical and not force myself to become an accountant.
Right?
Yeah.
We are bookkeeping for companies that don't want to worry about bookkeeping.
Right.
And we have a real focus on automation and trying to make things kind of seamlessly just work.
Nice.
That sounds really fun.
Do you guys have like machine learning and stuff going on there?
We have, I guess I could say we have proprietary machine intelligence, which might mean machine learning or might mean a pile of regexes.
Who could say?
Yeah, sure.
Yeah, who could say?
All right.
Awesome.
Well, it sounds like a really fun project.
So we're going to talk about some, spend a little time on your PyCon talk.
Now, this is the PyCon 2016 talk, but were you at the 2017 PyCon?
I was.
In fact, I spoke at the 2017 PyCon.
That's right.
I do.
I also have, we're going to also talk about your talk there.
How was that experience?
What do you think?
I mean, PyCon is always a highlight of the year.
There's just so much stuff that goes on.
I can't possibly consume all of it.
One of the really interesting things about PyCon is for a technical conference that has like a really large number of tracks.
And in fact, not only does it have a large number of tracks, but there's kind of an intentional scheduling thing they do where they will put high profile talks up against each other.
So Corey Benfield, for example, gave a really good talk right at the same time as I did.
So I didn't get to see his.
Yeah.
And that was inside requests or something like that, right?
I believe that was, I always get mixed up which year it is, but yes, I think that was it this year.
Okay.
But there's so much stuff going on beyond just the talks.
I mean, there's the summits.
There's just an incredible hallway track where there's people doing open spaces and informal conversations.
And it's a real opportunity for open source projects to get together and be strategic, which is not something that we get to do a lot in open source.
But we get to sit down and see people from Twisted and Requests and AsyncIO and Flask and Jinja and Django, all in the same room, all kind of talking about the future of Python and how we're all going to add features to our various projects and things that we can work together on, standards we can collaborate on.
And so there's so much stuff going on at PyCon, no matter what your level of skill is.
There's a lot of new folks.
Every year at PyCon, I learn something really interesting about some of the software that I work on from someone who's either never used it or who's just started using it for something really unusual.
So I love hearing from those types of people as well.
Yeah.
So PyCon, always amazing.
Yeah.
I definitely look forward to it.
I'm already looking forward to the next one.
And it's like 49 weeks away or something, right?
Just to start get a calendar, start checking them off or something.
I really like what they do with the program committee where there are also a lot of new speakers every year.
Like there are people sharing new and different perspectives.
It's not, you know, obviously I give great talks.
You should go see all of my talks.
They're all archived.
But it's not just me and Corey and Hinnick and Guido standing up every year and giving the same talk over and over again.
It's like if we want to be, if the old timers want to get up on stage and say something, it's a very competitive environment because there are people talking about monitoring black holes with Python or...
...innovating robots in factories or all sorts of stuff, right?
Yeah.
There's just so much, especially with the uptick in data science, there's so much science going on that has Python involved in it in some way.
Yeah.
That's interesting.
It's probably going to only get more competitive in that there are more people and more disciplines it's pulling from.
Exactly.
And it's great to see that reflected.
I like to say that Python is always the second best language for everything.
So it's never quite the best thing you can reach for, but as soon as you need to do two things, suddenly it's the best language because you can't do machine learning and be a web server at the same time in any other language nearly as well.
Unless you want to try to write it in R, which I hear is theoretically possible, but I'm not sure it's a good idea.
Yeah.
Well, it comes down to that same thing.
I can guarantee you R is not the second best language for writing a web server.
That's right.
This portion of Talk Python to Me has been brought to you by Rollbar.
One of the frustrating things about being a developer is dealing with errors.
Relying on users to report errors, digging through log files, trying to debug issues, or getting millions of alerts just flooding your inbox and ruining your day.
With Rollbar's full stack error monitoring, you get the context, insight, and control you need to find and fix bugs faster.
Adding Rollbar to your Python app is as easy as pip install Rollbar.
You can start tracking production errors and deployments in eight minutes or less.
Are you considering self-hosting tools for security or compliance reasons?
Then you should really check out Rollbar's compliant SaaS option.
Get advanced security features and meet compliance without the hassle of self-hosting, including HIPAA, ISO 27001, Privacy Shield, and more.
They'd love to give you a demo.
Give Rollbar a try today.
Go to talkpython.fm/Rollbar and check them out.
I definitely want to touch on a few of your projects before we get into shipping software because you've got some popular projects and you've got to package them up and ship them.
So maybe we could touch them.
Like probably the best known one is Twisted and the stuff that's spun out from Twisted, right?
I think that that will probably hound me to my grave is the most popular thing I've ever done.
Yes.
Yeah.
You don't get a pick, right?
Indeed, we do not.
So maybe tell people what Twisted is for those people who don't know.
Twisted is an event-driven programming system networking engine for Python.
It's a thing that basically if things happen on the network or over the passage of time and you want to get a method called on your objects, as a result of that, Twisted can help you out.
It's got web client and server.
It's got an IMAP client and server.
It's got a DNS client and server.
It's got a whole bunch of protocols implemented.
And it's also got a lot of stuff that lets you kind of combine asynchronous control flows in various interesting ways.
It's kind of almost the original framework for this.
I hesitate to say that because there are a lot of precursors that Twisted drew from.
But a lot of those precursors were much more special-cased and kind of purpose-specific.
Whereas Twisted, like the concept of a deferred originally came from Twisted and deferreds eventually moved kind of front-end into JavaScript and eventually deferreds became promises.
And promises are obviously a very popular thing for JavaScript developers to use these days.
So Twisted is both new and dynamic.
There's lots of interesting stuff going on in that community.
Lots of modern practices being adopted.
But it's also very kind of venerable and pretty old as a non-legacy technology goes.
Yeah.
It was definitely one of the original ways to write this style program that you talked about in the beginning,
where it's kind of IO completion port, not just 100 threads running next to each other, right?
Right. And one of the things we did, we actually presented a paper at Usenix at the very beginning of the Twisted project,
talking about the need for kind of a high-level interface to things like IO completion ports.
Because at the time, FreeBSD was adding KQ, and Linux was starting to add ePoll,
and Solaris had its own high-performance multiplexing mechanism.
But of course...
You guys are like, stop the madness. We can't have all of these.
Well, actually, we were kind of almost saying the opposite.
We were like, this is great, all these hyper-optimized, low-level kernel things.
And I guarantee you, no one will ever write an application to talk to one of these.
You're going to get the three biggest servers out there to do it,
and then no other app will ever be able to take advantage of your custom kernel special thing.
We need a way for apps to write against a common API so that when the kernel goes off and does some crazy new thing,
we can actually use it without having to rewrite all of our code from scratch.
So there was definitely an element of stop the madness from the perspective of stop putting all of these new .h files that I have to include.
Like, they're not helping me.
Yeah, yeah.
It sounds really interesting.
So Twisted's still going strong, huh?
People are still doing interesting new things with it?
Oh, yeah, absolutely.
One of the interesting things about it, which I did predict when AsyncIO came out,
there were a lot of people who don't like Twisted for one reason or another
and who were sort of sharpening their knives when AsyncIO came out.
And they were like, oh, great.
Now, you know, we don't have to use Twisted anymore.
It's like, it's true.
If you don't like Twisted, there's like more options now.
But there was a sense among many people that it was going to kind of be the doom of Twisted.
Oh, now there's this event loop in the standard library.
But one of the interesting things that came out of that was that event loop is just one small piece of what Twisted did.
And we did not want to have to be the kind of standard bearers for all event-driven programming in Python.
We wanted to provide like a nice little suite of protocols that all work together nicely and like tools to help you with testing and like generally be like a framework.
But it would sort of be like if Django, let's say, were the only way to speak HTTP from Python.
And one day somebody came out with a second web server or there was like a web server in the standard library.
Yeah, watch out.
There's a bottle now.
Everyone's going to just stop using Django.
Exactly.
It's like, no, Django does like one or two other things that you might want to do.
And Twisted's the same way.
We've actually seen a big uptick in activity and interest.
A lot of other people starting to pick up Twisted.
Because for a long time there was a vacuum in the standard library.
It really wasn't clear how Python was going to do concurrency.
And now that the answer is like async await, event-driven I.O., that's what's coming.
That's the future.
It's like, oh, okay.
Well, Twisted's been in the future for the last 15 years.
That's cool.
Are you thinking of, or can you already like access it in Python 3 with like async and await type programming models?
Oh, yeah.
No, we support.
So I believe we've been adding new features every release for the last couple of years.
I'm not sure exactly where everything landed.
But in 17.5, which is a release that just came out, I believe, yesterday, we have full support for converting deferreds into futures and creating futures from deferreds.
So not only can you use async await, which you've been able to do for a while with Twisted, you can even use Twisted in the middle of an async I.O. app.
You can switch to use some Twisted library code and then switch back anytime you want.
So it fully integrates at every layer.
Oh, that's awesome.
It's got coroutine support for interacting with futures.
It's got event loop support.
It's got an async I.O. reactor that you can use.
So you can map Twisted's event loop on top of async I.O.
There's TXTULIP, which is a third-party thing that's been able to do this for a really long time, even before Tulip became async I.O.
and got it at the standard library.
So we've been really – I mean, Twisted has always been a very integration-focused project.
I mean, we speak gross, difficult protocols like IMAP, so you don't have to.
And, you know, we do the low-level plumbing so you don't have to, too.
Yeah, that sounds really, really nice.
So two quick comparison questions.
First of all, what do you think of some of the new frameworks coming out, like UVLoop and things like Sanic and Jopronto and those efforts there?
I mean, I think it's great that everybody's learning this new paradigm and doing cool little experiments with it.
I do think that there is maybe a slightly odd perspective where people are looking at something like Sanic, which is brand new and kind of named after a weird meme,
to be equally kind of feature-complete and robust as something like Twisted.
And I think that in many cases, like, the comparison is almost unfair because, like, it's not like Sanic comes with its own DNS server, right?
Like, there's a lot more stuff in the Twisted ecosystem and in the Twisted core.
I think both those projects, personally, I think they're pretty interesting and they look very promising.
But I don't feel like they're close to ready yet.
Yeah, I think that, I mean, they're certainly ready for some things.
And I wouldn't want to discourage people from trying them out.
But I also think that it's important to kind of calibrate your expectations.
I mean, there are many things that Twisted still doesn't do right after 15 years of trying to do this.
And so I think that there's also, like, Curio and Trio, like, weird new event loop models that people are experimenting with.
Yeah, that was my second question.
Like, Curio also sounds a little bit similar to Twisted in that it's trying to really be the loop and, you know, talk different protocols in the network and stuff like that.
I mean, I think that the idea behind Curio and Trio was kind of to invent a new style of programming.
And Twisted has this kind of unofficial policy of no new ideas.
We don't implement anything, like, novel or original.
Everything that Twisted does at a kind of fundamental level is something that my dad was doing on Stratus mainframes with, in C, in, like, the 80s and 90s.
So, you know, we are not as focused on kind of being a research platform, which means that, you know, there's kind of less interesting new agey stuff in Twisted that might spark an interesting research direction.
But it also means that you can kind of let Twisted be boring and make your application be the interesting part.
Yeah, well, sometimes boring is good if you're building on top of it.
That is our hope.
Nice.
All right.
So you want to just maybe touch a little bit on some of your other projects that you want to mention?
And then we can talk about shipping software.
Sure.
I mean, a couple that I think are always need to be mentioned in the same breath as Twisted are Klein and Trek.
Klein is like Flask, but for Twisted.
Trek is like Requests, but for Twisted.
They're a little bit different than Flask and Requests in certain ways.
But if you want to build like a kind of standard service-oriented app or like a little web app with Twisted in an event-driven way, those are pretty much almost required.
Right.
Because you're going to need to not just listen on HTTP, like Twisted, the web server that comes with Twisted, you should think of like as a competitor to Apache or Nginx, not Django or Flask.
It's a web server and it's designed to be, the API that it offers is designed to be kind of like a configuration language for composing resources together.
Whereas like Klein is an app platform.
You can write a little server with it.
And then there's also TX Acme, which is based.
So I made a project called TX S&I, which was just sort of designed to make it easy to dump your SSL certificates into files without caring what order the private key and the chain certificate and the nine other things you seem to need to dump into a SSL configuration.
You could just kind of put them all in a file in any order and call it like your domain.pem and it would automatically get loaded.
And then Tristan Seligman built on top of that with TX Acme, which is a Let's Encrypt implementation for Twisted.
So you can just like combine those three things and get a service that automatically listens on an SSL port, automatically provisions the certificate and gives you nice async server and client web APIs.
Oh, that sounds like a fun set of building blocks.
So yeah, so those are the ones you should definitely check out.
We've also been trying to make an effort to move some of the data structures that Twisted uses that have nothing to do with event-driven programming, that are just kind of useful Python library functionality, out.
So Mahmoud Hashemi recently extracted our URL object into a project called Hyperlink.
And Hyperlink got adopted partially as part of that inter-project communication and collaboration that I mentioned at PyCon into the Python HyperOrg.
The name and the fact that the org is called Hyper are just kind of a coincidence, but people I'm sure are going to assume that it's called Hyperlink because it was made by Hyper.
But that's a really handy object if you need to parse URLs like a web browser does, like dealing with Unicode and all the different places that Unicode can show up and parsing percent escaped stuff into human readable text.
That's a handy library to have.
That sounds nice.
And that's the kind of stuff you don't want to mess with, with weird escapes people can do to get around security and all sorts of stuff, right?
Oh, yeah, you can find slashes in all kinds of strange places.
And yeah, Hyperlink, it's because it kind of parses like a browser does.
It lets you do all kinds of interesting stuff, like interesting transformations where you can say there's like a click method that'll take a URL and give you a new URL.
It's like a link to the URL, which is the kind of thing where if you like doing web crawling or, you know, indexing web documents, it's the sort of thing you have to be able to do a lot.
So, but there's a couple others.
There's also incremental, which is we have a version object in Twisted because we were very concerned with backward compatibility and long term support for various things that you need to be able to track versions.
So we spun that out to a different library.
It's also eventually, which is because we're concerned about compatibility.
Compatibility means you need to have deprecations.
And so eventually is a library for deprecating stuff and eventually removing it, which is where it comes from.
Yeah, I really like that project.
Yeah, we're hoping it becomes a little more popular because like in such a high level dynamic language as Python, you need to be kind of disciplined about making sure that you communicate to your users like, hey, this is going away.
It's going to stop working in so many versions.
And like this is perhaps segwaying into our main topic here.
It's important to be able to do that because you want people to be if they're packaging applications, including your stuff, if it's part of their requirements that text, you want them to be able to upgrade regularly.
But you also want them to know how much technical debt they've got pending and like how much work they have to do before they can upgrade again.
Yeah.
And you don't have the compiler with a, you know, a deprecated flag right there.
Right.
And so you basically have this runtime thing that does something similar, which is cool.
Exactly.
Yeah.
Nice.
Hey, everyone.
This is Michael.
Let me tell you about Datadog.
They're sponsoring this episode.
Performance and bottlenecks don't exist just in your application code.
Modern applications are systems built upon systems.
And Datadog lets you view the system as a whole.
Let's say you have a Python web app running Flask.
It's built upon MongoDB and hosted and scaled out on a set of Ubuntu servers running Nginx and MicroWSGI.
Add Datadog and you can view and monitor and even get alerts across all of these systems.
Datadog has a great getting started tutorial that takes just a few moments.
And if you complete it, they'll send you a sweet Datadog t-shirt for free.
Don't hesitate.
Visit talkpython.fm/Datadog and see what you've been missing.
That's talkpython.fm/Datadog.
You gave a really nice talk and you structured it in the form of a play, more or less, at PyCon 2016 called Shipping Software to Users with Python.
And this is something I'm also super passionate about.
And I feel like we've seen the growth curves of Python really, really taking off and, surprisingly, even in the last few years, becoming much more popular than it was.
But I think if we had a better deployment story, it would even be steeper, that curve.
I totally agree.
And this is one of the reasons that I wanted to write that talk in the first place was that I was and am really passionate about Python being available to people kind of where they are.
One of the things that drove me to talk about deployment is it's cool that Python's usable as a web service thing.
It's certainly been a huge driver of economic activity and scientific discovery in that kind of role.
But there's also something just tremendously empowering about being able to program your own computer and make it do useful stuff for you.
Yeah.
And the problem with having a kind of broken deployment story is it seems like a kind of arcane technical solution, system deployment or application packaging.
But when you think about it, it's really just like some fifth grader makes a hilarious guess the number game.
And then they want to share it with their friend.
Like what do they do at that point?
They go to their friend's house and they set up their machine to run it.
Right.
Exactly.
They take their laptop over there because that's all you can do these days.
And so that often drives educators away from Python because if they do it in Java or they do it in – so in Java, it's a little bit weird.
You often have like a strange runtime environment that all the students have to set up.
But if it's in JavaScript, they just load the web page and there it is, right?
Yep.
And Swift is making inroads there as well with their playgrounds and all that kind of stuff as well.
Exactly.
And Swift is as amazing as playgrounds are and there's a lot to like about them.
It's almost the thing that I was – it's sort of the nightmare scenario that I'm afraid of, which is why I really think we should get our deployment story together in the Python community, which is that it kind of draws this line between technical people and non-technical people.
And if you're like a real programmer, you ship to the app store.
And if you're just playing around, you use playgrounds.
And that dichotomy creates this sense that people are not empowered to do like real programming or make real apps.
And I think there's two sides to that.
Apple's also done quite a bit to reduce the barrier to entry on shipping software into the app store.
It's a lot less expensive than it used to be.
It's a lot less effort than it used to be.
But it is still this hurdle that, for example, kids are just never going to get over.
Whereas when I was learning to program as a kid, the sense that grown-up professional, serious software company like Broderbund could make something and put it on floppy disks and then you could do the same thing was very powerful.
It was really – it gave you a sense that you could do something real in a way that kids don't get to experience in a lot of different levels.
Like if a kid wants to be a doctor when they grow up, they can't like kind of do some surgery just to try it out, right?
But as programmers –
That's right. We hope not.
Exactly.
But as programmers, you know, we have this luxury of the safety of being able to potentially make something that's like real and useful and shareable.
But if deployment doesn't work, you don't get any of that.
Yeah. Yeah, absolutely.
And on the other end of the spectrum, if you go to the pro places and you say, let's write some – especially like the one that really strikes me is, let's write a GUI app in Python that we're going to ship around, right?
Like it certainly is possible and we'll talk about some of the tools that you can do it with.
But it's not as easy as some of the other here's the thing I compiled and you just take it and it just runs stories.
Right. It's really not very streamlined.
And it is getting better, but again, I guess we can talk about how.
Yeah, yeah, absolutely.
So you said that you had your talk sort of focused in different areas.
Like you were focused on maybe the people that create libraries, the people who run stuff in the cloud, like web developer types.
And then this third one where we talk about either from a kid perspective, like learning or from a pro perspective, shipping stuff to end users, right?
Was that basically the three areas you were focusing on?
More or less, yeah.
I mean I also talked a little bit about the people maintaining the infrastructure in Python, but that's kind of more of a like telling them to consider those other three perspectives.
Right. Okay. So you went through some of the stuff that you can do for the server side and that's pretty straightforward.
Like we can make packages.
We can use things like Twine and ship those up to PyPI.
We can package them as wheels.
We have requirements.txts.
Like that kind of stuff.
I don't know. It's super clean, but it certainly works well once you get used to it.
Like I've had a few people who are learning Python web development come to me and say, this is all really hard.
How do I make this stuff work?
Like I don't know what to do.
So maybe it's not hard, but it, and you kind of touched on that.
It's like, it's confusing or not clear what the steps are.
Yeah. One of the problems is, you know, we actually have a fair amount of documentation at this point, except there's so much of it now.
We trip over our own feet trying to explain to users how to do this kind of stuff.
And so you end up with something where it's like, it's actually pretty straightforward to assemble a Docker container, let's say.
But you'll find so many half written tutorials and there's so many concepts and so many separate tools that you have to chain together that most people do not end up on the fast path.
They do not end up just doing the one thing that's going to be easy for them.
And I think that that's getting a little bit better in terms of like what things people are linking to and what you happen to find just thanks to PageRank kind of finding the better articles over time.
But yeah, it's starting to stabilize a little bit as well.
Yeah, it's definitely been a long slog to get here, though.
And where we are is definitely not ideal.
One of the points I think that I didn't make in the talk that's probably worth talking about is that Python is not a deployment platform.
And so everything that we do, the things that I talked about in the talk, the things that we're talking about now, distutils, setup.py, virtualenv, right?
These are mostly developer tools.
They're for assembling the software into some shape, but they're not really for shipping it.
And one of the reasons that Cloud Python has gotten a lot better is that most of the assumption about where you're deploying your stuff is shifting towards containers.
And Docker is a deployment platform.
That is a system with like a pretty clear contract of what goes into a software artifact.
Like it's a Docker image.
That's it.
There are really no other options.
How do you run it?
Well, it's got an entry point.
And that's it.
Like there's a couple of things you might need to document.
I have a whole separate series of blog posts and stuff about type system for Docker and how it needs to be more expressive.
But basically, if you hand an ops person a Docker image, they more or less know what to do with it.
It's a clear integration point between Python people and systems people.
And the tools that we have at our disposal, like PIP, like distutils, like virtualenv, make sense in that context.
And we can pretty easily script them to do the right thing to build a Docker image.
But Docker is just one deployment platform.
And the problem is we need tools that deploy Python to multiple different deployment targets and not try to come up with a quote unquote Python deployment target that is universal and works.
Right. Like, for example, in the GUI space, just because you get a Docker container and you can ship that to end users and go, now run the Docker container.
Right. There's no Docker run on my iPhone.
Right.
Yeah, exactly.
That shows up in a couple of different places.
I mean, there's any kind of GUI front end thing suffers from this.
Like the GUI front end stuff just can't be shipped in that style.
But also it can't be as easily shipped with shell scripts.
Right.
The reason Docker works so nicely with the Python tool chain is that most of the things that we've sort of been building up from are a combination of dependency on some Linuxy,
type tools that are the low level stuff and then a script to assemble them into a coherent, like runnable shape.
And that's pretty easy to do in Docker, but that's a lot harder to do on, let's say, Windows.
Right.
Where ultimately you're just trying to get a P executable or zip file together.
But the process you need to go through to do that in order to, like, integrate with the Windows compiler and all of that stuff,
you actually kind of have to know about those tools and you can't just, like, write a little script and copy some binaries around.
Right, right.
The system's got to be, like, in a place to receive it in the first place.
Exactly.
Yeah.
So you kind of taunted the audience a little bit with this thing you called pip.app.
And you're like, okay, here's how we're going to deploy it.
We're going to run this thing called pip.app.
We're going to select our program.
We're going to select our dependencies.
We'll, you know, choose the operating system and we'll just package this puppy up, right?
Yeah.
And why can't we have it, right?
Like, this seems like a kind of almost obvious tool.
But it's, I think that one of the reasons that nobody's made such a thing is that it's, you have to care a lot about the general case.
And you have to care a lot about the end user experience.
And in the kind of open source world to scratch your own itch, you're never that end user, right?
You've already gotten to some point that's further down the line than just, like, I don't know what Python is.
But if we were thinking about making this in, like, a 1990s style desktop app where, like, a user finds your floppy disks in the store and can't talk to you after that, like, you'd better make it work just from the beginning.
And if we thought about it more like that, I think that people would end up having to Google for those confusing virtual end articles a lot less often.
And, you know, part of the problem is just that we don't have that many volunteers who are working on this stuff.
I think you're touching on a super important point.
And I've spoken to several people about this.
Like, you know, I sort of opened this section by saying if we could get the deployment, especially the client side UI style deployment better, it would just open up an entire new avenue of growth for Python and where we could really leverage apps.
And I was talking to somebody and said, look, this is a problem that is super important we need to solve.
And I said, well, it's just not a thing that I find people who do Python do very often.
We don't run into this problem.
And we don't run into this problem because it's so hard that we don't even consider doing this most of the time, right?
Exactly.
And it's really kind of sad because, in fact, it's not that hard.
And, like, 80% solutions exist for so many of these problems.
Yeah.
I mean, Dropbox is on, like, they always have that huge number.
I'm not sure what it is, like 10 billion computers or something.
They're running everywhere.
And that's a Python desktop app.
So clearly it's not going to, you know, wreck your company if you decide to use Python.
You know, they had to do some work to make that work.
And they made it work for them.
And I absolutely don't want to criticize Dropbox for not doing enough to help the open source community because they've definitely done tons of stuff.
Lots of really interesting work has come out of there.
But at the same time, like, if somebody else wanted to follow in their footsteps and make another Python app that would deploy to, like, a zillion machines, they'd kind of have to solve a lot of the same problems again in a different way because the Python ecosystem has moved quickly and has got a lot more and better tools than when Dropbox was first started.
So there's just problems.
The problem is everybody who's, like, really, really concerned about this problem is already too busy already.
Like, I gave this talk to try to help newer people to the community try to understand the problem because as we spent quite a while talking at the beginning of this show, I've already got a lot going on.
Like, I've got to, you know, keep the books for our customers and write software to automate financial stuff at work.
And then I come home and then I maintain Twisted and I maintain Climb and I maintain Track and I do all of this stuff.
And I, you know, try to keep the peace in the community and make sure the mailing list doesn't go down and keep our servers running.
And at the end of all that, I just don't have any time to start the fairly ambitious project to fix all of these problems.
Yeah. Well, and it doesn't sound to me, from what you described just now, that you individually have this problem, right?
And I feel like there needs to be, you know, a couple of major companies or a couple of major projects that are like, we need to build this app and ship it this way.
And we need to just fix the tooling to make it work for us and take the community along with us.
Yeah, I feel like it's the person who's going to have this exact problem is kind of hard to imagine.
Because if you want to ship a desktop app and you have interesting enough logic and enough investment in Python, there's lots of ways you can just do that today.
You can grab Pi to app and you can grab Pi to exe and you can work around the same seven bugs that everybody who uses them has to work around.
And eventually, after you've had a couple of professional programmers hammer on it for a few weeks, you'll have a deploy pipeline that works for you.
You put it into your continuous integration system and then you're good.
Right. Once you get around that, you make it work, then you forget how you even made it work, right?
Exactly. And then it's in your, you know, when you do something in your code that makes it stop working, then you notice and you back it out.
And this is actually one of the problems I didn't talk about in the Python talk was that one of the reasons this is so pernicious is that we don't tell users to start by deploying.
Because Python is so flexible and it's so empowering to just get in there and, you know, make a module and then make another module next to it and edit the first one to import the second one and then just change it and maybe even reload it on the fly.
There's all this cool stuff you can do with that and with Jupyter Notebook, just typing code into cells and never even put it into a module that by the time you have something you want to deploy,
you might have made a dozen mistakes about how you're loading resources or about how you're getting your code installed or the layout of your repository, right?
It's pretty easy to end up in a place where you can't even write a setup.py because all your modules are expecting to import stuff from like three different paths at the same time.
And at that point, you have to like back out of whatever weird structure you've got yourself into and then recreate something sensible.
And that's the point where you throw up your hands and go, I'm never going to ship this thing.
Like, I'm not going to rewrite my app or it's just not going to work for real apps or whatever, right?
So that's super interesting.
You're basically proposing that like if you know that you want to use Py2 app or Py2.exe or the cross-platform Py2 installer or Shakespeare's or some probably combination thereof,
like write your hello world and then create your hello.app and start building them up together.
Is that what you're proposing?
Yeah, I mean, I think for anybody who's out there who's thinking, I want to make a desktop app.
I want to make a mobile app.
I want to make a low-level system utility.
One of the categories we haven't talked about too much yet is just like if you're making a program that needs to like be a system control thing for Unix systems at a level lower than like Docker, right?
Like you want to write your own SSH server or something like that that like controls a system.
You also can't ship it as a Docker container because you need it to like live on the Debian or the Red Hat system.
So you need to ship it as a package.
So if you're in one of those categories and you're like, I want to ship this command line thing or GUI app and you're thinking, I'm definitely going to want this to have a GUI.
I'm definitely going to want this to ship as part of Homebrew.
I'm definitely going to want to ship this as a Debian package.
Whatever it is that your deployment target is, deploy your hello world to that target and get like Travis or some kind of continuous integration system to start running it for you and doing that build and making sure that it at least basically works.
Because it's really, really easy.
Once you've got that set up, once you've got that pipeline working, it'll pretty much keep working.
You might have the occasional problem where like some third party library has a weird like shared object that you need to install in some funny way.
But if you know that at that moment when you're adding that dependency or you're installing that tool, if it breaks right then, you could say, aha, I'm not going to use that.
Or I'm going to get in touch with their maintainers and say like, why is this broken?
As opposed to writing a big complicated app, getting everything all done, and then ramming headfirst into this brick wall of like, now how do I put this on somebody else's machine?
Because one of the things that you don't realize is you're making all kinds of decisions about how to get it to run on your machine.
And they seem like totally sensible, right?
You have icon.png and it's in the current directory.
So you just open up icon.png and you read it.
Except what's the current directory?
How do you know that it's in your git checkout?
Because your git checkout is not going to be there on your target machine.
So unless you're going to ship dev tools to everybody, you have to think about, well, where does that resource come from?
And that's exactly the kind of stuff that trips people up with packaging.
Yeah, that makes a lot of sense, actually.
I hadn't really thought about it that way, but it certainly makes a lot of sense.
I mean, it feels a little bit like, let's write 100,000 lines of code and then run flake 8 on it to find the problems.
Right.
Just the first time.
Exactly.
And a day before you ship, right?
Yeah.
Or another way to think about it is like, let's write 10,000 lines of code and we'll make sure that all unit tests pass, but we'll never run it.
Because we'll just assume that it'll work if we run it.
But of course, you run it that first time and it's like, oh, you forgot a couple of unit tests.
And your build pipeline is the same way.
So this is when I talk about pip.app, what I'm really talking about is not just like, let's make it easy, but let's make it the first thing you do.
So if there are bugs in it and there are problems with it, you're just doing it constantly.
So you notice when there's an issue.
Yeah.
I think that's really great advice.
So, you know, there might be a lot of people listening who don't, are not familiar with pip.app or pip.exe and how these things work.
Basically, you can take this pip.app utility.
So let's stick on the macOS for a moment.
And it will create, like kind of embed a Python runtime that you need, all the dependency packages that you need, your code and package it up in a way that looks just like Safari or something.
And users double click it and it can run.
Right?
Exactly.
Yeah.
And so they don't even necessarily, it doesn't even matter what version of Python they have, whether they have Python.
It's just, they get the app, it runs because it's a self-contained unit, like other runtimes like Go or certain Windows EXEs.
Yeah.
And this is exactly what I meant when I said that Python is not a deployment target.
Like macOS is the deployment target.
And the Mac says what you have to do to be an app.
And PyToApp just makes Python be that thing.
Right.
Here's your P list.
Here's your resources.
All that kind of stuff.
Exactly.
And it just bundles it up into the shape that macOS expects without any regard for like what else is on the system.
And really like Go is sort of famous for producing these static executables where they include all of your Go dependencies.
But oddly enough, Python is sort of in a better place for many operating systems than Go would be.
Because what Go lets you do is it lets you put all of your binary resources into one file.
But that's kind of a red herring.
The thing you actually need is to put it into the shape the operating system expects, which is almost never one file.
Windows is the one place that that's true.
But on Windows, there's a whole system for like tacking on resources into a .exe.
You can, I believe, Windows loads from the end of the binary.
So you can actually tack like you can, your binary can just be a zip file.
And then you stick the executable on the end.
And suddenly it works and it launches.
And I might be mixing that up.
I know that Unix is one way and Windows is the other.
And one's the beginning and one's the end.
But that kind of thing is like once you know how you want your app to run, it turns out that actually on Windows and on the Mac, you often need like shared libraries or DLLs or resources or things that can't be put into a single binary.
Like an app on the Mac cannot be a single binary.
It has to be at least an info.plist and an executable.
And practically speaking, you need a dozen other resources like icon files and other things.
And similarly, like even if you're just talking about command lines, right?
You think single file binary, you think, oh, that's really good for the command line.
That's really how I want to run my stuff is I just want to have this one binary.
And that can make the deployment process easier.
But how do people actually deploy stuff onto the command line on the Mac?
Do they like curl a binary in chamod plus exit?
No, they brew install it, right?
And homebrew has a whole complicated multi-file setup where the deployment target is homebrew.
That's a really interesting point.
In your little PIDA app graphic, you had the various targets.
And one was Ubuntu, one was Windows, one was macOS.
But another was a chocolatey install.
And one was a brew install.
And one was an aptitude package and things like that, right?
Yeah.
And each of these kind of defines its own deployment surface.
And the reason that you don't want to just be randomly curling some Go binary onto your system
is because that initial install is just one thing.
You've also got to have an update process.
And that update process probably has to be cryptographically signed or something.
Like somebody needs to be in charge of making sure there's a secure pipeline to
deliver it to all your users.
And then that has to run on a CDN to make sure you don't have too much load.
And by the time you're done with that, you've got JSON files that are describing your metadata
and hashes and all kinds of other stuff which don't fit into that one binary anymore.
So Go can kind of get you started.
And it can make a lot of parts of this pipeline easier.
But one of my favorite examples of this, which I don't think I mentioned in the talk
because I think I found out about it somewhat later, is Askinima, which is a website.
It's a really cool website for sharing like screencasts of terminals.
Have you ever used it?
No, no, I haven't.
But you have to put a link in the show notes for us so we can check it out.
Definitely.
But the idea is it's just this little thing.
It's like a social place where you can share your various like Emacs and VI sessions.
Nice.
That's awesome.
And when you do this, they have a local TTY recording tool, which they originally wrote
in Python.
And then, of course, because Python makes deployment hard, they rewrote it in Go from scratch.
And then they rewrote it again in Python because they just went to Python 3 and they shipped
it as a thing that you brew install because it turns out going to the single file Go binary
didn't really help solve their problems that much.
Right.
And, you know, Go is a lot lower level language.
So it didn't like there were a lot of things that they lost as well.
So by just kind of going straight to the never mind the single file thing, we just want to
make sure that this is brew installable.
It got to what their users really wanted, which is way to get it installed.
That's like easy to explain.
It doesn't require a lot of sysadmin knowledge to keep updated.
It doesn't require a studio.
Exactly.
Yeah.
You just type the brew install command.
And the killer thing about the way that the thing that people think they want when they
hear a single file is when you've got a Python install and you're doing like pip install
to get your tools installed.
The problem with that isn't that it's multiple files.
It's that it's sharing all kinds of files.
So you do a pip install A and then you do a pip install B.
And if you just need tools from A and B, they can conflict with each other.
So pip install B breaks A because they're all reading from the same location.
All their libraries are piled on top of each other.
And there's no dependency checker in pip, which makes sure that A isn't going to break.
The versioning metadata isn't fine grained enough for A to even know that it's going to
break when B gets pip installed.
So it's just too fragile to try to share all of this stuff between Python libraries.
It's not like a .so where you can have like a very, very strict binary interface.
That never, ever changes.
Like anything can change in any Python file anywhere and potentially break every user of
that library.
You pretty much need to do a full on test run of your application to make sure that it's
not going to break with a new version of a dependency.
So it's that sharing that becomes a really big problem.
Yeah.
And sometimes you can't even avoid that because you're using two packages.
They might both use a dependency, but they were built against different versions of that
dependency or something, right?
Exactly.
And there's nothing really wrong with that even.
That's the, when you describe the problem, it sounds like, oh, that one library really
should have ran its tests.
Shame on them.
But it's not really, it's, it's not their responsibility to make sure that whatever random
versions of libraries on your system happen to work, they have a continuous integration system
that says what they work with.
And so, you know, we've gotten a lot of improvements in the Python ecosystem for library developers
to put out more and more robust artifacts.
But that last mile of like, put the application together, packaging everything together.
One tool that I really like that I use a lot is Pipsy, pip S-I, which I don't think is actually
an acronym for anything, but I pretend that it stands for pip script installer.
What it does is you do Pipsy install HTTPIE, let's say, or Pipsy install Boto3 or AWS CLI
or something.
And it will install a new virtual env that contains just the scripts that come from that top level
package.
And it'll like symlink those scripts into a shared directory, but kind of hide the virtual
end from you.
So it's every single tool that you need is installed into a separate virtual end for
its own requirements installed into it.
It's still kind of a developer installation tool because you already need to have Python,
you already need to have virtual end.
There's like a little bit of setup that goes into installing Pipsy in the first place and
bootstrapping it.
But then once you've got it, at least your stuff doesn't break all the time.
Like, yeah, it lets you play with stuff more aggressively or without care, right?
Right.
It's isolated and it's kind of installed the way that it should be, which is that each
app has its own dependencies.
Because again, Python is not a platform.
The compatibility guarantees that a library can make in Python are not strict enough that
you can have users upgrading their own stuff and then thinking it's going to work afterwards.
Like you need to ship a user all of the libraries that you tested with.
Yeah.
That makes a lot of sense.
So one thing that you held up as a good example is Briefcase.
I think that Briefcase is headed in a really good direction.
I think that they, that project has set up some really good infrastructure in terms of
like how they think about the long-term solution to the problem in that they have great onboarding
for new contributors.
They show up at lots of events.
They had a great presence at PyCon.
And they also, so they're, they're playing the long game here.
They recognize that this is a very big complex problem.
That's going to require a lot of people to solve.
And that it's also multi-layered.
Like one of the parts of the Beware project is not just Briefcase, but Batavia.
And Batavia is this transpiler from Python byte or not transpiler.
It's a Python virtual machine written in JavaScript.
So that you can ship your PYCs into a web browser.
And that doesn't seem like it's really related to Briefcase at first, until you realize that
the vision that they're pursuing is ship Python anywhere, write all of your code in Python all
the time, which is really the vision that I'm also sympathetic to.
And, but unfortunately what that means is because they are taking this very long view of the problem,
it's probably not the thing that you would use like right now for everything.
It does have some really great iOS build templates.
If you were going to do a mobile app in Python, it's probably the best place to start.
Yeah, I agree with that.
They, Russell Keith McGee did a, a bunch of the build work on Pythonista.
So I don't think that Pythonista, that the iOS app that runs Python is itself like straight up
deployed with Briefcase, but it shares a lot of that same technology.
And so there's kind of a, at least a proof concept that it can work really nicely.
I don't know if you've played.
Yeah, I've played with Pythonista.
It's a cool app for sure.
It's basically, it's a Python editor and runtime for iOS.
Maybe also an Android.
I don't know about Android.
I'm pretty sure it's just iOS.
Yeah.
Which it's impressive to me that that's even possible given all the restrictions that Apple
puts on executables.
Yeah.
I mean, they probably wouldn't like it if you started shipping apps to people in the form of
like that really, really long base 64 encoded.py files.
There is some tooling to actually help you write an iOS app inside Pythonista on iOS.
You do need to like have a Mac to kind of bounce your project off of because you need to do the
build of an iOS app on a Mac.
Yeah.
But I've done that.
I've downloaded the templates and like made a little hello world out of the scripts that come
on Pythonista, which is actually kind of another interesting reflection of the same problem from
a different direction, which is that Pythonista does not have any equivalent to pip.
So it's actually very hard to write full apps that take advantage of the Python ecosystem because
you can't, your build pipeline can't include that kind of like, and install this requirements.txt file
first.
Python's less fun when you, you have no import.
Yeah.
I mean, Pythonista kind of cheats a little bit because it just gives you a thing that like
already includes like requests and like NumPy and some pretty big chunks of SciPy, I think
are also in there.
So it's, it's just kind of like, ah, here's about a third of the interesting stuff in the
Python ecosystem.
Just in a big box.
But yeah, the, the idea that like you can grab this, you know, from the, the staggering ecosystem
that Python has to provide for you.
That's really what makes this interesting because if you're just going to write an app, you know,
do it in a Swift playground and then, you know, copy the Swift code to a Mac and write all of
that yourself.
It's not that much different than Python.
Like Python might be a little nicer, but once you can pull in stuff, like you can pull in
Jupyter or something like that and you can have like live introspection of your objects
in your app or you can pull in something like NumPy and have that tremendously powerful numerical
library at your disposal, it starts to make the investment in Python kind of make sense.
Yeah.
Yeah, it definitely does.
I think Swift is a fine language.
I just think their equivalent of the standard library is really, really not, not a great story.
It's pretty bare bones.
Yeah.
But, but, you know, Python, the way Python can compete with that is by
being yet more robust in the library ecosystem and not by kind of cutting itself off at the
knees and saying like, here's a really streamlined deployment experience that only works if you
write all of your code yourself.
All right.
Yeah, absolutely.
We definitely don't want, I want to see that.
So, Cliff, this is a bunch of great advice and hopefully a lot of inspiration for, for people
that, like you said, go that last mile to kind of close the gap and make this really sweet
deployment story.
Well, I certainly hope that, folks get inspired to go do that.
I think that, if you are kind of, if you feel like you're just a regular developer and
you don't feel like you could take on something this ambitious, going and helping out the Beware
folks, get briefcase into the kind of shape that it can just do a lot of this work
itself is probably the best way to help out the community at this point.
Yeah, I agree.
And they are, they have like basically a mentorship program for first time open source contributors
and they're very welcoming there.
So it's, it's a nice environment.
Definitely.
I think that that's one of the things that they, they might do better than almost any other
project I've seen is that they are really focusing on the people problems and making it
easy to get involved with the project and make a real impact quickly.
Yeah.
It's good to see they're working on this problem as well, cause they're doing cool stuff.
All right.
So I think we probably should leave it there for, for that, but let me ask you the two questions.
So we talked a lot about shipping Python code, but if you're going to write some Python code,
what editor do you use?
So we began with a story about my childhood and I feel it's only fitting to, to end on one
because I've heard you ask this question of a lot of people and they all give you an answer
and I have an answer, but I, I think it's important to reflect on where that comes from.
When I was 10 years old, my father sat me down and he said, you're going to grow up and
people are going to tell you that you should be a VI user or you should be an Emacs user.
And what I have to tell you is they're both wrong.
You need to do both editors because sometimes you're going to be SSH'd into some machine
that you have.
He probably said telneted, but you know, sign of the times.
Same basic thing.
You're going to be in on some console where you can't install anything and Emacs isn't there
and the environment's set up wrong.
And you're really going to want to know how to be able to exit VI.
And at the same time, like Emacs is this tremendously powerful library ecosystem of all kinds of
sophisticated stuff that you probably want to be able to leverage to be able to use like
an IDE.
So I actually learned pretty young, both Emacs and VI.
And I have tried to take that philosophy to heart in that I have a working Sublime Text
configuration.
I've been working on upgrading that to Sublime Text 3.
I haven't messed around with Adam too much yet, but I definitely intend to.
And my wife is a big proponent of Visual Studio Code.
So I feel like we should all learn to use editors in harmony.
Yes.
That said, Emacs is the best one.
And that's what I use.
That's a great story.
Thanks.
And a good answer.
All right.
And notable PyPI packages?
I'll throw a twisted out there for you straight away.
Yeah.
Actually, I wanted to talk about, I wanted to bring up one that we haven't already mentioned
in the course of this discussion.
And so I think Hypothesis is a package that I would really recommend people check out.
I haven't used it very much yet, but what Hypothesis is, is it's a generative testing framework.
So you kind of give it a piece of code that you want it to test, and then you give it some
variables, some ways that it can generate data or state for that code to be tested in.
And then you kind of fire it off, and it will figure out what's interesting to test about
your code in some ways.
I'm making it sound a little bit more magical than it is, but it lets you, like if you have
just a function that takes two numbers, and there are range limits on how those numbers
are supposed to relate to each other, like there's one case where they're equal to each
other, and there's one case where the first one's greater, and one case where the second
one's greater.
Hypothesis can, if properly set up, discover that those are the three things that you can't
three unit tests you need to write.
And there's like a whole bunch of values where it behaves one way, and a whole bunch of values
where it behaves a different way, but it'll kind of like minimize and do like a binary
search to find the interesting test cases for you.
And so I haven't, like I said, I haven't really used it myself yet, but I have been investigating
it, and it's kind of changed the way that I've thought about how tests can interact with
each other.
And I would, I know a couple of my friends have given it a spin on various kind of complex
testing projects, and it's really helped improve the reliability of their software a lot.
It's, it's found bugs in a way that like straight up unit testing generally doesn't.
Yeah, it's awesome.
I've definitely heard that as well.
And there's some amazing stuff hypothesis can do.
I actually had the David McIver on there on episode 67.
So quite a while ago, but talking about that there, and it's, I'm impressed with it as well.
And it pairs up with the other unit testing things.
Like you can use it with pytest or with Tox or whatever.
Yeah, it's really, it's a, it's kind of a power up for your tests.
It's not like a whole new testing system.
People have used it with Twisted's built-in TestRunner and as well as pytest and a whole bunch
of other ones.
Yeah.
So you touched on this just a little bit, but one more chance, final call to action.
You've got people caring about this deployment story.
What can they do?
Well, so aside from just like go help beware, the thing to do when you go help beware is
if you're the sort of person who has like a virtual machine or like the ability to spin
up new VMs, run a VM for some GUI operating system, whether it's macOS or Windows and pretend
you don't know anything about Python and you want to just write a little GUI application,
try to find a tutorial.
And in your fresh new VM with no developer tools installed, try to make an app that you
can run on a different VM also with no developer tools installed.
And the interesting thing about this is, well, the reason this is my final call to action
is if you do this, you will see all of the places that even if you yourself are only do
like web-based Python and don't do a lot of stuff with GUIs or desktop apps or mobile apps,
you will see all kinds of places where you know where the sharp edges are and you know exactly
what to do and it's not really written down anywhere and try to figure out how to take
that process to like the parts of the process that you understand that you know how to get
done the same way, the right way every time.
Blog about it, write about it, contribute to packaging.python.org that where there's documentation
for how to set up packaging and try to think of whatever you're trying to help with these issues,
whether it's Beware or just on your own blog. Remember where the actual beginning is and don't
just write tutorials for people who already have pip installed and already have Python installed and
already know the difference between Python 2 and Python 3. Just go back to the beginning and think
hard about what it would take for a total beginner to get started because there are a lot of total
beginners out there that do not have a friend to kind of shepherd them through that wilderness and I feel
like we're losing a lot of new Python programmers who if only that part were easy, they would be
coming to PyCon with us every year.
Yeah, absolutely. Well, that's a great thing for people to try. I totally think it would be helpful
to go through that whole exercise. All right, Cliff, thank you so much for being on the show. I really
enjoyed chatting with you.
It was a total honor to be here and see my name up in lights next to all those other luminaries that
you've interviewed.
I'm thrilled to put it up there. Thanks again.
This has been another episode of Talk Python to Me. Rollbar takes the pain out of errors. They give you the context
and insight you need to quickly locate and fix errors that might have gone unnoticed until your users complain,
of course. As Talk Python to Me listeners, track a ridiculous number of errors for free at
rollbar.com slash Talk Python to Me. Datadog gives you visibility into the whole system running your code. Visit
Talk Python.fm slash Datadog and see what you've been missing. Don't even throw in a free t-shirt for doing the
tutorial. Are you or a
or a colleague trying to learn Python? Have you tried books and videos that just left you bored by
covering topics point by point? Well, check out my online course,
Python Jumpstart by Building 10 Apps at talkpython.fm/course to experience a more engaging way to
learn Python. And if you're looking for something a little more advanced, try my WritePythonic code
course at talkpython.fm/Pythonic. Be sure to subscribe to the show. Open your favorite podcatcher
and search for Python. We should be right at the top. You can also find the iTunes feed at /itunes,
Google Play feed at /play, and direct RSS feed at /rss on talkpython.fm.
This is your host, Michael Kennedy. Thanks so much for listening. I really appreciate it.
Now get out there and write some Python code.
Thank you.