WEBVTT

00:00:00.001 --> 00:00:05.120
Python is growing incredibly fast, and it's found its place in many facets of the developer and

00:00:05.120 --> 00:00:10.520
computational space. One area that is still shaky and uncertain is packaging and shipping software

00:00:10.520 --> 00:00:15.900
to users. I'm not talking about building reusable libraries and hosting them on PyPI. I'm talking

00:00:15.900 --> 00:00:21.100
about shipping executable software to non-developers. Take a moment and stop and think about the ways

00:00:21.100 --> 00:00:26.320
you would send an end-user a program built with Python that they can simply run. It's a bit of a

00:00:26.320 --> 00:00:31.120
mixed bag, isn't it? On this episode, we welcome back Christian Medina to run through the state of

00:00:31.120 --> 00:00:38.040
Python packaging. This is Talk Python To Me, episode 245, recorded November 21st, 2019.

00:00:38.040 --> 00:00:56.280
Welcome to Talk Python To Me, a weekly podcast on Python, the language, the libraries, the

00:00:56.280 --> 00:01:00.860
ecosystem, and the personalities. This is your host, Michael Kennedy. Follow me on Twitter,

00:01:00.860 --> 00:01:05.560
where I'm @mkennedy. Keep up with the show and listen to past episodes at talkpython.fm,

00:01:05.560 --> 00:01:10.640
and follow the show on Twitter via at Talk Python. This episode is brought to you by Tidelift and

00:01:10.640 --> 00:01:14.240
Linode. Please check out what they're offering during their segments. It really helps support

00:01:14.240 --> 00:01:17.200
the show. Chris, welcome back to Talk Python To Me.

00:01:17.200 --> 00:01:19.060
Hey, thanks. How's it going? It's been a while.

00:01:19.060 --> 00:01:25.800
It has been a while. It has been since the summer of 2018, so not quite two years, but it's definitely

00:01:25.800 --> 00:01:30.920
been a while since you were on. Previously, you were on to talk about continuous integration,

00:01:30.920 --> 00:01:33.800
continuous delivery with Python. That's right.

00:01:33.800 --> 00:01:38.520
And you know, that was a really popular episode, actually. I thought the topic would be popular,

00:01:38.520 --> 00:01:43.960
but you came across with all these little tools and techniques that people just loved. And so,

00:01:43.960 --> 00:01:47.900
yeah, it was really great. And we'll probably learn some more about cool tools and techniques

00:01:47.900 --> 00:01:48.620
this time around, too.

00:01:48.620 --> 00:01:54.280
Yeah, sure. It was a good episode to kind of get everything plugged together and a nice little

00:01:54.280 --> 00:01:57.860
summary for all that. So, yeah, anybody that's interested, it's a good one.

00:01:57.860 --> 00:02:03.420
So, let's maybe fill people in on what you've been up to lately, day to day.

00:02:03.420 --> 00:02:04.020
Sure.

00:02:04.020 --> 00:02:07.600
You were on the software development side, but it sounds a little bit like you're also on the testing

00:02:07.600 --> 00:02:13.580
and process, making sure stuff works for the folks around you, like that they don't build bad software

00:02:13.580 --> 00:02:13.900
as well.

00:02:13.900 --> 00:02:19.020
Yeah. So, when we recorded that last episode, yeah, I was mostly doing development side,

00:02:19.020 --> 00:02:24.940
but I was in a small team, so I was tied into everything, QA builds and everything. But since then,

00:02:24.940 --> 00:02:31.260
I've transitioned to a different organization and I'm mostly doing QA now. So, QA tooling,

00:02:31.260 --> 00:02:37.000
which still involves build stuff, but not really developing a product, more developing tools to

00:02:37.000 --> 00:02:39.420
help test and release code.

00:02:39.420 --> 00:02:44.360
That's cool. So, you're basically in the developer tool space, but internally for your company,

00:02:44.360 --> 00:02:47.820
not like JetBrains or Microsoft or something like that.

00:02:47.820 --> 00:02:52.380
Right, right. And I've done that in my career a lot. I actually like it because I can walk over

00:02:52.380 --> 00:02:56.560
and talk to my customers and tell them, did you like this? And they were like, no, it sucked.

00:02:56.560 --> 00:02:57.640
Okay, so I'll go fix it.

00:02:57.640 --> 00:03:03.740
That is a super cool feeling. I've worked in small offices where basically the users of the software,

00:03:03.740 --> 00:03:10.060
they were a few offices or a little lab space down. And it was like, all right, what we need

00:03:10.060 --> 00:03:14.900
for next week is this. Come back three or four days later. This is what I've built. I know you

00:03:14.900 --> 00:03:19.060
asked for this, but I think this part can be automated too. What do you think about it?

00:03:19.060 --> 00:03:23.180
Like either like, oh, that's amazing or no, what were you doing? Like, of course you can't do that.

00:03:23.180 --> 00:03:27.120
And so on and so on. Yeah. It's that quick feedback loop is pretty cool.

00:03:27.120 --> 00:03:32.340
Yeah. It just helps you produce something productive for people that'll help their productivity.

00:03:32.340 --> 00:03:32.960
Yeah.

00:03:32.960 --> 00:03:38.720
Yeah. Yeah. Cool. So, well, that sounds really fun. And, also related a little bit to what

00:03:38.720 --> 00:03:39.920
we're going to be talking about now.

00:03:40.320 --> 00:03:46.620
Yeah. Slightly. Slightly. Yeah. So I want to start really high level with our conversation.

00:03:46.620 --> 00:03:52.340
So the idea is we're going to dig into some of the options for packaging Python applications.

00:03:52.340 --> 00:03:58.160
And I think before we even dig into the details of how we do that, some of the cool tools

00:03:58.160 --> 00:04:05.020
that are out there, honestly, I think we have to define what the heck that means. And it's not

00:04:05.020 --> 00:04:10.940
because we just need to be precise, but I think some different people, they have vastly different

00:04:10.940 --> 00:04:16.280
expectations and needs and some tools completely solve that. And if your, your desire is different,

00:04:16.280 --> 00:04:24.300
it's completely broken. Like imagine I want to get my web app onto a server to run consistently.

00:04:24.300 --> 00:04:30.620
Maybe Docker and Kubernetes is the perfect answer. If I have a accounting application,

00:04:30.620 --> 00:04:35.520
I want to give to accountants running a Kubernetes cluster is not the right answer, right? Like these

00:04:35.520 --> 00:04:41.080
are really, really different. So maybe what are some of the definitions and like of what packaging

00:04:41.080 --> 00:04:43.720
might mean for different people? What's the spectrum out there?

00:04:43.720 --> 00:04:47.400
Right. So even in the org I'm in right now, we actually have this problem because we have a wide

00:04:47.400 --> 00:04:53.980
range of tools, right? So if you're building a bunch of services with REST APIs to help you

00:04:53.980 --> 00:05:00.240
deliver something to that's remote or let's call it cloud-like to people, right? That might,

00:05:00.240 --> 00:05:05.900
like you said, that's something you might want to package as a Docker container, as a service running

00:05:05.900 --> 00:05:15.260
on a server, which is a different deliverable than say a double click this icon here, desktop application

00:05:15.260 --> 00:05:21.720
that you'd want to deliver if you're wanting to say, create a log viewer for somebody to help them

00:05:21.720 --> 00:05:23.980
process that information, right? Right.

00:05:23.980 --> 00:05:29.360
Which then is completely different from some utility where you just want to provide a quick library

00:05:29.360 --> 00:05:37.660
for other people to write more code using your library, right? And all that you'd want to deliverable

00:05:37.660 --> 00:05:43.480
for all of that would be different and something that makes more sense to the user in the environment

00:05:43.480 --> 00:05:45.100
that they're in because they're all different environments.

00:05:45.100 --> 00:05:51.620
Yeah, absolutely. Like I suspect you're kind of on the border at work, right? Because you are working

00:05:51.620 --> 00:05:58.080
with developers. So it's probably reasonable to say, well, there's a REST endpoint or there is a command

00:05:58.080 --> 00:06:01.720
line tool. You type this in the command line and magic happens.

00:06:01.720 --> 00:06:07.840
Right. So the REST endpoint, easy, right? So there's this GUI uses some REST API and you can track your

00:06:07.840 --> 00:06:12.800
execution of your tests, for example, right? And then you can see how things are going. But when you're talking

00:06:12.800 --> 00:06:19.260
about the actual test you wrote, then that needs a library for you to access the infrastructure

00:06:19.260 --> 00:06:25.020
and a bunch of services in that infrastructure that might relate to just stuff you need, requesting

00:06:25.020 --> 00:06:30.760
resources for testing or using other, you know, integrating with other tooling that will help you

00:06:30.760 --> 00:06:36.860
with that, right? Which is then completely different from some utility that'll tell me, give me the list

00:06:36.860 --> 00:06:43.340
all my compute that I have available to run tests on, right? Yeah. And then that utility needs to run

00:06:43.340 --> 00:06:47.860
on every developer's machine. And then how you distribute that starts getting complicated.

00:06:47.860 --> 00:06:50.780
Yeah. And do you help these developers that you're working with? Do you help them

00:06:50.780 --> 00:06:55.360
distribute their tools, maybe to more end user type folks?

00:06:55.480 --> 00:07:01.060
Not so much. Some of the libraries that the organization runs are or might soon be open

00:07:01.060 --> 00:07:06.440
sourced. So we might wind up using IPI and GitHub to distribute some of that stuff. Internally,

00:07:06.440 --> 00:07:11.680
we have like internal private IPI repos and Docker registries and things like that today.

00:07:11.680 --> 00:07:15.440
Okay. Yeah. Yeah. Very cool. All right. Now I'm going to throw out as part of this high level

00:07:15.440 --> 00:07:21.780
discussion, an idea. I don't know if it's popular or not. It's not super positive, but I do want to kind

00:07:21.780 --> 00:07:28.120
of start there because I think this is a pretty serious issue. And I'm going to say that Python's

00:07:28.120 --> 00:07:32.580
in this broad sense that we've set it up, not necessarily like virtual environments and like

00:07:32.580 --> 00:07:38.700
pip install, but in the broad sense, Python's packaging of for applications in particular,

00:07:38.700 --> 00:07:41.320
it's fairly broken. How does that say with you?

00:07:41.320 --> 00:07:48.240
There's definitely a number of areas that need improvement, mostly because of the part of the

00:07:48.240 --> 00:07:53.760
problem is that we just have so many different ways of distributing say virtual environments or

00:07:53.760 --> 00:07:59.880
just the packages themselves or just putting the code together and giving it out to somebody.

00:07:59.880 --> 00:08:06.400
And part of it is good because just Python is flexible enough for you for allowing you to

00:08:06.400 --> 00:08:11.380
build whatever makes sense for your org, right? And then everybody puts it out there and then some

00:08:11.380 --> 00:08:16.700
people use it, some people don't. But if we had the one official supported thing that goes beyond

00:08:16.700 --> 00:08:23.200
just pip install because pip install involves a pre-existing Python executable, which is when

00:08:23.200 --> 00:08:24.300
things start getting complicated.

00:08:24.300 --> 00:08:30.500
Exactly. You've got to have a well-known, somewhat decent environment. You've got to have a certain

00:08:30.500 --> 00:08:36.420
version of Python or a range of version. It's got to be over 3.5 or say over 3.6 if you're using

00:08:36.420 --> 00:08:42.400
f-strings or whatever version it has to be. That has to all be in place and set up.

00:08:43.360 --> 00:08:48.800
Even when that works, it's usually difficult to give somebody an icon to double click to make their

00:08:48.800 --> 00:08:56.860
app go, right? Like, why is my thing not like Firefox? Well, you see, there's all these rules. Let me tell

00:08:56.860 --> 00:09:02.420
you about dependencies. Nobody wants to hear that, right? They want to go, I want the icon that I click.

00:09:02.660 --> 00:09:08.100
Yeah. It gets even more complicated once you're distributing compiled code along with it, like some

00:09:08.100 --> 00:09:13.300
of the machine learning stuff or whatnot, which is why you see all these alternative systems like,

00:09:13.300 --> 00:09:17.060
say, Anaconda exists to just help with that, right?

00:09:17.060 --> 00:09:22.640
Right. Yeah, yeah. That's a good point. That is sort of why Anaconda exists. I mean, it also focused a

00:09:22.640 --> 00:09:26.860
little more on the developer side, but right, it kind of tries to solve some of the challenges of how do I

00:09:26.860 --> 00:09:34.360
get some of the foundational bits in place for the developer users, right? Yep. So there was, here's a

