Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 285, recorded May 24th, and I'm Brian Okken.
I'm Michael Kennedy.
And I'm Mark Little.
I'm Ben Cosby.
Nice. Welcome, Ben. Welcome, Mark.
So, Michael, you have this story of why you brought Mark and Ben on.
Yeah, I did bring Mark and Ben on.
Mark and I have been really good friends for a long time, but that's not why he's here.
He's here because he's been sharing this Python journey that he and Ben have both been on.
They come from law, like being lawyers and bankers and stuff, and they've found their way over to writing software in Python.
And it's been so fun to watch you guys come along.
And you recently showed me the release of one of your SaaS products built with Python and Pyramid and other things.
And I thought it was just super cool.
So, I thought you could maybe share just a little bit of that before we kick off the main topics to kind of inspire people who are not, you know, traditional CS folks.
And they can still build amazing things.
You want to tell us a bit about yourself and then tell us a bit about your thing?
I'll say first that I'm strictly the hobbyist.
So, it's definitely been a collaboration and quite a journey.
And Ben, I'll talk a little bit about how we got started because you play an instrumental role in that, Michael.
So, we've released this product called LexChart that builds corporate organizational structures automatically.
And these charts are kind of weird.
They're sort of like, you know, human resources organizational charts, except that for legal entities, they're much more complicated.
And so, we've built some automation in Python principally in the server side that generates these hierarchies automatically.
And they can be quite elaborate.
So, for example, some of them we release publicly and we've been building these things with our own app and releasing them.
So, here's one for Elon Musk, for example.
This is before the early stages of his Twitter acquisition.
But our app does a lot of this layering automatically.
And those things can be quite stunningly complicated.
So, here's one, for example, with, you know, thousands of legal entities in the corporate structure of Blackstone.
And so, we've actually got some Python that sort of automates the presentation and structure of all that.
And then, as you say, it's using Pyramid and Chameleon and SQLAlchemy.
And then, a lot of, you know, legal and business finance expertise as well.
But it's been quite an exciting journey.
And so, you know, we were excited to share this with you and look forward to sort of talking about some of the piece parts that are in the product that might be useful to the broader community as well.
Yeah, yeah, exactly.
Some of the stuff you guys are going to cover today as our main topics sort of were extracted out of the building of this, right?
Yeah.
Ben, anything you want to add to that and maybe just tell people about yourself real quick?
As you pointed out, and Mark, too, you know, whenever I'm trying to explain to somebody what I do now, I always say, well, I'm a reformed barbarian at the gate.
I created buyouts and IPOs in a suit on Wall Street or, you know, code in my office at home and in my pajamas kind of thing.
And, but we've, as Mark talked about, we've kind of merged those couple of things together.
And so, these days, I spend a lot of my time with Python on the front end and JavaScript, sorry, JavaScript on the front end and Python on the back end and DevOps and all sorts of things, you know, sort of have to do it all.
But I also wanted to say kind of as part of our journey for your listeners, I'd be remiss if I didn't even know I didn't warn you beforehand I was going to do this.
But, you know, along this way of kind of, you know, going from, you know, suits and deals and IPOs and things like that, you know, Michael's Talk Python Training for, I'm sure lots of people on this podcast are familiar, but if you're not, you know, those courses were pretty instrumental for us and for those we've worked with in, you know, evolving and making Python.
Python now is completely central to our business and what we do.
So, it's been fun to get here.
Thanks for the shout out, Ben.
I appreciate it.
I would just say, too, we've been able to leverage that and, like, we've got some pretty complex math and graph theory, like, in the core of our app.
So, we've been able to, like, take, you know, Michael's classes and really sort of leverage them in a much bigger way than I think a lot of people expect or imagine they can when they start some of these online classes.
So, you know, your training in particular has been exceptional.
Thanks, Mark.
I just think what you guys have built looks so much more polished than a couple of guys who taught themselves programming a few years ago.
And I just, I love it.
So, super good work.
Brian, should we kick it off?
This is just great.
I'm blown away.
It looks awesome.
So, yeah, let's kick it off.
Yeah, I was, too.
And I think some of the stuff that we're going to talk about is going to certainly be part of that.
So, let's talk.
Oh, whoop.
Yeah.
Nope.
Wrong one.
I'm up next, right, Brian?
Yeah.
Sorry.
All right.
I have a whole bunch of extras, folks.
So, let me just, I'm going to start with, like, a quick one for one of our main topics here that maybe.
We may have to cut you off.
I know.
You might have to cut me off.
So, check this out, Brian.
If I go over to PyPI.org and I go look for something like, let me look at Beanie.
I don't know if I get that right.
Actually, I don't think that's going to help me right.
Let me look for SwitchLang, which is my Switch implementation.
I added to Python, I don't know, a couple years ago.
So, if you look over here on the left, oh, I think it's being blocked.
But over here, it says, here's your avatar from Gravatar for M. Kennedy.
But my little, I don't know, my browser settings are blocking that or whatever.
But, so, this is a thing you see a lot of the times.
And, like, where do you get these little Gravatar, right?
So, if you have users and you have users who have emails, you want to show something about them,
there's a chance that over in Gravatar, there's going to be some profile for them,
different images, things like that.
So, if you're in Python and you want to add Gravatar features to your site,
it is ridiculous using this thing called LibGravatar.
Oh, wow.
So, all you got to do with LibGravatar is you go and you create an instance of one of these objects, Gravitars.
You pass it an email.
And you can say, get image.
You give it a size and potentially a file extension if you want to control that or anything
or whether or not you want to use SSL.
And then it gives you back this non-reversible URL that is the image of that person based on the size that you asked for,
who they are, and so on.
And if they don't exist, you get the standard Gravatar logo, just like a little circle type thing.
And so, this is some kind of hash algorithm that you have to follow based on their email address to pull them back and so on.
But if you want to add that kind of Gravatar look and feel, then like literally, Gravatar object, give it the email address, dot get image.
And that's pretty neat.
It goes from 1 to 248 pixels on the image size.
So, I'm not sure one's super useful.
Like, you get one dot.
But, you know, maybe you want it to be kind of like a particular, like a shade of the person is all you're going to get, I guess.
Like a 5x5 would be fun, you know, just a few pixels.
It would.
So, you can do a get profile, which will then give you access to the user and see all of their email addresses,
all of their information about them, and so on.
So, there's a little bit more that you can actually.
Social security.
Oh, yeah, yeah.
There's this whole shadow profile that's built up by, like, you know, the surveillance ad tech industry.
It's only 5 bucks a use.
No, just kidding.
But you can get, like, more details about them through their profile if you really want.
But basically, the main use case is, given an email, can I get a picture without hassling this person to upload a picture?
Maybe.
And just so, if anybody's not familiar with Gravatar, it's owned by Automatic, who does WordPress.
So, all the WordPress people use it.
And that's why it's, like, well-supported and it's not too evil or anything like that.
Yeah.
And like I said, PyPI.org uses it.
So, that's the start.
Mark, Ben, what do you guys think?
Do you have user pictures in your app?
Are you worried about this kind of stuff?
We don't.
We don't in Let's Chart.
But it's funny because at the very beginning of our journey, we implemented a little question-answer app as, like, a demo to make sure that, you know, we could, like, justify going down to Python.
And I used Gravatar in there.
This actually is a pretty cool library.
Because I remember in that app, I really was just focused on Python.
But I had to, you know, fall back on some JavaScript in order to put the Gravatar icons in there.
But it is great.
Gravatar is really useful.
I'd encourage your listeners if you're looking for something.
Because the nice thing, as you said, is it'll just generate, like, this automatic little drawing, even if they don't have an image.
So you can kind of create a nice look and feel for your site, for your user profiles, where everybody gets some sort of a graphic, even if they haven't uploaded anything.
It's kind of a nice little tool.
Yeah, absolutely.
Kim Van Weck out in the audience says, when pixel Gravitars might be useful for building images, like displaying contributors and stuff.
Maybe not one, but you could do, like, 10 by 10.
And you could build up, you know, a montage of all the people or something that people.
And you also, Ben, you also have some cheering folks in the audience, which is lovely.
So go, Ben.
Good to have you here.
All right.
Brian, over to you.
I'm very excited about it.
When I first saw this, I'm like, oh, you don't really need that.
Pydantic does this on.
Oh, wait, no, this is amazing.
Tell me.
So this is so cool.
It's a little thing that was suggested by Chun Li.
It's a JSON to Pydantic converter.
And Chun said, this awesome JSON to Pydantic is so useful.
It literally saves me days of work with complex nested JSON schema.
So the idea is you've got basically it's just this website with, like, you know, a JSON side and a Pydantic side.
And I've got one prepared.
I went and copied one from somewhere.
And so if we go over and just replace the simple one with, like, a more complex one, paste it in there.
And then it just generates the Pydantic model.
And it's pretty awesome.
There's a couple of options.
So for people who are listening, it's not that it converts JSON to Pydantic.
It converts JSON to Pydantic code.
It writes the code that you would have to write for the Pydantic to understand what you put.
It's amazing.
I love it.
Right.
And then some of the options are cool.
You might not use it for everything, but just knowing the syntax for it.
So if you drop a give them optional, it'll tell you where to put optional in your model to make it all work right.
And it's like this one's only just showing up at the bottom.
So anyway.
And then the last one is aliasing camel case.
I didn't know you could do this.
Aliasing camel case for snake case.
So if you're using, I guess, both camel case and snake case, you can have them work.
I don't know.
A lot of times if you're consuming a JSON API that's written in another language, the variable names are idiomatic to that language.
So like C# would be or JavaScript would represent this one where you've got like the camel casing.
But that would not be how you would want to call it in Python.
So you can say, well, give me the Python version, but allow Pythonic to find the other size.
Okay, cool.
Yeah.
Then one of the neat things about this that I really love is it's an open source project.
So at the bottom, there's a link.
It takes you to the to the just the open source page.
And this is built with FastAPI and create react app, which is pretty cool.
And then a data model code generator.
So it's like that's doing the most of the work.
So if you want to do this yourself somewhere else by, you know, embed it within your tool
chain or something like that, you can do this.
So I don't know why you'd regenerate it all the time, though.
But it's just super kind of fun to just drop drop some JSON, a JSON example of a good one
in there and drop it in.
It's fantastic.
If you're going to consume an API and you say, here's a specification of what I'm going
to get back.
Boom.
You're halfway there.
Or you're a consultant.
You pick up somebody else's code.
And you're like, I want to use Pythonic here.
This is great.
Anthony on the audience is, oh, come on.
I could use this last week.
You guys, what do you think of this?
That's really cool.
We have a project where we're looking at migrating from a different tech stack to Python.
And, you know, one of our output sources there is JSON.
So I'm looking at this and, you know, wondering, you know, Ben, this might be an opportunity for
us to, you know, get there a little quicker for some of that data.
That is cool.
Especially for prototyping or something where, you know, you just want to see and you want
to spend three days seeing what it's going to look like.
This is pretty cool.
Yeah, it's very cool.
Also another, I mean, we get this all the time, but I just want to remind people, this
was a suggestion from a listener.
And that's one of the neat things about the podcast is people can find cool things and
send them in and then we can share it with everybody.
It's nice.
Absolutely.
That's like half of our topics are that, right?
All right, Mark, you're up with the next one.
Awesome.
So this is not a Python library and it's probably well known to most of your listeners, but I
wanted to just talk about a few Tailwind CSS things that people, if you're only sort of
casually aware of Tailwind, might help you jumpstart.
We are an aggressive user of Tailwind and some of the components.
The other piece I want to talk about is Tailwind UI, which is not open source.
So Tailwind CSS is completely free from Tailwind Labs.
But Tailwind UI is behind a paywall.
But these are pre-built components by the creators of Tailwind.
So there are lots of people building components for Tailwind.
But Tailwind UI is specifically built by the people who created Tailwind in the first instance.
And it's interesting to me.
I know that both of you have a lot of interest in user interface design around Python and web
apps and Tailwind certainly is a part of that theme.
And it's also interesting for the business model piece about how to turn sort of open source
into sort of a revenue generating model.
So you can use Tailwind and never need Tailwind UI.
But if you need examples or references, Tailwind UI is a fantastic resource.
And so I thought I would just show they've got widgets, basically pre-built components around
marketing or app UIs and then a new sort of e-commerce section.
And to give you an example, there's really low-level granular stuff.
Like if you want a little stats component, you can come in here.
They'll show you what it looks like.
They've designed several options.
You can see what they are like responsibly.
And then you can actually see the code.
And they'll give you the code in raw HTML, React, or Vue.
And some of them need JavaScript as well.
They'll give you hints around what to do with the JavaScript if that's necessary.
But this is an example of that little stats widget with all of the sort of Tailwind classes
built in there that you can grab and reuse.
And we have found it really useful for creating this sort of really professional sort of user
interface experience.
And our app, so for example, if I just quickly create one, like our toolbar here is a couple
of chameleon templates with Tailwind running around each of these buttons to keep them consistent,
which also means that at different resolutions, the buttons will look different.
So if I'm on a larger screen, there will actually be help text underneath each of these buttons.
They get smaller.
All that's done really nicely in Tailwind.
And then we can, because it's a chameleon template running in our Python stack, we can use those
toolbars in a variety of circumstances and have really granular, nice, intuitive control of them.
So, you know, between Tailwind CSS and Tailwind UI, these are sort of great resources to get
familiar and up and running with it.
There have been a few people.
This is so, Mark, this is so nice.
Just to give people a sense of like some of the size of the building blocks is we've all gone to the
websites where you click pricing, for example, and it's got like the three columns and one's
a little bigger and it says, this is the most common or whatever.
Yeah.
That is just a drop-in element.
Yes.
And it's so beautiful, right?
Yeah.
And this is the best thing about Tailwind from my perspective is it's built principally by Adam
Wathen and Steve Schroger.
And Adam, I'm probably grossly oversimplifying this, would be the technical component of this.
And Steve is the design element.
And they have some great resources.
If you just, Steve Schroger has some wonderful videos where he sort of recomposes user interfaces
and he's got a book out on refactoring UI that I think you can add to the show notes.
But you're basically standing on the shoulders of these giants, right?
These are fantastic design principles.
Yes.
I'm sure there are people that are better than me at doing this, but I know that Steve and
Adam have done a fantastic job in using these components.
Even if I need to tweak them, I learn a lot.
There are a lot of comments that people will learn a lot about CSS, just watching them work
and seeing how these components are built.
Tailwind automatically handles lots of cool edge cases.
And you see that when you look at these components and they're, you know, everything is built to
be responsive from the beginning and they're just lovely to work with.
Yeah.
It's also super fast.
So there are a bunch of components.
Their latest release has made their just-in-time compiler native.
So it's built in.
It does generate a lot of CSS, but it will only do that if you're actually using, you
know, certain classes or components.
And so it's just been fantastic to work with.
I will also say we used this in a recent project.
You can actually drop Tailwind into an existing project and avoid conflicts with existing CSS.
There's a way to have a custom prefix on all the Tailwind classes.
And both PyCharm and VS Code will, their Tailwind plugins will adapt to that prefixing.
So for example, instead of it, you know, if you need padding, you just append or pre-pinned
TW hyphen to the classes, to the Tailwind classes.
And VS Code and PyCharm will pick up that prefix.
They'll still give you all the helps and prompts for Tailwind.
And you'll avoid all the conflicts with your existing CSS.
Yeah.
It's amazing.
And then finally, I'd say it's just, it's great with, you know, template languages.
So whether it's Chameleon or Jinja or Mako, it's really nice because you're just looking
at that little bit of HTML in those templates.
And you can just put the classes right there in the HTML and have a high confidence in what
that's going to look like.
Brian, have you played with this any?
No, but one of the things I was having a, did a little consult with a, somebody trying
to get a startup off the ground.
And I was looking at their site and I was like, man, your site looks awesome.
Did you hire somebody?
And they said, no, I'd use Tailwind UI.
And actually, so that's the thing, the sweet spot, I think, is somebody that like maybe took
the Michael's entrepreneurial course or something.
And just like one or two people that are trying to get a business off the ground.
You don't have any money.
You can't hire somebody.
Or maybe you do, but often you don't.
Or it might just be too early to worry about that, right?
Yeah.
So starting off the ground with a professional looking site, I think that's a great way to
start.
And yes, it's not free, but it's also not out of the realm of a small startup.
Yeah.
I would add, we've used a lot of frameworks.
We've used Bootstrap, of course, Semantic.
We've used a lot of these things.
And what Tailwind is nice, particularly Tailwind UI, Tailwind in general, but Tailwind UI as
well, is they will give you full page references.
So if I scroll down here, you'll see, for example, there's this page example.
So if you need a landing page, they will show you what an entire landing page looks like.
But you don't have to take the entire page.
If you want to assemble these components individually into your own page structure, you can certainly
do that.
So here's a feature section.
It doesn't include any of the other stuff, but these are, if you like this feature presentation,
you can go grab just this bit and mix and match it.
So unlike a lot of the theme kind of frameworks where you have this entire theme that just sort
of stomps all over your design, you can actually get a custom looking output with Tailwind that's
still consistent.
So it's a nice balance between pretty modular granular control, but still a consistent look
of the entire app or website.
And I have no doubt that like the stuff behind it, like how much CSS is there and the
size, it's probably going to be a heavier site than having somebody custom write all this
stuff, but it's also going to be cheaper.
Yeah.
And that is true.
What they have done, they have a just-in-time compiler that really minimizes the amount of
CSS they produce.
And then, of course, you can do, they recommend using post-CSS and a number of other things like
CSS Nano to sort of reduce the size of those files.
We still get very high performance.
So keep in mind, sort of our app is built entirely with Tailwind, plus we're doing a lot of math
on the server side.
And we get, you know, very small sub-second returns on our pages as a result, even with
all that stuff.
Yeah.
That's cool.
You've definitely inspired me, Mark, to think about rewriting a lot of what I've been doing
in Tailwind.
And it'll get there.
I'm just not there yet.
I've got other stuff to work on first.
All right.
Before we move on, Brian, can I take a moment and tell you all about our sponsor?
Yes.
Yeah.
So this week, the show is brought to you by Compiler, the Compiler podcast from Red Hat.
Just like everyone on the show and everyone listening, Brian and I are fans of podcasts.
And I'm super happy to share Compiler with you.
It comes to you from Red Hat, a well-respected open source company we all know of, I'm sure.
So with more and more of us working from home, it's important to keep our human connection
with technology.
And Compiler unravels industry topics and trends, things you've always wanted to know about in
tech, all the way up to interviews with people who know it best.
So on Compiler, you'll hear a course of perspectives from diverse communities behind the code.
Conversations include questions like, what is technical debt or what are tech managers
actually looking for?
And do you have to know how to code to get an open source?
I was actually a guest on Red Hat's previous podcast, Command Line Heroes.
And Compiler is following along in that same tradition of being an excellent produced and
polished show.
So actually, the show that they just released, When Should Data Die, I think is one of those
cool sort of philosophical questions of, you know, should data have a lifetime?
Should your data be able to outlive you?
All those kinds of things are pretty interesting.
So I recommend people check it out.
Just visit pythonbytes.fm/compiler.
The link is in your podcast show notes.
I know we're all smart developers who are listening.
You can just search for Compiler in your podcast player, but please sign up by clicking that
link and then clicking your podcast player.
It'll help them know it came from us.
So thank you to Red Hat and Compiler for supporting the show.
All right.
I guess I'm still up, huh, Brian?
So let's talk peps.
This PEP is pretty interesting.
This comes to us from Itamar.
It's by Jermaine Bravo and Carl Meyer, sponsored by Barry Warsaw.
And it's something, honestly, I'm surprised it hasn't been covered or addressed yet.
I think this comes out of Meta's sender project where they're trying to do a whole bunch of
performance improvements, but I'm not 100% sure.
So I think that with a grain of salt.
Basically, the idea is right now what happens when I write some Python code, I'll write at
the top import requests, import Beanie, import FastAPI.
What happens when I import Beanie?
Well, inside Beanie, it says import motor, import Pydantic.
What happens inside motor?
It says import.
It's just this transitive closure of at the top of all of these projects, each one of them
is importing something and like parsing and compiling the Python code as in, you know, into
abstract syntax trees into memory and stuff like that.
All of that happens when I write one import line, right?
That's a lot.
But what if there's different paths in my code and only some of the time, maybe I'm using
Pydantic or only later in the app am I actually using FastAPI, but not right away.
And sometimes you might not use them at all, right?
I could do a bunch of data science imports, but only if a certain function runs do I care.
So this PEP, this PEP 690 says, well, let's not do that.
Let's not preload every possible path that you might run when you're going to use a library.
Let's wait until you use it.
So that import FastAPI kind of just hangs there until I say FastAPI dot.
And soon as the first line of code runs there, then the import happens.
So you don't have this transitive closure of all these imports if you're not actually going
to use them.
So it helps with startup time and it also maybe helps with overall performance if not
every bit of code runs.
I want this.
Me too.
It looks cool, right?
Yeah, you can spend a lot of time in startup just because of all the import statements.
Yeah, one of the things that I face a lot with helping people is with pytest.
So pytest imports your code.
So it does when it's, well, it imports your tests and then the tests will import your code
to run your code.
But if you're running, if you're going to like, for instance, stop on the first failure, you're
not going to hit a whole bunch of that code.
And so avoiding those and getting to start earlier, it would help that.
And that's just one example of startup time being helped.
Now, I'm curious about if it'll affect runtime early on otherwise, you know, at post-startup.
There's some conversations about compatibility.
So what could happen is there could be side effects that happen because of the import, right?
You're not supposed to make changes to the system, but that's arbitrary code running during
your import statement, right?
So it could have an effect.
So theoretically, this could change things.
And they refer to the not the lazy ones as eager imports.
But they do talk about how some of these, you'll have to pass a runtime flag to the Python
interpreter or set an environment variable for this to happen by default.
It won't happen by default.
It's off by default.
So for better or worse, maybe someday that'll change.
But right now.
That's pretty cool.
I like it.
Yeah.
Yep.
Indeed.
Ben, Mark, you guys have thoughts on this?
Yeah, I agree.
I think this is really interesting from the front end world where I spend a lot of time
too.
I mean, there's a billion analogs for this.
We do all kinds of jumping through hoops, you know, from the old day code splitting in the
old days and all kinds of, you know, web back and a million other roll up and all sorts
of ways of, you know, trying to take advantage of this on the client side, you know, because
the browser.
But I can actually imagine a lot of situations using Python where, you know, what in one app,
you know, maybe it is just limited to, you know, that moment of startup.
But I can imagine a lot of situations where the way that your app or your service is being
used is causing that, you know, initial run event to, you know, to be an experience that
the user is having on a more frequent basis, you know, based on what you're doing or what
you've constructed.
So that's actually really cool.
And I haven't thought much about this, but I kind of agree with you.
Sort of surprised now that I see it.
I should have always done this, right?
I've been in a more conversation before.
Yeah, absolutely.
And I also wonder if it allows you to have code that can be less, have more optional dependencies
installed.
So like, for example, I think it was a FastAPI.
There's some support for form stuff you have to install as a separate pip dependency.
And here you could just write that code and unless you actually run it, it doesn't matter
if you have import that thing that's missing because not until does it try to use it, is
it going to be a problem?
So it might allow you to write simpler code.
Let's see out in the audience.
Eddie Bergman says, I feel like with it opt in, many people won't know to use it, but making
it opt out could break so many systems depending on the behavior.
So yeah, it's I don't know what the right choice is.
So I guess the safe one is to just opt out or to make people opt in.
And Beanie, the author of, sorry, Roman Wright, the author of Beanie, gives it definitely a
thumbs up for this idea as well.
So support for some framework authors there as well.
All right, Brian, what do you got for your last one here?
Hope it's something rich for us.
Well, I've got a couple of things that a couple of these are small.
So it's sort of a multi-grab bag.
pytest Rich.
So this is a plugin for pytest that uses Rich.
Not much more to say other than it's kind of cool to use Rich to have some nice output.
This was done by Bruno Oliveira, who is he's one of the core people on pytest and also the
only other person on the planet that I know of that has written a book focused on pytest.
But cool guy.
He said this is a proof of concept and he'd love for somebody else to take it over.
But it doesn't look like it's like dead or anything.
It's good.
It's some activity.
So anyway, I think this is fun.
So cool opportunity for people to jump in if they want to.
Thanks.
The question from the audience, Ryan, how's it compared to pytest sugar?
I haven't used sugar for a really long time.
But you can look at the image.
So it looks like similar to sugar.
But sugar doesn't have these cool rich tracebacks in it.
So there's that.
Yeah, indeed.
So the next thing I wanted to talk about before we move on to somebody else is a short little thing.
This was a recommended by actually the pytest rich was recommended by Brian Skin.
Thanks, Brian.
And then this is recommended by Henrik Finsberg is a video by Anthony Sotilli on how to get images and read me.
And I guess I didn't know how to do this.
We encourage and I wanted to bring this up because we encourage everybody to put pictures and animated GIFs and all that sort of stuff in your read me so that when we review stuff, we can see what it does.
It helps.
But it's not hard.
So Anthony goes through this little thing of like, you don't have to put the image in your repo.
You just have to drop it into a comment field or in a repo edit field.
And then GitHub will just put it on a CDN somewhere.
So the image is just there.
So some magic there.
Kind of trick GitHub into uploading it and then not actually.
Well, I mean, since the read me supports it, it's interesting.
Anthony talks about going using the using a edit a comment field of your issues to drop a picture in and then you get the URL from that.
But if you just go into your read me in within GitHub on the web interface and edit there, you can also drop it there.
And it just works fine.
I guess maybe he's thinking that you're probably not going to edit your read me directly.
You'll probably edit it locally and push it in.
You can still do that.
But anyway.
It's neat.
Yeah.
Very nice.
That's cool.
Yeah.
People should definitely have pictures and explanations and charts and all sorts of stuff in there.
They're reading me.
So this is great.
Yeah.
I would just add more generally, you know, docs and tutorials can be a strategic asset when done well.
You know, Tailwind does this amazingly well.
EdgeDB does it really well.
DigitalOcean is off the chart in the comprehensiveness and thoroughness of there.
And those things become an asset for the business.
Instead of an annoyance, you know, that you have to do, the docs actually become valuable for the project or the business.
Yeah.
Do you want to be there or do you regret that you have to go there, right?
Right.
Exactly.
All right.
Ben, you want to take us out of here with your final main topic?
Yeah.
So, you know, as you mentioned, part of our latest project, LexChart, that Mark's talked a little bit about, you know, one of the things that we had to do, despite the fact that, you know, as we were getting close to it,
I realized you can use LexChart for a lot of things that maybe, you know, we didn't think about when my 12-year-old daughter sent me, and I spun her up an account so she could tinker with it,
so I could kind of get an interesting test case out of somebody that has, like, no connection to what we're doing.
And she sent me a little organization chart of Encanto characters and their family tree from the movie Encanto.
So I wasn't expecting, but she's not really our typical user.
And with our target audience, who looks a lot like, you know, I did in my former life, you know, security is a big, big deal with our clients.
And so one of the things we obviously had to look at is, you know, we need to implement some multi-factor authentication.
And, you know, initially, my, you know, knee-jerk reaction to that was, okay, yeah, we'll just do what everybody does,
and, you know, we'll set it up, and you'll get an SMS message on your phone and all that kind of stuff.
But as I looked at that more and thought about some of the conversations we'd had with clients of some of our other software,
you know, I wondered, how long is that really going to last?
Because there's a number of kind of real security issues with SMS, not least of which is, you know,
just the way voice networks are built.
Everything's sent in clear text.
It's actually really not that hard to, you know.
Yeah, it works, but people do look down upon it a little bit.
They're like, oh, this is not quite real security.
This is better than nothing but, right?
Yeah, exactly, right?
And it's not to say, you know, you make me a point.
It's everywhere.
Everyone's using it.
And, you know, by the way, yeah, absolutely.
You know, password, bless MFA, even with SMS, is great.
It's so much better than the password only from a security standpoint.
So it's not a knock on it.
You know, I just, well, maybe we need to step one more step forward here and see if there's some other things.
And so, you know, I was looking for a library that could help us with one-time password stuff,
and specifically one that could help us with time-based one-time password implementations,
which is something that I think Google really ultimately started this way back.
And that's why a lot of people associate this with the Google Authenticator app.
But there's actually a lot of authenticators.
It's an open standard.
And it really is closely connected to what's happening when you do it with SMS or with email.
Both of those are similar in that, you know, both of these approaches, they just lean on a moving factor.
So in the case of your SMS, that moving factor is just usually like a counter in the database, right?
Just kind of clicking for it and whatever.
And that's, you know, along with all the other secret sauces, you know, generating, you know, these temporary codes, if you will.
In time-based, the moving factor is time.
And so what that allows you to do is, you know, have an authenticator app where you don't actually have to communicate with that at all.
But, you know, based on a shared secret, again, same as how you do with SMS, you're able to, you know, sync up these passwords.
And then they have like kind of a, they sort of explode, if you will, right?
You know, so they last for like 30 seconds and all that kind of thing.
And so, yeah, the library you're highlighting here is PyOTP, which I guess lets you do this really easy in Python, huh?
It does.
Yeah, it makes it really, really straightforward.
So, you know, I've, in the notes, you know, people will be able to see, I put a couple of representative, you know, functions that you could use to do this.
But it's a very small amount of code.
Basically, you generate a secret, you store it with your user credentials.
Then, you know, when you're actually verifying somebody, you know, they come in, you have the shared secret in there.
They, you know, pull up their little authenticator app on their phone.
You know, I think most people know what this looks like, but we'll do this there.
So that's the Google Authenticator app.
And so it gives you a little code and you can see it ticking down and all that kind of stuff.
And so instead of getting your SMS, you just pull up your code, you hit your app, you type it in, and then your user's putting that.
And then you're just running that through the verifier.
And based on this shared secret, it says, yeah, you're the real guy.
Great.
And every 30 seconds, those go away.
So even if somebody, you know, just looked at mine for my Google Authenticator, you know, you got, you know, 30 seconds to figure out my password.
Exactly.
See if you can get into that test account that I'm showing you that for.
But yeah, it's super, super simple to implement.
The only thing, you know, for the Python crowd here is that it is helpful from a setup standpoint to do a little bit of front-end work.
Because the easiest way for users to set this up is to scan a QR code.
And so we have that implement on the front-end where you can see, you know, that QR code and scan it from a setup.
But those little functions I put in the show notes, you know, you just spin up a little URI.
You can put that into any kind of QR code generator, including Python-based generators if you actually want to do that.
Store the image on the server and then serve it up.
In our case, I actually do that on the JavaScript side.
And I put a little link to QR code.
It's just kind of one of the most widely used, you know, NPM packages for that purpose.
Display that to users.
They scan it.
They set it up.
They pair that first time.
And then, you know, it takes a little getting used to for the user.
I think, you know, at the end of the day, SMS is a little more user-friendly just because people are a little bit more familiar with it.
This isn't a big leap.
So we went here instead of something like WebOften, which is, you know, even probably better from a security standpoint.
But I think a bigger leap for users.
So I just think it's a cool little library.
It's easy.
It's purpose-built.
Literally those few lines of code that I put in the show notes, it's almost everything that you would need to implement this on the back end.
There really isn't anything else.
It's amazing.
I've always avoided doing this because I'm like, ah, it's probably kind of complicated.
I don't want to screw it up and unlock people out.
But it looks really simple and fantastic and straightforward.
So, yeah, this is a great suggestion for people.
Yeah.
Cool.
Brian, have you had to do any of this?
No.
But I do have, like, a SaaS app in the works that, like, I don't think I'll get that complicated.
Because I think for somebody, like, with GitHub, we have to use it, like, something like that for GitHub now.
Or you can.
And I have set it up.
But some people, for some kind of apps, it depends on your audience.
Some audiences aren't really going to want that.
Sure.
It also depends on what you're protecting.
Yeah, exactly.
Most of our clients, you know, are B2B, large corporations, sort of all over the world.
And many of them already have these authenticator apps.
And the nice thing about this solution is it works with any of them.
So you don't have to, as a business, you don't have to direct your clients to use a particular authenticator app.
So if you're using Microsoft or Google or Twilio's Authy or any others, you know, you can just plug this in and just use it.
You know, we test and validate on those three, but it'll likely work on any of them.
And so it's really nice in that corporate environment just to slide in.
Yeah, and I should have emphasized for this audience, one of the great things about this is SMS is not expensive, but this is free.
It's free for you from a developer standpoint, and it's free for your users.
These authenticator apps are free downloads.
This isn't, you know, you're not imposing any friction on your users from that standpoint.
Just a tiny bit of a learning curve for them.
But I think what you find, like you said, GitHub, you can link an authenticator app to GitHub if you want to add MFA to your GitHub login,
which, you know, I would say most of your listeners probably are familiar with.
And so, you know, if you're wondering about it, I'd encourage you just try that.
Download Google Authenticator, Microsoft Authenticator, implement their MFA.
You'll see what the experience is like, and you'll probably find that not really probably a big hard sell with your clients.
If, in fact, MFA is something you need, as you say, you don't need it, you don't need it.
But if you do, you know you do.
And, you know, this is a solution I think people should consider because I think SMS, you know, is fine and great.
But obviously, the more widespread it becomes, you know, the more likely, you know, people are to attack it.
And the hacks on this are not hard.
My favorite one is using a cell signal booster, which, you know, some of you heard of, especially some of your listeners that don't live in urban areas and whatever.
And, you know, I'm not encouraging this.
But if you poke around just a little bit, it's not going to be very hard for you to figure out how to hack a cell signal booster.
People don't even know they're attached to it.
And you can listen to everything and record all their texts and all that.
So, yeah, that's just.
That's a nervous.
Brian is getting ideas.
I got to go, guys.
I love having this.
I use Authy and I just checked.
My Authy has 45 different accounts doing 2FA, MFA, which is fantastic.
Yeah, I like Authy as well.
Brian, what else we got?
Well, I've got a few extras.
Do you have any extras?
You know I do.
All right.
Yeah, I'll do mine first.
So let's start with some real quick ones.
First of all, Mac Rumors points out that the machine learning framework PyTorch, traditionally these have been like mainstream GPU, these machine learning training frameworks,
and especially focused on NVIDIA, which if you're on a Mac is a problem because you don't have NVIDIA.
Not even before the M1 stuff, you had Radeon chips and stuff.
So doing hardware-based machine acceleration was really tricky.
They are now supporting Metal on Apple, which means you get GPU-accelerated training on the new Apple Silicon Macs, including the M1 Ultra and all that stuff.
So if people are on M1, they may check that out.
That sounds good.
Let's see.
I got a message from Harry.
This is a 15-year-old kid who said, hey, I built this learning platform and a bunch of tutorials with my cousin, Anna, who's 14.
And they built this app, which I'll link into, called Mission Encodable.
And you come in and you can do little tutorials and you've got like little lessons and achievements to do after and stuff.
So anyway, I just thought I'd give them a shout out because it's really cool that a 15 and a 14-year-old put this together for people.
Yeah, very cool.
Yeah.
All right.
Two real quick things as well.
I use Calendly.
Calendly.
Not stating that.
That's how it's supposed to be.
Calendly.com, which is great for like sharing your available free time.
People can sign up and book slots with you.
I recently learned about Cal.com, which is an open source parallel or equivalent to Calendly.com.
So if you can self-host it or you have a free version, you can even have them host it for more pro things if you want.
But I just thought it was kind of cool.
There's an open source Cal.com, which is Calendly.
And on the same vein, if you heard about Firebase, which is kind of like the back-end platform for so many mobile apps and stuff.
So you don't have to have a website and an API and a database and users like this would handle all of those things for Firebase.
I also heard about Supabase, like super but without the R, Supabase, which is the open source equivalent of that.
So you can have sort of like the back-end cloud for free for your open source for your mobile things if you care about that.
And yeah, so those are my – oh, I have one more extra I want to share with you.
So we've all heard about PyScript, right?
PyScript is awesome.
This comes from Anaconda, takes the CPython runtime and turns it into WebAssembly and then runs it in your browser.
And I've been looking at the PyScript.net website, and they've got all sorts of cool stuff in there.
And if you go to PyScript slash examples, there's actually a bunch of examples.
You showed the one – you covered this last time.
I think it was last time or time before.
You covered the anti-gravity one and those kinds of things, right?
What's lacking from here is anything that looks like a regular application, right?
Yeah.
So I said, well –
It was the ToDo app.
The ToDo app is not a regular – you got it.
Come on, man.
No, no.
You're right, though.
That is the absolute closest by far.
But everything here says data science, data science.
I want Jupyter in the browser but not with a server.
Run it in the browser.
And that's fine.
But that comes, I think, far short of the potential, okay?
Yeah.
So this weekend, I'm like, I'm going to fix this.
And the way I'm fixing it is with this project and a video that I was working on right before we jumped on.
I'll publish it later today.
It's called the PyScript PWA weather app.
So check this out.
See this thing here on the screen?
This is an application that installs in your dock offline.
It installs in your dock.
It's written in Python and PyScript and with Python on the front end and has no back-end stuff locally.
It's got like Electron or something like that.
It's a progressive web app.
It downloads all the files, including the 15 megabytes of the Pyodide runtime in PyScript, puts it offline.
And when you run it, it just starts instantly.
So from a cold launch until you have this thing up and running, it's about two seconds.
And it goes out and it talks to an API and gets this cool weather here.
And you can have a little button.
You press this refresh button.
It goes pop, pop, pop, and it'll refresh.
It's as you click it, it's instantaneous the way it sort of interacts with it.
And all of it is written on the front end using stuff that you would recognize, stuff that looks like requests and JSON and Python classes and try accept and everything.
That's pretty cool.
It is.
Here, let me actually pull up a little bit of code really quick just to show you all.
So check it out.
We've got our regular code.
Here's our flask bit.
But if I go to static, there's now a Python folder in static.
And you can go to the weather API.
And let me make that bigger for the screen.
See this code right here?
It's download a report.
Type in, goes to report.
It has this thing that comes back from calling this URL, turns into JSON, does the URL.
It's hardly any code.
That.
Nice.
That is running in the browser in the CPython runtime, all of it locally with no download and no slow startup.
So.
Pretty cool.
Anyway, I'm going to do a video on that.
And I'll, yeah, what do you guys think?
Neat, huh?
Yeah.
PyScript is.
And that's cool what you've done too.
PyScript's interesting to me.
I'm interested to see how that evolves.
I'm sure, you know, like you said, I think most people are using it maybe from a data science standpoint or waiting for it to, you know, mature or whatever.
But there's some kind of odd analogs between, you know, how React and some of those things got started here.
Obviously, you angled a different audience.
But I think, you know, there's some really cool things that could be done with this, you know, as, as you evolve.
And interesting that you mentioned this on the show today, because if you look in the repo for PyScript, Tailwind is one of their core dependencies.
Oh, nice.
How interesting.
Yeah, it's all coming together.
So I'll talk more about it when I release the video later.
But I think that this, and the source code is out.
It's linking to GitHub.
People can check it out and install it.
It's really neat.
And I think it opens the door.
I can see people writing like a Vue.js wrapper.
So you create a Python class that sort of parallels Vue or React or something like that.
And you could create really neat stuff in this offline sort of progressive web app mode.
So we'll see.
All right.
That's it for my extras.
Okay.
I've got a few.
The videos for PyCon US 2022 are up.
So, yay.
You can watch them now.
I'll have a link in the show notes.
But you can also just look on YouTube and search for PyCon US.
Yeah.
So I'm looking forward to it.
I've got a whole stack of ones I want to watch.
I unfortunately didn't get a chance to make it this year.
So I'm looking forward to participating in this way.
Second thing I wanted to bring up is another podcast.
So there's another Python podcast out there called the Sad Python Girls Club.
So far they have two episodes.
The second episode they interviewed Brett Cannon.
And it's good.
They're not actually sad.
The sad comes from that they used to be emo people when they were young.
So I thought that was interesting.
So I listened to a lot of the same music.
Nice.
All right.
Congrats to them for starting that.
That's cool.
Yeah.
Third thing was is I'm going to do this publicly to try to get me motivated to finish it.
The pytest course.
So yes, I've started work on a pytest course.
And it will be through the Talk Python Michael Kennedy thing.
Unless, you know, unless it's really terrible.
And then he probably won't want to do it.
No, it'll be great, Brian.
I'm looking forward to it.
Yeah.
So I, man, a couple of days ago, I recorded like 20 minutes for the video with the mic off.
I've done that.
Or two mics on where there's a weird echo.
It's offset by 20 milliseconds.
And no.
But I'm looking forward to getting that out because a lot of people have asked for it.
So that's in the works.
Fantastic.
I think that's cool, Brian.
You need to finish it.
We're all a little, none of us, none of us write enough tests.
We need more.
We can use the course.
That's all for me.
Mark, either of you guys.
Yeah.
You got anything else you want to give a shout out to before we wrap it up?
I guess I better shout out.
Go ahead, Mark.
No, I said I better shout out since you highlighted the cheerleaders earlier.
I'm pretty sure that was my daughter, Isabel, and a friend, Olivia, and Jess listening.
So if they've hung with us this long through Python podcast, then I better shout out to them.
Thanks.
Right on.
That's cool.
And I would just say, if you're interested in any sort of public company, complicated organizational structures like Tesla or Apple or anything, we have some of them on our website on LexChart.
And if you want others, just drop us a line and we'll build them.
Nice.
Yeah, that's very cool.
All right.
Shall we close out with a joke, Brian?
Yes.
I wanted to come up with something that I felt was a little bit associated with learning to code and being somewhat beginner, even though what these guys built is not at all beginner.
But I know that they've been on that path recently.
So here we go.
So this one is an animated GIF of a very frustrated person carrying their computer out, throwing it in the dumpster in the back.
It says, programmers, when they finally fix all their syntax errors in their code, just to be confronted with a bug.
I don't know about you.
I remember when I was learning C++.
I was so happy when I got my complicated code to compile.
And then I realized, no, that's just the beginning of the hair pulling part.
Yeah.
It's Ron Swanson.
Yeah.
Absolutely.
All right.
Thanks a lot.
That's all I got, Brian.
Excellent.
That was fun.
Thanks, Ben and Mark for showing up.
And thanks, Michael, as always.
It's been fun.
Thank you, guys.
You bet.
Bye, everyone.
Bye.
Cheers.