00:09:34.360 --> 00:09:43.540
quote from the PyOxidizer page. So Greg, I believe, is on board with this idea. And this is from Russell

00:09:43.540 --> 00:09:51.540
Keith-Magee's PyCon 2019 keynote talk. So he's on idea. He's on board with this idea. But he gave a talk

00:09:51.540 --> 00:09:58.060
basically about these black swan events for Python. Are you familiar with this idea? Did you see his talk?

00:09:58.060 --> 00:10:03.400
Yep. And it was discussed in a couple episodes. I think you guys talked about it probably in a Python

00:10:03.400 --> 00:10:08.640
bytes episode before as well. Yeah, I do think we might have done that. Yeah. Yeah. So the idea of the

00:10:08.640 --> 00:10:15.240
black swan event roughly is like this thing that is very rare that people don't see coming in an

00:10:15.240 --> 00:10:23.620
ecosystem and society and cycles, whatever, that are potentially existentially critically bad,

00:10:23.620 --> 00:10:30.160
right? So the original example was something like a turkey thinks the farmer loves them. Every day,

00:10:30.160 --> 00:10:36.460
the farmer comes in and greets them, treats them really well. Feeds them. Yeah, feeds them. And nobody saw

00:10:36.460 --> 00:10:42.880
Thanksgiving coming, right? Something like that or, you know, things along those lines. I guess maybe

00:10:42.880 --> 00:10:49.100
another one might be traditional photography and Kodak and digital cameras, right? Like that might like

00:10:49.100 --> 00:10:55.820
nobody saw that coming in the sense, like well enough, I guess. I'll give you one more with server

00:10:55.820 --> 00:11:02.820
development and the commoditization of that and what happened with the larger manufacturers when

00:11:02.820 --> 00:11:07.380
all the cloud companies started to develop their own servers. Yeah, probably first they're like,

00:11:07.380 --> 00:11:12.200
you know what? It's no big deal that there's all these cloud hosting places because they're just

00:11:12.200 --> 00:11:15.460
going to buy our servers and put them in their data centers and we'll be fine until they said,

00:11:15.460 --> 00:11:19.900
you know what? We could do better on efficiency and our biggest cost is electricity. So thanks,

00:11:19.900 --> 00:11:26.540
but no thanks. Yeah, exactly. Yeah. Yeah. So Russell Keith-Magee said there are a couple of things that he

00:11:26.540 --> 00:11:33.820
believes are these black swan type of threats for different parts of Python, right? He loves Python,

00:11:33.820 --> 00:11:39.340
but like what might undo this great success that Python has had over the last couple of years and

00:11:39.340 --> 00:11:45.140
one of them is definitely about packaging. Yeah. Look, I believe some of the others, there was mobile,

00:11:45.140 --> 00:11:50.760
there was packaging and there was a few others, but those are the two that really stood out to me.

00:11:50.760 --> 00:11:53.380
It was like, you know, people who are coming into programming,

00:11:53.540 --> 00:11:57.960
why would they come into Python if they can't take the cool little app they built and share it with

00:11:57.960 --> 00:12:01.000
their friends, right? They're going to do it in JavaScript or they're going to do it in something

00:12:01.000 --> 00:12:06.140
else where they can package it up and share their game or whatever, right? Exactly. Yeah. So that's

00:12:06.140 --> 00:12:10.580
why I think this is a big challenge, right? I think it's important. It's also tricky, but I think it's,

00:12:10.580 --> 00:12:15.180
I do think it's really important. Also, you probably heard me go on and on about like building GUIs in

00:12:15.180 --> 00:12:19.420
Python, right? Like this is another, another one. And I've done my GUI thing too. So yeah. Yes,

00:12:19.420 --> 00:12:23.280
you have. That's right. You gave a talk at PyCaribbean about it. That's cool. And

00:12:23.280 --> 00:12:29.300
I think one of the reasons people don't build more desktop applications and GUI applications in Python

00:12:29.300 --> 00:12:34.620
is because one, yeah, there's a, there's a little bit of a gap in the tooling there, but things like

00:12:34.620 --> 00:12:41.240
cute and what, whatnot, they're actually quite decent. Cocoa touch and not Cocoa touch, but some of the

00:12:41.240 --> 00:12:49.660
PI OBJC or whatever, the wrappers around the Cocoa APIs, those are probably pretty much okay. But

00:12:49.660 --> 00:12:54.920
even once you build those, then you come back to this packaging problem that we're talking about here.

00:12:55.680 --> 00:13:01.020
I think it's, it's so much of a problem that people don't put any energy to build out the GUI apps,

00:13:01.020 --> 00:13:05.200
the GUI capabilities, because heck, once you build them, it's, you still can't really give them to

00:13:05.200 --> 00:13:10.420
anybody in like a super decent way. So why, why bother building, like, you're just going to build a web

00:13:10.420 --> 00:13:15.600
app or, or whatever. I think there's a bit of a chicken and egg problem where like people don't work on

00:13:15.600 --> 00:13:20.820
trying to distribute their application because it's so hard to build the type of applications that get

00:13:20.820 --> 00:13:25.960
distributed. So like, it's just kind of like, it's a little anemic in that space. So what I'm trying to

00:13:25.960 --> 00:13:26.140
say.

00:13:26.140 --> 00:13:32.580
No, no, I'm with you. And, and even, so when I said like, I did my GUI thing. And so I have my attempt

00:13:32.580 --> 00:13:36.960
at a GUI framework where I went through the analysis or what you're just talking about. And I

00:13:36.960 --> 00:13:43.320
just pretty much just gave up and said, well, the web one, we can just make our GUIs in the web.

00:13:43.320 --> 00:13:48.380
Let's figure out how to do that a little bit easier and just go down the Chromium distribution

00:13:48.380 --> 00:13:53.240
kind of electron JS equivalent to do everything. And then everybody just gets a web browser,

00:13:53.240 --> 00:13:58.420
which is cool that that works. But then when you start thinking about the, what else you're

00:13:58.420 --> 00:14:02.540
distributing with your application, just to do a simple GUI or whatever, like an entire web browser

00:14:02.540 --> 00:14:05.340
or whatnot, then just seems kind of wasteful as well. Yeah.

00:14:05.340 --> 00:14:11.340
Yeah. Yeah. I do think actually that might be something that happens for Python, something

00:14:11.340 --> 00:14:16.140
like electron, right? That's actually really totally possible. And the WebAssembly stuff

00:14:16.140 --> 00:14:19.280
could make that really interesting as well. If you could package up the runtime as a web

00:14:19.280 --> 00:14:22.300
assembly and just drop that with your, your electron distribution.

00:14:22.300 --> 00:14:26.580
I managed to do it. It works. I'm not using electron itself. I'm just using the stuff that

00:14:26.580 --> 00:14:29.120
electron uses in the backend. So it's all totally possible.

00:14:31.120 --> 00:14:36.260
This portion of Talk Python To Me is brought to you by Tidelift. Tidelift is the first managed

00:14:36.260 --> 00:14:40.660
open source subscription, giving you commercial support and maintenance for the open source

00:14:40.660 --> 00:14:46.380
dependencies you use to build your applications. And with Tidelift, you not only get more dependable

00:14:46.380 --> 00:14:50.720
software, but you pay the maintainers of the exact packages you're using, which means your

00:14:50.720 --> 00:14:55.740
software will keep getting better. The Tidelift subscription covers millions of open source projects

00:14:55.740 --> 00:15:00.980
across Python, JavaScript, Java, PHP, Ruby, .NET, and more. And the subscription includes

00:15:00.980 --> 00:15:06.280
security updates, licensing, verification, and indemnification, maintenance and code improvements,

00:15:06.280 --> 00:15:11.500
package selection and version guidance, roadmap input, and tooling and cloud integration.

00:15:11.500 --> 00:15:16.760
The bottom line is you get the capabilities you'd expect and require from commercial software.

00:15:16.760 --> 00:15:22.920
But now for all the key open source software you depend upon, just visit talkpython.fm

00:15:22.920 --> 00:15:25.200
slash Tidelift to get started today.

00:15:26.900 --> 00:15:33.680
All of this conversation sort of started from this, it's almost like a retrospective on a journey

00:15:33.680 --> 00:15:40.180
that you went on. This blog post that you wrote, four attempts at packaging Python as an executable.

00:15:40.180 --> 00:15:45.340
I'll put the link for that original article over there. So maybe just tell us a little bit about

00:15:45.340 --> 00:15:50.320
what that was all about in the journey and then we can dive into some of the details that we pulled

00:15:50.320 --> 00:15:56.040
out of there. Sure. So in the, even in the previous episode, when I was working on mostly CI/CD stuff,

00:15:56.040 --> 00:16:03.340
as part of that CI/CD system, there's a, you know, you need to execute some code inside it to like keep

00:16:03.340 --> 00:16:09.520
your process going. Right. And one of the limitations I had at the time was that the containers that I was

00:16:09.520 --> 00:16:14.560
using required Python to be installed in it. And I wanted to remove that dependency. I knew it was

00:16:14.560 --> 00:16:20.060
possible to compile my code down to an executable. I wanted to figure out what, what method worked for

00:16:20.060 --> 00:16:25.500
me. And I tried, I didn't have a lot of time. So I tried four systems, which at the time was

00:16:25.500 --> 00:16:35.240
Cython, PyInstaller, Nutka and PyOxidizer. Right. And each one had, you know, I fumbled through most of

00:16:35.240 --> 00:16:38.700
them and, and, you know, I'd use PyInstaller before. For simple cases, you could get it to work,

00:16:38.700 --> 00:16:42.880
right? Like Cython, you sort of got it to work, but only for a simple app. Yeah, exactly.

00:16:42.880 --> 00:16:47.880
I got what I wanted. It works pretty well. It's been in production for my side of the world for a

00:16:47.880 --> 00:16:52.860
while. So I'm, I'm happy with it. But yeah, so out of that came, you know, this analysis of where we're

00:16:52.860 --> 00:16:58.720
at with like how to turn your Python script into a double click executable kind of thing.

00:16:58.720 --> 00:17:04.100
Yeah. And I definitely think it depends on what level you need to be at, right? If you're building

00:17:04.100 --> 00:17:08.820
a tool for fellow developers, that's one thing. If you're building a tool, like I said, for accountants

00:17:08.820 --> 00:17:15.400
or lawyers, exactly. They expect something to put next to their word icon in their macOS doc or

00:17:15.400 --> 00:17:21.540
whatever, like that's a different type of thing. Right. So let's go through it. I guess we've got

00:17:21.540 --> 00:17:28.980
it broken up into some, some nice taxonomy here. Let's talk about delivering an application first.

00:17:29.380 --> 00:17:35.660
Yeah, sure. So just to give the overall taxonomy a little bit, right? We have three things based on

00:17:35.660 --> 00:17:42.060
what deliverable, what your end goal is from having this Python package, this distribution to your end

00:17:42.060 --> 00:17:48.000
user, right? And we have the idea of putting it together as an application that you run or putting

00:17:48.000 --> 00:17:53.920
it together where you just distribute a virtual environment with it, or you just give out a specific

00:17:53.920 --> 00:17:59.500
executable. And then there's some other things along with it that we talk about later. But if you want

00:17:59.500 --> 00:18:04.780
to deliver an application or a service type of application, one of the best things to use these

00:18:04.780 --> 00:18:11.820
days is Docker. I've used it successfully to run pretty much everything Python related. And in fact,

00:18:11.820 --> 00:18:17.580
there's an official Docker image that you can run that's based on Debian, I believe. And I use that in

00:18:17.580 --> 00:18:19.440
my automated testing all the time.

00:18:19.640 --> 00:18:22.960
That's supported by the PSF. I've learned, right? That's pretty interesting.

00:18:22.960 --> 00:18:27.980
Somewhere in the Python builder, a little bit after that comes an official Python Docker image

00:18:27.980 --> 00:18:29.900
that you can just pull from and use.

00:18:29.900 --> 00:18:34.260
Yeah, that's cool. Docker is cool. But it makes me a little bit nervous because you're taking like

00:18:34.260 --> 00:18:40.720
layers of customized operating system that maybe different people have, you know, changed or built

00:18:40.720 --> 00:18:45.900
on stuff. And then, you know, how sure are you that those are not, you know, that somebody hasn't

00:18:45.900 --> 00:18:50.300
slipped something in there. I think the Docker files are maybe a safer bet, of course, right?

00:18:50.300 --> 00:18:53.980
To just like build it yourself rather than to download the full container.

00:18:53.980 --> 00:18:56.440
But you still need to start from an image, right?

00:18:56.440 --> 00:18:56.580
Yeah.

00:18:56.580 --> 00:19:01.160
So if you start from, say, some official distribution of something like the Python one,

00:19:01.160 --> 00:19:05.800
but just the same, there's like all kinds of other images from Postgres, Ubuntu, MySQL,

00:19:05.800 --> 00:19:09.800
whatever that you can use. You can, you know, slowly build up with your Docker file,

00:19:09.800 --> 00:19:11.780
whatever dependencies it is that you need.

00:19:11.780 --> 00:19:16.460
Now, the advantage of this is that you're distributing all the dependencies for your

00:19:16.460 --> 00:19:23.560
operating system along with the Python executable that you need along with your actual application,

00:19:23.560 --> 00:19:23.960
right?

00:19:23.960 --> 00:19:24.300
Yeah.

00:19:24.300 --> 00:19:29.780
That makes the, it worked on my machine problem go away, essentially.

00:19:29.780 --> 00:19:37.060
I do think Docker is a pretty cool solution. If having Docker running on your operating system,

00:19:37.060 --> 00:19:41.360
it's not a big deal to you, right? You've already got the desktop Docker or whatever.

00:19:41.660 --> 00:19:43.600
Or it's installed on your server.

00:19:43.600 --> 00:19:44.260
Right.

00:19:44.260 --> 00:19:48.660
Then this is a pretty solid way, certainly to deliver like services and stuff.

00:19:48.660 --> 00:19:54.020
If it's just a matter of pulling it down and say, you know, Docker run this container or whatever,

00:19:54.020 --> 00:19:54.980
then it's, it's okay.

00:19:54.980 --> 00:20:01.400
Yeah. I've also come across a couple of applications, I would call them that where you,

00:20:01.400 --> 00:20:06.460
you run a CLI and the, your interface is the CLI, but in the backend of CLI,

00:20:06.460 --> 00:20:10.760
Docker runs something for you. So it all runs in its own little contained environment.

00:20:10.760 --> 00:20:11.940
And then just exits.

00:20:11.940 --> 00:20:18.120
Yeah. One of the slicker instances of this was from Gigantum. Are you familiar with them? They're pretty new.

00:20:18.120 --> 00:20:18.380
Nope.

00:20:18.380 --> 00:20:22.320
So I just had them on the show three or four episodes ago, not very long ago.

00:20:22.960 --> 00:20:23.400
Okay.

00:20:23.400 --> 00:20:28.840
And basically what they are is they are like a collaboration environment for data science.

00:20:28.840 --> 00:20:38.440
So they distribute their application to you as a Docker container. And then each environment you create starts from one of these containers as well.

00:20:38.580 --> 00:20:45.660
So either it's like an Anaconda pre-configured container or it's a, you know, just a bare one with Python or whatnot.

00:20:45.820 --> 00:20:51.980
But yeah, it's really cool that the PS has enough PSF has an official Docker container. Cause I didn't, I didn't realize it. That's great.

00:20:51.980 --> 00:20:54.200
Yeah. Yeah. It really does help it along.

00:20:54.200 --> 00:20:59.000
Yeah. The other thing that can be tricky with Docker is you're trading that,

00:20:59.000 --> 00:21:05.820
well now set up this version of Python in this way for now make sure you expose these ports and the right way.

00:21:05.820 --> 00:21:12.780
And you map that volume over there. There's just like, there's still some friction to distribute and stuff as a Docker container, right?

00:21:12.960 --> 00:21:21.920
Yes, that's correct. So if once your application, if you get like something that's really somewhat complicated and you need to have persistent data and things like that,

00:21:21.920 --> 00:21:32.520
then you got to worry about making the proper volumes or mapping the correct directories into it so that you can persist the data outside the container or even access it without having to get into the container.

00:21:32.900 --> 00:21:43.740
And then when you have to do things like when you depend on networking in some way, like if say you're running HTTP server, then you need to make sure you pass in the right commands to open the correct ports for it to work for you.

00:21:43.740 --> 00:21:45.780
So that's some of the complications you get there.

00:21:45.780 --> 00:21:54.660
But it could get wrapped up, right? Like you don't, the example you pointed out where you don't really know that you're doing Docker when you're working with your CLI.

00:21:54.660 --> 00:21:59.360
It just happens to Docker behind the scenes to make things reliable. Like that's a pretty good use case.

00:21:59.360 --> 00:22:00.200
Yeah, I think so.

00:22:00.200 --> 00:22:05.180
Cool. All right. So another one that you have out there, which is maybe pre-Docker.

00:22:05.180 --> 00:22:06.240
Yes.

00:22:06.240 --> 00:22:10.660
I'm just going to give you a virtual machine and you can just run that.

00:22:10.660 --> 00:22:16.920
Yep. And along with that. And so like the original thing was, yeah, here's your virtual machine application, essentially.

00:22:16.920 --> 00:22:25.200
And you just, it starts an entire operating system that you can run in VirtualBox, but along as well as other virtual machine environments.

00:22:25.320 --> 00:22:32.520
But along with that came Vagrant, which was kind of like a Docker file for virtual machines, except before Docker files.

00:22:33.180 --> 00:22:40.920
And so you can sit there and say, oh, it's a VM. It's going to have this configuration for your network, for memory, CPU, whatever, file systems and whatnot.

00:22:41.240 --> 00:22:46.700
And spins up essentially a pre-configured OS, fully packaged OS for you.

00:22:47.040 --> 00:22:52.540
And now, of course, when you distribute a VM, you're distributing a whole OS.

00:22:52.720 --> 00:23:00.700
So it's going to be a large image that you're giving out, which is the difference with something like Docker, because it's a layered file system.

00:23:00.700 --> 00:23:06.200
Then you only need to, you only distribute the pieces that you're adding on top of some basic image.

00:23:06.200 --> 00:23:17.260
Any changes you make to that virtual machine maybe requires like a new 5 gig download, whereas a change or two Docker file might just, well, you just rebuild like the last layer of that Docker image.

00:23:17.580 --> 00:23:27.380
Yeah. And then you can find, like for the Docker side, you can find, you know, tiny OS images in the tens of megs versus a full VM, right?

00:23:27.380 --> 00:23:30.600
That'll be like probably a couple of gigs. You can get small VMs too.

00:23:30.600 --> 00:23:33.620
Yeah, a couple of gigs to start. Yeah, yeah, true.

00:23:33.620 --> 00:23:40.180
The other thing that seems like a challenge with the VM option is it's now your puppy.

00:23:40.740 --> 00:23:48.460
You've got to caretake it, right? So if it has a security vulnerability or something like that, then you've got to go in there and like patch it and whatnot.

00:23:48.460 --> 00:23:51.600
Right. Which you technically still have to do with Docker.

00:23:51.600 --> 00:23:59.780
But if you spin off your image on top of an existing one, for example, let's go back to the Python thing.

00:23:59.920 --> 00:24:09.320
If I have my application built on Python 3.6 and 3.7 comes out, I just need to change my base image to 3.7 and stuff just starts working on top of that.

00:24:09.320 --> 00:24:14.720
Right. Or you could just live a little bit out on the edge and do something like Ubuntu Python colon latest.

00:24:14.720 --> 00:24:15.760
Right. Exactly.

00:24:15.760 --> 00:24:22.100
Something like, right. Whatever's the latest. If there happens to be a new latest when I rebuild it, get the new latest and then give me that.

00:24:22.100 --> 00:24:26.900
That one's probably patched at the OS level and got the newer version of whatever in it.

00:24:26.900 --> 00:24:27.800
Right. Exactly.

00:24:27.800 --> 00:24:35.480
There's a risk that it's not 100% repeatable potentially, but things like Linux and Python, they're pretty backwards compatible.

00:24:35.480 --> 00:24:35.840
Yep.

00:24:35.840 --> 00:24:42.060
As opposed to I now have to log into my Docker images and patch them. That's another level of effort.

00:24:42.060 --> 00:24:44.320
Yeah, exactly. That's a lot more complicated.

00:24:45.000 --> 00:24:49.800
Usually, it's just considerably easier to just update the base image.

00:24:49.800 --> 00:24:50.720
Right, right, right.

00:24:50.720 --> 00:25:02.640
It's also a great little test thing, right? If you want to check whether your code works in 3.7 versus 3.5, for example, just start an image with 3.7 in it and you're done.

00:25:02.640 --> 00:25:04.800
Yeah, and run it through your CI and see what happens.

00:25:04.800 --> 00:25:05.660
Yep.

00:25:05.660 --> 00:25:13.040
Another thing that might be a benefit of the Vagrant VM style, though, could be background work, background jobs and whatnot.

00:25:13.400 --> 00:25:20.960
Like, Docker, typically, it has the Docker container, but then there's, like, the one thing it runs as its life, right?

00:25:20.960 --> 00:25:25.640
Like, there's not a system D in Docker that I'm aware of and things like that, right?

00:25:25.640 --> 00:25:28.880
Right. Depending on what you want to do, right?

00:25:28.880 --> 00:25:31.580
Because you can configure it to do whatever, pretty much.

00:25:31.580 --> 00:25:34.300
And there's, like, privileged containers, too, right?

00:25:34.300 --> 00:25:42.260
So, you got some limitations on your normal stuff, but you can also add other kernel privileges to it to help it communicate or create new devices and whatnot.

00:25:42.900 --> 00:25:49.320
And, yes, the process manager and service managers inside the container aren't there by default.

00:25:49.320 --> 00:25:51.960
So, if you want to do that, you get to configure it yourself.

00:25:51.960 --> 00:25:52.620
Right.

00:25:52.620 --> 00:25:58.560
Right, which is complicated, but it can be complicated, but it's also good because you get, like, a really base thing.

00:25:58.560 --> 00:26:01.200
So, if you don't need it, you don't have it.

00:26:01.200 --> 00:26:01.440
Yeah.

00:26:01.440 --> 00:26:05.560
One of the things that's cool about that, though, is you have all the control, right?

00:26:05.560 --> 00:26:06.500
That's correct.

00:26:06.580 --> 00:26:15.220
Once you set it up, it might be painful to set it up, create that Docker file that's just right, but once you got it, like, you put it in version control and you just forget about it, right?

00:26:15.220 --> 00:26:16.040
You just build on top of it.

00:26:16.040 --> 00:26:16.380
Yeah, exactly.

00:26:17.060 --> 00:26:17.300
Yeah.

00:26:17.300 --> 00:26:17.620
Yeah.

00:26:17.620 --> 00:26:17.680
Yeah.

00:26:17.680 --> 00:26:25.300
And you can have, like, a build container, for example, in version control just exists to build your code, for example, or package your code.

00:26:25.300 --> 00:26:25.920
Yeah.

00:26:25.920 --> 00:26:28.320
And then just gets destroyed afterwards.

00:26:28.320 --> 00:26:28.640
Yeah.

00:26:28.640 --> 00:26:28.820
Yeah.

00:26:28.820 --> 00:26:38.460
So, we've got these different container technologies, like, really big shipping container style, and then, like, the small, I don't know, Tupperware style with Docker and VMs.

00:26:38.460 --> 00:26:38.580
Right.

00:26:38.580 --> 00:26:41.080
But we also have, you know, things like PyInstaller, right?

00:26:41.080 --> 00:26:41.420
Yep.

00:26:41.420 --> 00:26:44.860
So, with PyInstaller, it has been around for a while.

00:26:44.860 --> 00:26:50.400
That's what I used to distribute the GUI stuff we were just talking about earlier.

00:26:50.980 --> 00:27:02.920
So, PyInstaller can take your Python application, like you pointed to your directory, and it can output fully installable application in both Linux, Windows, and Mac.

00:27:02.920 --> 00:27:09.900
So, in Mac, you'll get a .app, you know, in Windows, you'll get an executable, and for Linux, you'll get another executable file.

00:27:10.380 --> 00:27:23.480
I used it recently to do something simpler, which is what I discussed in my recent article, but I used it in the past to not only write a Python app that ran, say, a WebSocket server in it, right?

00:27:23.480 --> 00:27:30.920
It also included an entire Chromium browser along with it and got delivered almost like an Electron application.

00:27:30.920 --> 00:27:31.880
Yeah, that's super cool.

00:27:31.880 --> 00:27:32.120
Yeah.

00:27:32.120 --> 00:27:34.280
I do think PyInstaller is quite nice.

00:27:34.280 --> 00:27:39.120
It's been around for a while, but it seems to be, like, one of the go-tos that people are keeping around.

00:27:39.120 --> 00:27:39.460
Yeah.

00:27:39.740 --> 00:27:46.900
So, actually, after I wrote my post, I got a number of folks that pinged me when, like, talking about how great PyInstaller is, and they've been using it for a while.

00:27:46.900 --> 00:27:47.740
Yeah, yeah, super cool.

00:27:47.740 --> 00:27:53.000
This is pretty close to here's your executable you can have and run.

00:27:53.000 --> 00:27:54.240
Yeah, just double-click and go.

00:27:54.240 --> 00:27:56.100
Yeah, I've had pretty good success for it.

00:27:56.100 --> 00:27:58.880
I used GUI, you know, GUI, G-O-O-E-Y.

00:27:58.880 --> 00:27:59.620
Yep.

00:27:59.620 --> 00:28:05.480
I used GUI to build a little app, which was a super simple thing, and then I packaged it up with PyInstaller.

00:28:07.080 --> 00:28:11.020
And it was good except for it ran fine on Windows.

00:28:11.020 --> 00:28:13.320
Like, it had a .exe.

00:28:13.320 --> 00:28:14.600
It, like, had an icon.

00:28:14.600 --> 00:28:15.440
You double-clicked it.

00:28:15.440 --> 00:28:16.140
It did the thing.

00:28:17.080 --> 00:28:19.620
On macOS, I had a .app file.

00:28:19.620 --> 00:28:20.860
Mm-hmm.

00:28:20.860 --> 00:28:26.120
And you double-clicked it and did its thing, except for it also opened a terminal kind of off to the side.

00:28:26.120 --> 00:28:26.880
Oh, really?

00:28:26.880 --> 00:28:28.900
Which, for the life of me, I couldn't get it to go away.

00:28:28.900 --> 00:28:33.800
Like, the commands to make the terminal not show were obviously working on Windows, but not on Mac.

00:28:33.800 --> 00:28:35.400
And I was like, ah, it's so close to working.

00:28:35.400 --> 00:28:36.120
Oh, that's interesting.

00:28:36.780 --> 00:28:37.400
Yeah, yeah, yeah.

00:28:37.400 --> 00:28:40.940
So, I still think there's some rough edges, but it definitely seems...

00:28:40.940 --> 00:28:43.580
Like, the other stuff I tried didn't get that far, right?

00:28:43.580 --> 00:28:44.260
So, that was cool.

00:28:44.260 --> 00:28:46.040
Yeah, so I haven't had that experience.

00:28:46.040 --> 00:28:56.900
But I have had complications, because when you package your application, now you have to worry about things that depend on some of the Dunder methods to come in with Python, like the Dunder file stuff.

00:28:57.100 --> 00:29:03.340
Which is supposed to tell you the directory in which the file that you're working on is located.

00:29:03.340 --> 00:29:04.260
Right.

00:29:04.260 --> 00:29:14.940
Well, that's kind of different, because the way PyInstaller works is it bundles your application, all the files, and whatever extra data you want with it, and it bundles a Python interpreter in it.

00:29:14.940 --> 00:29:21.820
So, when it runs, it just extracts all this stuff into some internal directory that you're not aware of.

00:29:21.820 --> 00:29:23.160
So, Dunder file just doesn't work.

00:29:23.160 --> 00:29:25.160
It gives you anything.

00:29:25.160 --> 00:29:25.920
I can't remember.

00:29:26.340 --> 00:29:27.260
It's wrong, right?

00:29:27.260 --> 00:29:33.520
So, but PyInstaller provides its own little API to get the actual directory where the files actually exist.

00:29:33.520 --> 00:29:34.680
So, you just got to be aware.

00:29:34.680 --> 00:29:40.760
You do a check in your Python code to say, oh, we're inside PyInstaller, so we need to check here and go here instead.

00:29:40.760 --> 00:29:41.820
Okay, that's interesting.

00:29:41.820 --> 00:29:42.160
Yep.

00:29:42.160 --> 00:29:52.440
Can you use the Dunder file to still get, like, I need to go up one folder and get that other file next to it, or is it even relative stuff is not really working?

00:29:52.440 --> 00:29:55.960
Even relative stuff is not quite set up right.

00:29:55.960 --> 00:29:58.320
Okay, but if you build for it, it's not a big deal, it sounds like.

00:29:58.320 --> 00:29:58.420
Yeah.

00:29:58.420 --> 00:29:59.380
Yeah.

00:29:59.380 --> 00:30:03.180
And then another option is, I mentioned Russell Keith-Magee.

00:30:03.180 --> 00:30:03.980
Right.

00:30:03.980 --> 00:30:05.920
And his big project is the whole Beware project.

00:30:05.920 --> 00:30:08.120
And one of those is about packaging, right?

00:30:08.300 --> 00:30:09.340
Yeah, briefcase.

00:30:09.340 --> 00:30:09.420
Yeah, briefcase.

00:30:09.420 --> 00:30:30.220
And so, you know, Beware is a whole slew of individual repositories that provide different functions, specifically a way to, together, they provide a way to build cross-platform Python applications, which involve GUIs in mobile devices, as well as your desktop app or the web.

00:30:30.300 --> 00:30:32.660
And as part of that, they need a way to package the application.

00:30:32.660 --> 00:30:36.960
And so they built a briefcase, which is the repo that lets them do that.

00:30:36.960 --> 00:30:47.920
And so you can take, essentially, write a base app and using briefcase, produce, you know, an Android application and iOS application and everything else.

00:30:47.920 --> 00:30:52.140
I haven't particularly used it to do anything major.

00:30:52.320 --> 00:30:58.340
So I don't know a lot about the internal details, but I know it's there and people are working with it.

00:30:58.340 --> 00:31:01.480
Yeah, certainly it's pretty interesting that it has iOS and Android.

00:31:01.480 --> 00:31:01.860
Yeah.

00:31:01.860 --> 00:31:03.100
And I have seen the apps work.

00:31:03.100 --> 00:31:08.760
And, you know, Russell's done several talks on how that all does all this stuff.

00:31:08.760 --> 00:31:10.940
It's actually pretty neat, all the things that they're doing.

00:31:10.940 --> 00:31:15.320
Some of the Android stuff, last I checked, was transpiling some of the Python code.

00:31:15.320 --> 00:31:19.540
Some of the iOS stuff was directly calling into Objective-C, a few things.

00:31:19.540 --> 00:31:20.880
So it's pretty neat.

00:31:20.880 --> 00:31:21.120
Yeah.

00:31:21.480 --> 00:31:27.500
So that is some subset of the options for delivering an application, right?

00:31:27.500 --> 00:31:36.700
Like, I want to have the whole environment come along and whatever that takes, if that's a VM or bundling stuff up like Chrome or whatever you need, do that.

00:31:36.700 --> 00:31:41.640
Maybe another level is delivering a virtual environment, right?

00:31:41.640 --> 00:31:47.100
This sounds like it's most useful kind of for developer and automation and server type stuff.

00:31:47.100 --> 00:31:47.420
Great.

00:31:47.420 --> 00:31:53.780
So say you have an organization or customers that you know are on a set Python interpreter.

00:31:53.780 --> 00:31:57.060
So you don't need to bundle your Python interpreter with you.

00:31:57.180 --> 00:32:04.720
Then you can use some of these tools to bundle your application along with all of its dependencies into one file.

00:32:04.720 --> 00:32:15.960
So the ones I'm talking about here are PEX, for example, which was built by the folks at Twitter and SHIV, which was built by the folks at LinkedIn based on the PEX stuff.

00:32:16.160 --> 00:32:26.880
And the idea is they take all your code and they bundle it into one file and you can feed that file into Python and it follows a, I forget, I should have made note of that.

00:32:26.880 --> 00:32:31.020
There's a PEP that explains how to build these zip apps.

00:32:31.020 --> 00:32:32.260
PEP 441.

00:32:32.260 --> 00:32:33.780
There you go.

00:32:33.780 --> 00:32:34.580
Python zip applications.

00:32:34.580 --> 00:32:35.100
Yeah.

00:32:35.320 --> 00:32:35.560
Right.

00:32:35.560 --> 00:32:41.480
And so then with one command, you can just feed that into your Python interpreter and it knows how to unpack it and run all the stuff in it.

00:32:41.480 --> 00:32:42.020
Nice.

00:32:42.020 --> 00:32:45.380
And does PEX and SHIV, do these package up the dependencies?

00:32:45.380 --> 00:32:46.420
Yes.

00:32:46.420 --> 00:32:50.880
Like if I depend upon HTTPX or requests or Sook Alchemy, it'll take it with it?

00:32:50.880 --> 00:32:51.400
It'll do it.

00:32:51.400 --> 00:32:51.880
Yeah.

00:32:51.880 --> 00:32:52.580
That's pretty cool.

00:32:52.580 --> 00:33:01.420
But typically the virtual environments, at least on the Unix, Linux, macOS systems, are like symlinks back to the real Python, right?

00:33:01.420 --> 00:33:03.900
They're not full copies of Python.

00:33:03.900 --> 00:33:04.580
Right.

00:33:04.700 --> 00:33:04.860
Right.

00:33:04.860 --> 00:33:05.220
Yeah.

00:33:05.220 --> 00:33:06.740
So is that kind of how it works?

00:33:06.740 --> 00:33:12.860
It's like, here's a little virtual environment shell and just link back to the main Python and then run?

00:33:12.860 --> 00:33:13.180
Right.

00:33:13.180 --> 00:33:15.260
So you'll be using whatever the Python it is.

00:33:15.260 --> 00:33:21.000
And I haven't done this, but I imagine you could make a virtual env with your Python interpreter that you want to use.

00:33:21.000 --> 00:33:23.920
And then in that virtual env run your PECS or your SHIV package code.

00:33:23.920 --> 00:33:24.140
Yeah.

00:33:24.140 --> 00:33:24.460
Yeah.

00:33:24.460 --> 00:33:25.560
I would think so as well.

00:33:25.560 --> 00:33:26.000
Yeah.

00:33:26.000 --> 00:33:34.440
So you still, basically the idea is you still got to have Python bare bones as a thing, the version that you need as a thing.

00:33:34.580 --> 00:33:36.800
There to bootstrap.

00:33:36.800 --> 00:33:40.720
But once you have that, at least you don't have to say, first step is create the virtual environment.

00:33:40.720 --> 00:33:43.960
Second step is pip install dash are the requirements.

00:33:43.960 --> 00:33:45.660
Like you can skip all of that.

00:33:45.660 --> 00:33:49.020
Long as Python is present, you can basically run it potentially.

00:33:49.020 --> 00:33:49.720
That's correct.

00:33:49.720 --> 00:33:50.560
Yeah.

00:33:50.640 --> 00:33:50.920
Okay.

00:33:50.920 --> 00:33:51.940
Yeah.

00:33:51.940 --> 00:33:52.940
That looks really cool.

00:33:52.940 --> 00:33:57.680
When I first saw that, I was like, oh, please let this package up the Python runtime with it.

00:33:57.680 --> 00:33:59.680
And no, you're right.

00:33:59.680 --> 00:34:09.200
It just builds on top of that PEP 441 to say, basically you can create these zip versions that are directly executable by Python.

00:34:09.440 --> 00:34:09.980
That's it.

00:34:09.980 --> 00:34:10.240
Yeah.

00:34:10.240 --> 00:34:10.500
Yeah.

00:34:10.500 --> 00:34:10.600
Yeah.

00:34:10.600 --> 00:34:19.760
So if you have like a, in a large organization, sometimes you have a standard virtual developer, virtual machine or developer laptop or desktop stuff that you distribute to everybody.

00:34:20.160 --> 00:34:36.180
And if you have the stuff in place, which not everybody does to automatically keep that up to date with say whatever Python interpreter it is that you're running, then you can make a safe assumption that your customers, your users are all going to have this Python environment and just go from there.

00:34:36.280 --> 00:34:36.420
Yeah.

00:34:36.420 --> 00:34:39.160
It definitely seems like an interesting way to ship stuff to a server.

00:34:39.160 --> 00:34:39.640
Right.

00:34:39.640 --> 00:34:49.400
Instead of creating the environments and setting them up there and installing the packages, just like, I'm going to take this zipped up virtual environment, send it over there and say run.

00:34:49.400 --> 00:34:55.000
It's not quite Docker works on my machine level, but it's closer.

00:34:55.000 --> 00:34:55.380
Right.

00:34:55.380 --> 00:35:02.180
So other things you'd have to think about at sites from the interpreter would be any other like external dependencies of your package.

00:35:02.180 --> 00:35:04.260
Those will probably not get zipped up with it.

00:35:04.560 --> 00:35:10.560
I think there's some options to help that along on both of them, but I'm, I don't know all the details with that specifically.

00:35:10.560 --> 00:35:10.820
Right.

00:35:10.820 --> 00:35:14.800
But maybe you need Redis on the machine and like, that's not a Python thing.

00:35:14.800 --> 00:35:16.540
Or you need lib MySQL.

00:35:16.540 --> 00:35:17.200
I see.

00:35:17.200 --> 00:35:17.420
Yeah.

00:35:17.420 --> 00:35:18.380
Or something like that.

00:35:18.380 --> 00:35:22.720
I'll throw one more into this part of the taxonomy delivering as a virtual environment.

00:35:22.720 --> 00:35:23.700
PIPX.

00:35:23.700 --> 00:35:24.660
Are you familiar with PIPX?

00:35:24.660 --> 00:35:25.360
I am.

00:35:25.360 --> 00:35:26.780
I use it a little bit.

00:35:26.780 --> 00:35:27.400
Yeah.

00:35:27.400 --> 00:35:30.180
I haven't done much else after initial config.

00:35:30.180 --> 00:35:30.580
Yeah.

00:35:30.580 --> 00:35:30.860
Yeah.

00:35:30.920 --> 00:35:47.400
So PIPX is interesting because PIPX, if you have Python on your machine and you pip install PIPX, from then on, you can do basically the way things like homebrew or chocolatey work for installing like utilities into your, your OS.

00:35:47.920 --> 00:35:53.180
If those utilities are based on Python, PIPX serves the same role as say homebrew.

00:35:53.180 --> 00:35:53.600
Right.

00:35:53.600 --> 00:35:53.960
Right.

00:35:54.020 --> 00:36:00.720
So I can go, and if I pip install --user PIPX, from then on, I now have a PIPX command.

00:36:00.720 --> 00:36:03.620
And I could say like PIPX install glances.

00:36:03.620 --> 00:36:12.260
And glances is like a cool terminal sort of process explorer type thing with, you know, ASCII bar graphs and whatnot.

00:36:12.260 --> 00:36:12.720
Right.

00:36:13.120 --> 00:36:22.280
So if I wanted that, I could say PIPX install glances and we'll create a dedicated virtual environment just to run and install glances.

00:36:22.280 --> 00:36:32.960
And if then, if I want HTTPY, which is a cool alternative to curl, that's Python basic, I say PIPX install HTTPY and it'll actually go and create a dedicated isolated environment for that command line tool.

00:36:32.960 --> 00:36:44.720
So if you've got a command line option that you want to, a command line tool that is Python based and you want to be able to have it upgrade itself because you can say PIPX upgrade all and stuff like that.

00:36:44.720 --> 00:36:45.640
And it's isolated.

00:36:45.640 --> 00:36:47.080
It's not being installed in one of your projects.

00:36:47.080 --> 00:36:48.440
It's just something you want on your machine.

00:36:48.440 --> 00:36:50.240
PIPX is actually a pretty cool option.

00:36:50.240 --> 00:36:50.680
Yeah.

00:36:50.680 --> 00:36:57.580
Like I would use it for, I would even use it for something like a linter or a, you know, install flacate.

00:36:57.580 --> 00:37:02.940
And then you can use, when you type flacate anywhere, it'll just run your PIPX frozen essentially.

00:37:02.940 --> 00:37:04.400
environment for that.

00:37:04.400 --> 00:37:04.680
Yeah.

00:37:04.680 --> 00:37:04.980
Yeah.

00:37:04.980 --> 00:37:06.220
That is pretty cool.

00:37:06.220 --> 00:37:14.620
And then along with that, if you want to create a package that fits into that world, I want to create a package that I'm going to create as a tool for somebody.

00:37:14.620 --> 00:37:18.700
Then you can create an entry point in your package, right?

00:37:18.700 --> 00:37:22.780
Which is a thing you can do in your, I think in the setup PY, where you put it.

00:37:22.780 --> 00:37:22.920
Yep.

00:37:22.920 --> 00:37:23.740
Yep.

00:37:23.740 --> 00:37:26.440
And you say, here's the command and here's the entry point.

00:37:26.440 --> 00:37:29.640
And like, here's actually what that means in terms of my package, right?

00:37:29.640 --> 00:37:31.480
Like black or whatever.

00:37:31.480 --> 00:37:32.080
Right.

00:37:32.080 --> 00:37:32.720
Yep.

00:37:32.780 --> 00:37:33.760
So you can set those up.

00:37:33.760 --> 00:37:40.760
And then if you install them with PIPX, now you're managing that almost as a separate command line set of APIs.

00:37:40.760 --> 00:37:41.540
Right.

00:37:41.540 --> 00:37:42.820
That could automatically be updated.

00:37:42.820 --> 00:37:51.080
Obviously you can install them with PEP elsewhere, but PIPX is cool because it's isolated and automatically, well, upon request will automatically upgrade stuff for you.

00:37:51.080 --> 00:37:52.840
Yeah, no, that's another cool utility.

00:37:52.840 --> 00:37:57.720
This portion of Talk Python To Me is brought to you by Linode.

00:37:57.900 --> 00:38:06.660
Whether you're working on a personal project or managing your enterprise's infrastructure, Linode has the pricing, support, and scale that you need to take your project to the next level.

00:38:06.660 --> 00:38:21.320
With 11 data centers worldwide, Linode delivers the performance that you expect at a price that you don't.

00:38:21.320 --> 00:38:37.380
Get started on Linode today with a $20 credit and you get access to native SSD storage, a 40 gigabit network, industry-leading processors, their revamped cloud manager at cloud.linode.com, root access to your server, along with their newest API and a Python CLI.

00:38:37.800 --> 00:38:45.400
Just visit talkpython.com.com when creating a new Linode account and you'll automatically get $20 credit for your next project.

00:38:45.400 --> 00:38:46.680
Oh, and one last thing.

00:38:46.680 --> 00:38:47.460
They're hiring.

00:38:47.460 --> 00:38:50.560
Go to linode.com slash careers to find out more.

00:38:50.560 --> 00:38:51.900
Let them know that we sent you.

00:38:54.300 --> 00:38:54.860
All right.

00:38:54.860 --> 00:39:05.360
And then the third part of our trifecta, three or four, something like that, is basically what I started with.

00:39:05.360 --> 00:39:09.240
I want an icon next to Firefox and Word in my doc.

00:39:09.240 --> 00:39:12.960
I click it and I want to see it run and do its thing.

00:39:12.960 --> 00:39:13.580
Right?

00:39:13.580 --> 00:39:15.820
Like that type of thing.

00:39:15.820 --> 00:39:17.360
Take us through what our options are here.

00:39:17.360 --> 00:39:17.720
Great.

00:39:17.780 --> 00:39:23.100
So we already kind of discussed PyInstaller and that's the best one for the icon, double click and go.

00:39:23.100 --> 00:39:25.040
Yeah, it works for all the operating systems, right?

00:39:25.040 --> 00:39:27.740
It works for macOS and Windows and Linux.

00:39:27.740 --> 00:39:33.100
But don't you need those systems in place to build the deliverables?

00:39:33.100 --> 00:39:33.860
That's correct.

00:39:33.860 --> 00:39:34.300
Right?

00:39:34.300 --> 00:39:38.920
Like if I just have Windows, I'm in trouble because I don't have a Mac to build my Mac version.

00:39:38.920 --> 00:39:39.360
Right.

00:39:39.360 --> 00:39:47.500
In fact, to the point where I even considered it would be interesting to set up some online stuff that creates PyInstaller packages for you

00:39:47.500 --> 00:39:53.200
that just somebody that's essentially renting out the Windows or the Macs for doing it.

00:39:53.200 --> 00:39:53.420
Right?

00:39:53.420 --> 00:39:53.660
Yeah.

00:39:53.660 --> 00:39:55.100
That would actually be a really cool service.

00:39:55.100 --> 00:39:57.520
It's like, here's my Python application.

00:39:57.520 --> 00:39:59.240
Here's its icon.

00:39:59.240 --> 00:40:06.020
Here's what I wanted to just make that for all the operating systems and give it back to me as like an MSI installer on Windows,

00:40:06.020 --> 00:40:09.400
a .app on a Mac and a Linux binary or something like that.

00:40:09.400 --> 00:40:09.600
Right?

00:40:09.600 --> 00:40:10.720
That would be a super cool project.

00:40:10.720 --> 00:40:11.620
And yeah.

00:40:11.620 --> 00:40:12.940
So PyInstaller gives you that.

00:40:12.940 --> 00:40:14.320
And, you know, we mentioned it earlier.

00:40:14.480 --> 00:40:19.960
And you can also get just a package application without all the extra pretty stuff along with it.

00:40:19.960 --> 00:40:24.380
But the one that makes it the most pretty so far for me has been PyInstaller.

00:40:24.380 --> 00:40:25.180
Yeah.

00:40:25.180 --> 00:40:26.140
Now the next contender.

00:40:26.140 --> 00:40:30.340
So actually, before I go with that, let's just talk about Newtka a little bit.

00:40:30.340 --> 00:40:33.660
So that package has been around for a while.

00:40:34.400 --> 00:40:39.720
And so PyInstaller produces and packages all of your stuff together for you.

00:40:39.720 --> 00:40:42.240
It doesn't compile it for you.

00:40:42.240 --> 00:40:42.840
Right?

00:40:42.840 --> 00:40:43.520
Okay.

00:40:43.520 --> 00:40:43.820
Yeah.

00:40:43.820 --> 00:40:46.760
It just takes Python along with it.

00:40:46.760 --> 00:40:49.840
And then it like drops your files out and then like runs those.

00:40:49.840 --> 00:40:53.080
It doesn't fundamentally change what's happening.

00:40:53.080 --> 00:40:54.080
That's right.

00:40:54.140 --> 00:40:57.720
It just delivers the two pieces and it clicks them together and says go.

00:40:57.720 --> 00:40:59.220
Like CPython already.

00:40:59.220 --> 00:40:59.420
Yeah.

00:40:59.420 --> 00:40:59.760
Right.

00:40:59.760 --> 00:41:08.680
If you want to actually compile it and get some extra speed boosts out of having an actual compiled C code instead of an interpreted language,

00:41:08.680 --> 00:41:13.240
then you can use something like Newtka, which actually produces the one file.

00:41:13.240 --> 00:41:18.680
You can just .slash run or double click and get it to run your stuff.

00:41:18.680 --> 00:41:19.420
Right?

00:41:19.700 --> 00:41:27.620
Now there's, of course, since you're compiling it, things get a little bit more complicated and you have to start thinking about having compilers,

00:41:27.620 --> 00:41:32.580
having the correct libraries in order to do all of that and the dependencies of those libraries.

00:41:32.580 --> 00:41:35.680
So it's slightly harder to do it.

00:41:35.680 --> 00:41:45.000
But you'll get in the end code that doesn't, you know, when you run your application in PyInstaller, you're extracting the application and then running it.

00:41:45.000 --> 00:41:48.820
But if you run it on something like Newtka, you don't need to extract it.

00:41:48.900 --> 00:41:50.960
It's just the one file that just runs.

00:41:50.960 --> 00:41:51.140
Right.

00:41:51.140 --> 00:41:54.740
It's converted to machine instructions that just do its thing.

00:41:54.740 --> 00:41:55.020
That's correct.

00:41:55.020 --> 00:41:55.740
Yeah.

00:41:55.740 --> 00:41:59.600
So that sounds actually like an incredibly good option.

00:41:59.600 --> 00:42:00.040
Right?

00:42:00.040 --> 00:42:01.180
It's got to run pretty fast.

00:42:01.180 --> 00:42:03.760
It sounds like it's nice and independent.

00:42:03.760 --> 00:42:04.440
That's great.

00:42:04.440 --> 00:42:09.260
But what if I depend on other complex things?

00:42:09.520 --> 00:42:18.840
Like I'm using NumPy or I'm using SeqAlchemy, which has its own compiled bits or something like that.

00:42:18.840 --> 00:42:23.340
So if you're using something like NumPy, then you're not going to get a lot of speed boosts out of it.

00:42:23.340 --> 00:42:24.000
Right?

00:42:24.000 --> 00:42:24.800
Right.

00:42:24.800 --> 00:42:26.500
Because you're already running at C.

00:42:26.500 --> 00:42:29.180
Is it going to take NumPy along with it?

00:42:29.180 --> 00:42:32.340
Like, can it handle like dependencies of this type?

00:42:32.340 --> 00:42:32.680
Do you know?

00:42:33.160 --> 00:42:34.540
Pretty sure it can.

00:42:34.540 --> 00:42:36.120
I haven't had to do it myself.

00:42:36.120 --> 00:42:36.140
Yeah.

00:42:36.140 --> 00:42:37.000
I've not tried either.

00:42:37.000 --> 00:42:37.580
Yeah.

00:42:37.580 --> 00:42:37.840
Yeah.

00:42:37.840 --> 00:42:39.620
I mean, if it could, that would be pretty cool, actually.

00:42:39.620 --> 00:42:39.980
Yeah.

00:42:39.980 --> 00:42:41.340
All right.

00:42:41.340 --> 00:42:43.220
Want to talk about the new kid on the block?

00:42:43.220 --> 00:42:49.480
The new kid on the block is PyOxidizer, which has come up a few times this year already.

00:42:49.480 --> 00:42:50.040
Clever name.

00:42:50.040 --> 00:42:50.940
Yep.

00:42:50.940 --> 00:42:57.540
It's built on the packaging tools that the Rust programming language brought with it.

00:42:57.540 --> 00:43:02.520
And so it can produce executables for you.

00:43:02.520 --> 00:43:05.760
It still bundles things as well.

00:43:05.760 --> 00:43:10.920
The difference is that instead of extracting them into the file system like PyInstaller does,

00:43:10.920 --> 00:43:12.960
it extracts it into memory.

00:43:13.080 --> 00:43:18.160
So you'll get a faster startup time when, and all your library loads are going to happen

00:43:18.160 --> 00:43:20.360
straight off of memory because it's all mapped in there.

00:43:20.360 --> 00:43:21.300
That sounds really good.

00:43:21.300 --> 00:43:25.600
I know that you tried this on your example in the article that you wrote and you didn't

00:43:25.600 --> 00:43:26.420
go with this.

00:43:26.420 --> 00:43:27.780
That's correct.

00:43:27.780 --> 00:43:31.900
Like, if I had to just guess, close my eyes and say, all right, I don't really know too

00:43:31.900 --> 00:43:35.120
much, but I'm going to guess, I would, I would actually guess PyOxidizer might be the

00:43:35.120 --> 00:43:39.240
place to start because it's a little fresher, but what was the challenge there?

00:43:39.240 --> 00:43:43.040
So there's just a couple of different things similar to the PyInstaller stuff.

00:43:43.040 --> 00:43:45.000
Dunder file doesn't work.

00:43:45.000 --> 00:43:47.420
So you got to configure a few things.

00:43:47.420 --> 00:43:51.700
And in this case, it's a slightly more complicated because it's not like it's a different directory

00:43:51.700 --> 00:43:53.360
because there's no directories in memory.

00:43:53.360 --> 00:43:53.700
In memory.

00:43:53.700 --> 00:43:54.040
Yeah.

00:43:54.040 --> 00:43:54.440
Yeah.

00:43:54.440 --> 00:43:54.860
Right.

00:43:55.280 --> 00:43:58.680
But they have like very extensive documentation on how to get past it.

00:43:58.680 --> 00:44:03.600
And so that, that was like my biggest holdup, which at the time to me just kind of felt like,

00:44:03.600 --> 00:44:05.620
I need to think about it a little more.

00:44:05.620 --> 00:44:09.240
So I just put it on the side as a come back to this later.

00:44:09.660 --> 00:44:15.780
But the thing I really liked about it was it's like the config options you have for the, for what

00:44:15.780 --> 00:44:18.440
you can, the output that you can get out of it are really neat.

00:44:18.440 --> 00:44:26.000
And so you can get an executable that runs a function inside a module, or it just runs file,

00:44:26.000 --> 00:44:29.980
works as if you were running your file from the CLI, your Python file from the CLI.

00:44:29.980 --> 00:44:35.460
Or you can get, which is what I like because I can play with, you run it and it just starts

00:44:35.460 --> 00:44:42.400
your Python interpreter, your REPL with your entire virtual environment along there available.

00:44:42.400 --> 00:44:51.580
So you just say, create my REST API application, a client application, and I can just run client,

00:44:51.580 --> 00:44:54.280
not that PI because it's compiled, right?

00:44:54.280 --> 00:45:00.720
And well, it's an executable and I'll get a Python REPL with, you know, requests already

00:45:00.720 --> 00:45:01.940
available for me to import it.

00:45:01.940 --> 00:45:03.240
And I don't have to pip install anything.

00:45:03.240 --> 00:45:03.960
That's cool.

00:45:04.200 --> 00:45:05.600
So in that sense, it's slight.

00:45:05.600 --> 00:45:08.460
And I think you can do that with pecs and shiv as well.

00:45:08.460 --> 00:45:09.660
There's a way of doing that.

00:45:09.660 --> 00:45:11.500
But this was really neat.

00:45:11.500 --> 00:45:15.000
You have a lot of control over it and you can watch it, pull in all the dependencies.

00:45:15.000 --> 00:45:19.960
You can have it, it'll pip install everything for you into this, this kind of directory structure

00:45:19.960 --> 00:45:22.120
when it's trying to put itself together.

00:45:22.120 --> 00:45:26.840
And so it grabs all the dependencies fresh out of PI PI or whatever indexes you feed it and

00:45:26.840 --> 00:45:29.200
then creates your final environment from that.

00:45:29.200 --> 00:45:30.060
It sounds pretty promising.

00:45:30.060 --> 00:45:32.000
It seems like it's got a nice modern take.

00:45:32.160 --> 00:45:34.280
I like the making your code run faster.

00:45:34.280 --> 00:45:35.200
It's already in memory.

00:45:35.200 --> 00:45:35.640
Yeah.

00:45:35.640 --> 00:45:36.540
It's all pretty cool.

00:45:36.540 --> 00:45:39.520
This one does all the OSs as well, right?

00:45:39.520 --> 00:45:39.860
Yes.

00:45:39.860 --> 00:45:40.080
Cool.

00:45:40.080 --> 00:45:45.000
As I'm sitting here listening to talk about all this stuff, it seems to me like one of

00:45:45.000 --> 00:45:48.340
the big challenges is how do I get Python to come over correctly?

00:45:48.340 --> 00:45:51.200
How do I get the dependencies to come over correctly?

00:45:51.200 --> 00:45:56.240
Sometimes it's a little bit tricky to get the program to actually start.

00:45:56.240 --> 00:46:00.700
You know, it seems like there's some challenges on around some of the platform stuff.

00:46:00.700 --> 00:46:05.960
What I don't see with any of these is what do you think the viability of saying like you

00:46:05.960 --> 00:46:09.900
can take CPython and embed it into any application, right?

00:46:09.900 --> 00:46:10.460
Yeah.

00:46:10.460 --> 00:46:11.820
Like you can host CPython.

00:46:12.220 --> 00:46:17.360
What if you created an app that is just a C-based app that obviously runs, no problem.

00:46:17.360 --> 00:46:20.660
It already has Python compiled into it.

00:46:20.660 --> 00:46:27.160
And its job is to unravel the virtual environment and run your code alongside.

00:46:27.160 --> 00:46:34.200
So you're just shipping this, your EXE that already comes with Python and like it already

00:46:34.200 --> 00:46:35.680
knows how to run totally reliably.

00:46:35.680 --> 00:46:40.600
It's just a matter of executing your Python code as part of its like internal automation

00:46:40.600 --> 00:46:40.960
or whatever.

00:46:40.960 --> 00:46:41.400
Yeah.

00:46:41.400 --> 00:46:48.480
So I haven't done too much work into all of that, but I think it's things like PyOxidizer

00:46:48.480 --> 00:46:54.600
will help with that or even something that the ones that do the compilation for you, if

00:46:54.600 --> 00:46:59.500
you're trying to deliver an executable like Nutca or even Cython, it can help you along

00:46:59.500 --> 00:47:00.020
those lines.

00:47:00.020 --> 00:47:00.380
Okay.

00:47:00.380 --> 00:47:01.100
Interesting.

00:47:01.100 --> 00:47:01.720
All right.

00:47:01.720 --> 00:47:01.920
Yeah.

00:47:01.920 --> 00:47:07.120
So you mentioned Cython, that one in your article sounded like I'm a fan of Cython.

00:47:07.120 --> 00:47:08.760
I've used it for a couple of things.

00:47:08.760 --> 00:47:12.760
It's really cool that it supports the Python type hints.

00:47:12.760 --> 00:47:16.220
Now it doesn't have its own like type language necessarily.

00:47:16.540 --> 00:47:22.220
It still has it, but it used to be, you'd have to describe your types in the Cython way.

00:47:22.220 --> 00:47:28.020
Now, if you just describe them in the CPython way, Cython goes along with that, which is really

00:47:28.020 --> 00:47:28.260
cool.

00:47:28.260 --> 00:47:33.900
That means you can write kind of just annotated Python in the traditional sense or the normal

00:47:33.900 --> 00:47:38.100
sense and you get compiled machine instruction type stuff.

00:47:38.100 --> 00:47:39.100
That's pretty awesome.

00:47:39.100 --> 00:47:41.400
But it's not really built for packaging, is it?

00:47:41.400 --> 00:47:47.020
The end goal of Cython was really to integrate C and Python essentially so that you can go

00:47:47.020 --> 00:47:53.260
into C code and use Python libraries from it, or you can go into, which is the more common

00:47:53.260 --> 00:47:59.520
part, go into Python code and use a C library inside Python code, like say NumPy or something

00:47:59.520 --> 00:47:59.900
like that.

00:47:59.900 --> 00:48:00.360
Yeah.

00:48:00.500 --> 00:48:06.120
Something beyond just C types and some of the base stuff that Python already has.

00:48:06.120 --> 00:48:08.320
But it'll compile your Python code for you.

00:48:08.320 --> 00:48:12.080
And it has an option to produce a single file executable.

00:48:12.080 --> 00:48:17.600
It just isn't going to do a lot of like, for example, if you do it with Nuka, it'll traverse

00:48:17.600 --> 00:48:19.960
all of your dependencies and compile and put them together.

00:48:20.120 --> 00:48:23.120
But Cython will only do a little bit of that.

00:48:23.120 --> 00:48:25.080
It won't traverse dependencies.

00:48:25.080 --> 00:48:26.260
Right.

00:48:26.260 --> 00:48:26.820
Right.

00:48:26.820 --> 00:48:30.700
It probably expects like, you're going to compile these three files and then put them together

00:48:30.700 --> 00:48:31.880
or something.

00:48:31.880 --> 00:48:32.140
Right.

00:48:32.140 --> 00:48:37.160
And you just want to give it a Python application and say, put these pieces together for me.

00:48:37.160 --> 00:48:38.700
And it's just, it's not really for that, is it?

00:48:38.700 --> 00:48:38.980
Yeah.

00:48:38.980 --> 00:48:40.260
It's not really built for that.

00:48:40.260 --> 00:48:41.720
But it's one of the things I tried.

00:48:41.720 --> 00:48:42.100
Yeah.

00:48:42.100 --> 00:48:42.360
Yeah.

00:48:42.360 --> 00:48:42.640
Sure.

00:48:42.640 --> 00:48:47.020
And it, you know, it does get you C code, which is, and you can compile.

00:48:47.400 --> 00:48:53.140
And yeah, it's, it's a possibility, but it's, yeah, it just seems like it's abusing Cython

00:48:53.140 --> 00:48:57.240
because you, because you could probably make it work, but it's not like it's goal, right?

00:48:57.240 --> 00:49:01.640
Like PyOxidizer doesn't have another purpose other than to package up your thing.

00:49:01.640 --> 00:49:03.560
And so it's kind of what it's for.

00:49:03.560 --> 00:49:03.920
Yep.

00:49:03.920 --> 00:49:09.680
Then two of the things that didn't fit in the taxonomy were Flatpak and Snapcraft, both

00:49:09.680 --> 00:49:12.720
of which are ways to package up an application.

00:49:13.300 --> 00:49:16.300
It's for Linux.

00:49:16.300 --> 00:49:17.540
Is it?

00:49:17.540 --> 00:49:18.900
And specifically Linux.

00:49:18.900 --> 00:49:19.320
Yeah.

00:49:19.320 --> 00:49:19.800
Linux.

00:49:19.800 --> 00:49:23.160
And, and, but what's cool is they, they both have like their own little app store.

00:49:23.160 --> 00:49:28.580
It's kind of like the macOS app store or the Windows 10 app store, but it's the Snapcraft

00:49:28.580 --> 00:49:31.380
or Flat, Flat, Flatpak app store.

00:49:31.380 --> 00:49:31.880
Yes.

00:49:31.880 --> 00:49:36.720
It's more like apt or yum, like its own little package manager type thing.

00:49:36.900 --> 00:49:40.900
And it, it packages everything together with you, Flatpak.

00:49:40.900 --> 00:49:46.600
I don't have a lot of, it's been a while since I've gone into all the details of how

00:49:46.600 --> 00:49:48.280
Flatpak did its, its thing.

00:49:48.280 --> 00:49:52.480
And I think it even included some, some OS stuff when it did all its packaging.

00:49:52.480 --> 00:49:57.940
So you run in a completely isolated environment, your application and Snapcraft does something

00:49:57.940 --> 00:49:58.440
similar.

00:49:59.140 --> 00:50:01.820
And on top of it, it's an app store.

00:50:01.820 --> 00:50:03.940
So type experience.

00:50:03.940 --> 00:50:09.860
So if you push an update, it'll, if you enable it, it'll automatically update your application

00:50:09.860 --> 00:50:10.260
for you.

00:50:10.260 --> 00:50:10.460
Yeah.

00:50:10.460 --> 00:50:11.700
I think that's actually pretty cool.

00:50:11.700 --> 00:50:12.040
Yeah.

00:50:12.040 --> 00:50:12.680
I think that's neat.

00:50:12.680 --> 00:50:17.140
There's actually a lot, actually a lot of use cases for that, even in, in large organizations,

00:50:17.140 --> 00:50:20.120
beyond just, typical customer stuff.

00:50:20.120 --> 00:50:25.120
Like if you're talking about developers, if you have a bunch of developer tools and

00:50:25.120 --> 00:50:30.000
you just produce some new Python package with these tools in it, then you got to go ask all

00:50:30.000 --> 00:50:33.020
the developers to go pip install --upgrade.

00:50:33.020 --> 00:50:33.500
Right.

00:50:33.500 --> 00:50:33.880
Yeah.

00:50:33.880 --> 00:50:38.560
But if you do, if you have something like this and everybody's on Linux, which may or may not

00:50:38.560 --> 00:50:43.440
be true, then you can just push the update out to the developers.

00:50:43.960 --> 00:50:48.320
And since I'm on that, that just reminded me, there's another system, which isn't a packaging

00:50:48.320 --> 00:50:54.780
system, but it's a distribution system called pulp that works a little bit like artifactory.

00:50:54.780 --> 00:50:59.380
If you're aware of that, which is essentially a package distribution system.

00:50:59.380 --> 00:51:03.040
it will do like a private PI PI server.

00:51:03.040 --> 00:51:03.320
Yeah.

00:51:03.320 --> 00:51:06.600
But yeah, it covers like all the different types and languages.

00:51:06.600 --> 00:51:06.940
Yeah.

00:51:06.940 --> 00:51:08.080
Docker registries and all that.

00:51:08.080 --> 00:51:12.900
But pulp has agents that you can install on your systems and push updates to them.

00:51:12.900 --> 00:51:13.300
Oh, I see.

00:51:13.380 --> 00:51:17.980
And then like, Hey, run this script to make sure everybody's got like the newest engine

00:51:17.980 --> 00:51:19.600
X or the newest whatever.

00:51:19.600 --> 00:51:19.920
Right.

00:51:19.920 --> 00:51:20.200
Yep.

00:51:20.200 --> 00:51:20.460
Okay.

00:51:20.460 --> 00:51:21.120
That's pretty cool.

00:51:21.120 --> 00:51:22.820
I definitely like the auto update.

00:51:22.820 --> 00:51:28.740
Now you should be able to a very strong should not necessarily could, but should, if you could

00:51:28.740 --> 00:51:35.820
get high oxidizer or PI installer to truly work correctly, you should be able to take that

00:51:35.820 --> 00:51:39.940
output and put it in the macOS app store or in the windows 10 app store.

00:51:39.940 --> 00:51:40.700
I think so.

00:51:40.700 --> 00:51:41.420
Yes.

00:51:41.420 --> 00:51:41.760
Right.

00:51:41.760 --> 00:51:43.680
And then you get the benefits of doing that.

00:51:43.680 --> 00:51:46.180
Those app stores always have weird restrictions.

00:51:46.180 --> 00:51:47.520
Yeah.

00:51:47.800 --> 00:51:50.560
I know one of the worst parts of my mobile app.

00:51:50.560 --> 00:51:50.760
I know you had your experiences.

00:51:50.760 --> 00:51:51.000
Yeah.

00:51:51.000 --> 00:51:52.100
Oh man.

00:51:52.100 --> 00:51:57.620
I'm still, I don't want to go into it, but I'm still having, let's call them disagreements

00:51:57.620 --> 00:52:02.140
at very strong levels with some of the app stores, right?

00:52:02.140 --> 00:52:05.740
Like just some of them were completely weird and out of place.

00:52:05.740 --> 00:52:08.140
Other are just, I don't know.

00:52:08.140 --> 00:52:12.300
They're just, no, you have to change your app to be like this for no particular reason.

00:52:12.620 --> 00:52:13.940
But they're very frustrating.

00:52:13.940 --> 00:52:16.820
But if it works, it's actually a great experience for the user.

00:52:16.820 --> 00:52:17.220
Right.

00:52:17.220 --> 00:52:17.900
Right.

00:52:17.900 --> 00:52:25.100
When I install an app on my Mac, if it has a version in the app store or I could buy it

00:52:25.100 --> 00:52:28.140
separately, I get it in the app store because then I know it's going to be just be on all

00:52:28.140 --> 00:52:28.780
my machines.

00:52:28.780 --> 00:52:29.480
Yeah.

00:52:29.480 --> 00:52:32.880
I don't have to worry about what happens if I lose the license code or I've activated it

00:52:32.880 --> 00:52:34.860
twice, but that one machine actually died.

00:52:34.860 --> 00:52:39.000
So I'm not actually using it, but I can't deactivate it because it's actually dead.

00:52:39.000 --> 00:52:42.900
Like, you know, like how often have you been through this experience of like, you've over,

00:52:42.900 --> 00:52:44.800
you've used up your five activations.

00:52:44.800 --> 00:52:48.240
It's like, well, but the machines were virtual machines and I threw them away.

00:52:48.240 --> 00:52:49.340
I can't unactivate them.

00:52:49.340 --> 00:52:50.800
I don't know what you want from me, you know?

00:52:50.800 --> 00:52:53.260
So the app stores are good in that regard.

00:52:53.260 --> 00:52:53.780
They are.

00:52:53.780 --> 00:52:58.880
And you can also have the experience of, well, I have all the, all of these devices that are

00:52:58.880 --> 00:53:04.280
registered on my app store and I want to install this application.

00:53:04.280 --> 00:53:06.520
Please install it on all of them for me.

00:53:06.520 --> 00:53:07.220
Right.

00:53:07.220 --> 00:53:07.440
Yeah.

00:53:07.440 --> 00:53:10.820
Because the system's already built with the permissions to do that.

00:53:10.820 --> 00:53:11.780
Then you're set.

00:53:11.780 --> 00:53:12.100
Yep.

00:53:12.100 --> 00:53:12.660
Absolutely.

00:53:12.660 --> 00:53:18.280
Well, I think these are all really good options and I think it's most important to break it

00:53:18.280 --> 00:53:19.180
into that taxonomy.

00:53:19.180 --> 00:53:21.680
Like first, what are you even trying to do?

00:53:21.680 --> 00:53:27.280
Because the fix for one of these is definitely not the fix for another one of them necessarily.

00:53:27.280 --> 00:53:27.880
Right.

00:53:28.180 --> 00:53:29.060
So, yeah.

00:53:29.060 --> 00:53:32.560
But this gives people a lot to think about and a lot to go play around with.

00:53:32.560 --> 00:53:33.940
So, yeah, it's cool.

00:53:33.940 --> 00:53:36.000
Yeah, for sure.

00:53:36.000 --> 00:53:36.240
Yeah.

00:53:36.240 --> 00:53:42.560
Now, I do have one plea, one request for the folks maintaining all of these things.

00:53:42.560 --> 00:53:44.560
Maybe not all of them.

00:53:44.560 --> 00:53:46.860
Like Cython, Cython's off the hook.

00:53:46.860 --> 00:53:49.660
But for many of these things, right?

00:53:49.660 --> 00:53:57.940
For Pi Installer, for Briefcase, for a lot of these, have one or two showcase applications.

00:53:57.940 --> 00:54:00.400
That when you go there.

00:54:00.400 --> 00:54:01.960
And guess what?

00:54:01.960 --> 00:54:08.720
We found this awesome open source GUI application and we built a Mac, Linux, and Windows version of it.

00:54:08.720 --> 00:54:10.020
Here's a screenshot.

00:54:10.020 --> 00:54:13.360
Click to download and run it and see what the experience is as a user.

00:54:13.360 --> 00:54:14.020
Right.

00:54:14.200 --> 00:54:15.180
Briefcase is really cool.

00:54:15.180 --> 00:54:15.860
But I go there.

00:54:15.860 --> 00:54:20.500
There's not like a single example of anything built with it or what.

00:54:20.500 --> 00:54:20.720
Right.

00:54:20.720 --> 00:54:24.600
There's no evidence to me before I commit to trying it out.

00:54:24.600 --> 00:54:28.320
Like, look at this amazing stuff that's built with Briefcase or Pi Installer.

00:54:28.320 --> 00:54:28.580
Right.

00:54:28.640 --> 00:54:34.600
Like, here's three applications that are well-known apps that you probably didn't even know were built on Python.

00:54:34.600 --> 00:54:35.160
Right.

00:54:35.160 --> 00:54:36.720
So anyway, I'm going on and on.

00:54:36.720 --> 00:54:37.140
I'm with you.

00:54:37.140 --> 00:54:39.360
If people are out there like, please put this.

00:54:39.360 --> 00:54:42.060
This will do so much to help the adoption.

00:54:42.480 --> 00:54:44.080
If people can go see like that.

00:54:44.080 --> 00:54:46.940
And it doesn't have to be the owner of that application.

00:54:46.940 --> 00:54:51.240
Find an open source application that's awesome that you could package up and then package it up.

00:54:51.240 --> 00:54:52.760
Like, you know, it doesn't even have to.

00:54:52.760 --> 00:54:53.240
Right.

00:54:53.240 --> 00:54:56.860
You could just do it as your own proof of concept and then tell, like, do a PR back.

00:54:56.860 --> 00:54:57.200
Who knows?

00:54:57.200 --> 00:54:57.500
Yep.

00:54:57.500 --> 00:54:57.840
All right.

00:54:57.840 --> 00:55:00.660
Well, let's maybe wrap it up there for the.

00:55:00.660 --> 00:55:01.300
Oh, go ahead, Chris.

00:55:01.300 --> 00:55:04.300
I was going to say maybe we need one of those awesome lists.

00:55:04.300 --> 00:55:06.680
Awesome lists of Pi Installer applications.

00:55:06.680 --> 00:55:07.640
Awesome list of.

00:55:09.120 --> 00:55:09.680
That's right.

00:55:09.680 --> 00:55:14.140
Mahmoud Hashemi just recently did an awesome Python applications.

00:55:14.140 --> 00:55:15.620
I'm sure there's a bunch.

00:55:15.620 --> 00:55:17.900
I know that there are a bunch of GUI applications there.

00:55:17.900 --> 00:55:21.060
You could go and package one or two of those up and put it on your site.

00:55:21.060 --> 00:55:21.340
Exactly.

00:55:21.340 --> 00:55:22.380
No doubt.

00:55:22.380 --> 00:55:23.100
Cool.

00:55:23.100 --> 00:55:23.320
All right.

00:55:23.320 --> 00:55:26.620
Well, let's leave it there for the packaging exploration landscape.

00:55:26.620 --> 00:55:30.420
And just, you know, talk about a few things really quick before I let you get out of here.

00:55:30.420 --> 00:55:30.840
Sure.

00:55:30.840 --> 00:55:36.640
Is there a rumor that you might be doing less typing and more talking and communicating with the world?

00:55:36.640 --> 00:55:37.300
Maybe.

00:55:38.720 --> 00:55:47.000
I've been exploring the idea of starting up my own podcast, something short form type thing,

00:55:47.000 --> 00:55:51.200
kind of 10 minute, 15 minute episodes with the idea.

00:55:51.200 --> 00:55:52.600
A little bit like developer tea?

00:55:52.600 --> 00:55:59.660
A little bit like developer tea where we just pick a technical topic based on some online article.

00:55:59.880 --> 00:56:16.480
People can send suggestions and we read through it, not in complete detail, but just kind of give you my take on it and just kind of analyze what it's talking about and how it affects just development topics in general and technologies.

00:56:17.280 --> 00:56:19.600
Well, if you get that out, I'm definitely looking forward.

00:56:19.600 --> 00:56:22.500
Are you going to call it the Try Accept Pass podcast?

00:56:22.500 --> 00:56:23.900
That's the plan for now.

00:56:23.900 --> 00:56:25.200
The Try Accept Pass podcast.

00:56:25.840 --> 00:56:29.100
I might change my mind on that, but I think that's good for now.

00:56:29.100 --> 00:56:29.480
That's cool.

00:56:29.480 --> 00:56:31.220
It could be Try Accept podcast.

00:56:31.220 --> 00:56:32.300
Try Accept podcast.

00:56:32.300 --> 00:56:32.700
Yeah.

00:56:34.340 --> 00:56:34.700
Yeah.

00:56:34.700 --> 00:56:36.420
If it doesn't work, make a podcast about it.

00:56:36.420 --> 00:56:36.780
Why not?

00:56:36.780 --> 00:56:37.580
Yeah, exactly.

00:56:37.580 --> 00:56:37.860
Right.

00:56:37.860 --> 00:56:39.780
That's the finally clause of the podcast.

00:56:39.780 --> 00:56:40.900
Either way, you're going to podcast.

00:56:40.900 --> 00:56:41.640
Exactly.

00:56:41.640 --> 00:56:42.720
Yeah.

00:56:42.720 --> 00:56:42.900
Yeah.

00:56:42.900 --> 00:56:57.580
So I was looking for a way to kind of diversify the content I'm putting out with the website, try acceptpass.org, which lately has been doing, well, just finishing up a series on CI/CD and all the different aspects of it.

00:56:57.580 --> 00:56:57.780
Yeah.

00:56:57.780 --> 00:56:58.880
And you have a newsletter too, right?

00:56:58.880 --> 00:57:00.560
That people can go sign up and hear about it.

00:57:00.560 --> 00:57:01.360
That's correct.

00:57:01.360 --> 00:57:10.240
If you're interested in the site and keeping an eye out for the podcast and everything that's coming up, just feel free to drop by the website and sign up for the newsletter.

00:57:10.900 --> 00:57:14.720
We're also open for any suggestions of anything you want to hear more about.

00:57:14.720 --> 00:57:17.380
Like my biggest request so far has been async stuff.

00:57:17.380 --> 00:57:19.340
So I'm going to be doing a few more things on that.

00:57:19.340 --> 00:57:23.560
Or if you want to contribute an article, it's a good way of getting yourself out there.

00:57:23.560 --> 00:57:24.400
Yeah, absolutely.

00:57:24.400 --> 00:57:24.700
Cool.

00:57:24.700 --> 00:57:28.840
Well, I know the articles you have out there so far are pretty good.

00:57:28.840 --> 00:57:30.320
So people should check it out for sure.

00:57:30.320 --> 00:57:30.620
Yeah.

00:57:30.620 --> 00:57:32.040
The articles are long form too.

00:57:32.040 --> 00:57:37.180
So expect 2,000 word articles more or less every couple of weeks.

00:57:37.180 --> 00:57:40.380
A little bit like a magazine type of article or something.

00:57:40.380 --> 00:57:40.640
Yeah.

00:57:40.800 --> 00:57:41.180
Yeah, cool.

00:57:41.180 --> 00:57:41.460
Yes.

00:57:41.460 --> 00:57:42.020
All right.

00:57:42.020 --> 00:57:42.360
Well, excellent.

00:57:42.360 --> 00:57:42.560
Yeah.

00:57:42.560 --> 00:57:44.940
So keep up the good work over there at trixatpass.org.

00:57:44.940 --> 00:57:46.100
I will keep on chugging.

00:57:46.100 --> 00:57:47.040
Yeah.

00:57:47.040 --> 00:57:48.940
The content creation, it never ends.

00:57:48.940 --> 00:57:49.860
No, it doesn't.

00:57:49.860 --> 00:57:50.740
It's fun though.

00:57:50.740 --> 00:57:52.060
I have lots of fun doing it.

00:57:52.060 --> 00:57:52.640
Yeah, that's awesome.

00:57:52.640 --> 00:57:53.340
All right.

00:57:53.340 --> 00:57:56.140
Now, time for the final two questions before you get out of here.

00:57:56.140 --> 00:57:58.880
If you're going to write some Python code, what editor do you use?

00:57:58.880 --> 00:58:01.020
These days I am using VS Code.

00:58:01.020 --> 00:58:01.640
All right.

00:58:01.640 --> 00:58:02.100
Right on.

00:58:02.100 --> 00:58:04.020
The remote extension is awesome.

00:58:04.020 --> 00:58:04.380
Yeah.

00:58:04.380 --> 00:58:04.640
Yeah.

00:58:04.640 --> 00:58:04.960
Very cool.

00:58:05.220 --> 00:58:10.900
I just read that Facebook has made VS Code their official editor.

00:58:10.900 --> 00:58:11.060
Oh, really?

00:58:11.060 --> 00:58:12.080
Yeah.

00:58:12.080 --> 00:58:12.800
Interesting.

00:58:12.800 --> 00:58:15.400
Which is a pretty interesting move there.

00:58:15.400 --> 00:58:15.920
Yeah.

00:58:16.180 --> 00:58:16.540
So it's cool.

00:58:16.540 --> 00:58:18.340
And then notable PyPI package.

00:58:18.340 --> 00:58:20.800
There's probably some in our list here.

00:58:20.800 --> 00:58:23.840
But what comes to mind, you're like, oh, you should totally know about this thing.

00:58:23.840 --> 00:58:25.160
I'm going to throw out Sanic.

00:58:25.160 --> 00:58:30.740
I've been using Sanic a lot lately as a REST framework.

00:58:30.740 --> 00:58:34.140
But it also has WebSockets integrated with it.

00:58:34.140 --> 00:58:39.680
And so you can provide both endpoints that answer HTTP requests and endpoints that answer WebSockets.

00:58:39.680 --> 00:58:40.500
And it's asynchronous.

00:58:41.000 --> 00:58:45.540
So I've been playing with async APIs, REST APIs using Sanic lately.

00:58:45.540 --> 00:58:46.260
Oh, that's super cool.

00:58:46.260 --> 00:58:46.460
Yeah.

00:58:46.460 --> 00:58:52.780
Sanic is one of the contenders for the hot new async ASGI Python web framework.

00:58:52.780 --> 00:58:54.680
So yeah, it definitely seems like it's a good one.

00:58:54.680 --> 00:58:55.000
Yep.

00:58:55.000 --> 00:58:56.720
I've had great experience so far.

00:58:56.720 --> 00:58:57.440
Oh, that's good to hear.

00:58:57.440 --> 00:58:58.060
All right.

00:58:58.060 --> 00:58:58.780
Final call to action.

00:58:58.780 --> 00:59:01.440
People, they got some kind of Python app.

00:59:01.440 --> 00:59:02.460
They got to package it up.

00:59:02.460 --> 00:59:03.500
What do they do?

00:59:03.500 --> 00:59:03.880
Yep.

00:59:03.880 --> 00:59:09.540
Just have a listen to the podcast and see where you land.

00:59:09.740 --> 00:59:15.440
Make a decision on who your users are going to be and what your best deliverable is.

00:59:15.440 --> 00:59:18.640
And make your choice based on that.

00:59:18.640 --> 00:59:24.880
If you can help out anybody to, like we were just talking about, produce some examples of

00:59:24.880 --> 00:59:27.660
how their packaging systems work, that would be great.

00:59:27.660 --> 00:59:28.020
Yeah.

00:59:28.020 --> 00:59:31.800
And if you're out there and you've built a cool application and you've bundled it up with

00:59:31.800 --> 00:59:35.900
one of these things, shoot a note back to the maintainer.

00:59:35.900 --> 00:59:40.400
Say if you use PyOxidizer, shoot a message back to them and say, hey, here's a cool thing

00:59:40.400 --> 00:59:40.880
I did.

00:59:40.880 --> 00:59:43.360
Could you feature this?

00:59:43.360 --> 00:59:45.020
Here's a picture you can feature on the site.

00:59:45.020 --> 00:59:46.180
Like, I don't know.

00:59:46.180 --> 00:59:47.540
I just think we need more of that.

00:59:47.540 --> 00:59:47.800
Yeah.

00:59:47.800 --> 00:59:48.300
I'm with you.

00:59:48.300 --> 00:59:50.740
And some of it, I know there's lots of apps already.

00:59:50.740 --> 00:59:53.660
And some of them might not even be using any of these systems.

00:59:53.660 --> 00:59:59.800
I think that just having examples of Python producing these types of system applications

00:59:59.800 --> 01:00:01.580
is just good for the language.

01:00:01.580 --> 01:00:02.020
I agree.

01:00:02.020 --> 01:00:05.000
It would start to break the chicken and egg cycle.

01:00:05.000 --> 01:00:05.600
Yeah.

01:00:05.600 --> 01:00:08.540
And I'm tired of hearing that Python is only a scripting language.

01:00:08.540 --> 01:00:09.540
Yeah.

01:00:09.540 --> 01:00:10.880
So am I.

01:00:10.880 --> 01:00:11.960
Awesome.

01:00:11.960 --> 01:00:14.080
Well, thanks so much for being here, Chris.

01:00:14.080 --> 01:00:15.440
It was a lot of fun to go through all this stuff with you.

01:00:15.440 --> 01:00:15.580
Yeah.

01:00:15.580 --> 01:00:16.380
Loads of fun.

01:00:16.380 --> 01:00:17.040
Thanks for having me.

01:00:17.040 --> 01:00:17.320
Yep.

01:00:17.320 --> 01:00:17.540
Bye.

01:00:17.540 --> 01:00:21.160
This has been another episode of Talk Python To Me.

01:00:21.160 --> 01:00:23.640
Our guest on this episode was Chris Medina.

01:00:23.640 --> 01:00:25.900
It's been brought to you by Tidelift and Linode.

01:00:25.900 --> 01:00:31.040
If you run an open source project, Tidelift wants to help you get paid for keeping it going

01:00:31.040 --> 01:00:31.540
strong.

01:00:31.540 --> 01:00:34.820
Just visit talkpython.fm/Tidelift.

01:00:35.240 --> 01:00:37.160
Search for your package and get started today.

01:00:37.160 --> 01:00:41.640
Start your next Python project on Linode's state-of-the-art cloud service.

01:00:41.640 --> 01:00:46.140
Just visit talkpython.fm/Linode, L-I-N-O-D-E.

01:00:46.140 --> 01:00:49.340
You'll automatically get a $20 credit when you create a new account.

01:00:49.340 --> 01:00:51.740
Want to level up your Python?

01:00:51.740 --> 01:00:56.580
If you're just getting started, try my Python Jumpstart by Building 10 Apps course.

01:00:56.580 --> 01:01:01.680
Or if you're looking for something more advanced, check out our new Async course that digs into

01:01:01.680 --> 01:01:04.760
all the different types of Async programming you can do in Python.

01:01:04.880 --> 01:01:08.700
And of course, if you're interested in more than one of these, be sure to check out our

01:01:08.700 --> 01:01:09.420
Everything Bundle.

01:01:09.420 --> 01:01:11.280
It's like a subscription that never expires.

01:01:11.280 --> 01:01:13.440
Be sure to subscribe to the show.

01:01:13.440 --> 01:01:15.860
Open your favorite podcatcher and search for Python.

01:01:15.860 --> 01:01:17.080
We should be right at the top.

01:01:17.080 --> 01:01:22.620
You can also find the iTunes feed at /itunes, the Google Play feed at /play, and the

01:01:22.620 --> 01:01:26.060
direct RSS feed at /rss on talkpython.fm.

01:01:26.520 --> 01:01:28.160
This is your host, Michael Kennedy.

01:01:28.160 --> 01:01:29.660
Thanks so much for listening.

01:01:29.660 --> 01:01:30.700
I really appreciate it.

01:01:30.700 --> 01:01:32.480
Now get out there and write some Python code.

01:01:32.480 --> 01:01:52.100
We'll see you next week.

01:01:52.100 --> 01:02:22.080
Thank you.