Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 297, recorded August 16, 2022, and I am Brian Okken.
I'm Michael Kennedy.
It's good to be back and be with you, Michael.
Yeah, it's great to be back. Not in the usual location today.
You may hear some nature sound shmaiya and apologize if animals go crazy,
but there's construction, which is guaranteed to be a problem in my office.
So I'm sitting in the backyard. We'll see how it goes.
Yeah, for people that are listening to the podcast, the live stream people get to see his lovely view from his backyard.
Some nice trees.
Yeah, big trees. It's all Oregon backyard here.
Nice.
But also, I also want to say this episode is brought to you by IRL podcast from Mozilla.
So we'll tell you more about that later, but thanks to Mozilla and the IRL podcast for supporting the show.
Thank you.
Let's talk about writing code by not writing code.
Does that sound like a good idea?
Well, okay.
Not in the low code, no code sense.
There's actually some pretty cool tools in that space, but that's not what I'm talking about.
Imagine, Brian, somebody says, we used to be a .NET shop and we have this huge database and all of our code to talk to it is in some other language or it's Ruby or it's Java or whatever.
It's not Python.
And you decide the best way to talk to this database is with some flavor of SQLAlchemy.
SQLAlchemy straight.
Or if you prefer, you could have it with data classes or you could even mix in a little sprinkling of SQL model if you're doing async and FastAPI and pydantic.
Whatever choice you want to make from that perspective.
If you're looking at a database with 150 tables and all sorts of gnarly relationships, you might say, well, I'm going to have to spend the next week planning out how to model those out so I get them to exactly match the database.
Is it a Varchar?
Is it a Varchar with a limit like Varchar 10 or, you know, what?
That doesn't sound fun, does it?
No, no.
Not, not.
I mean, at least for me, maybe some people that's a special kind of fun for them.
But Josh Thurston sent over this project called SQL A for SQLAlchemy code gen.
So I'm taking that he doesn't think it sounds like fun.
I certainly don't think that it does either.
So people should check this out.
It's it looks really cool.
And what you do is it's it's an automatic model generator for SQLAlchemy.
What does it generate it from?
So what you do is you go through and you point it at some database.
OK.
Just say SQL A code gen and you give it your connection string.
For example, Postgres SQL colon triple slash some database connection string.
And then magic happens and you have a whole bunch of Python classes that are attempted to look handwritten.
So instead of taking all your time, like a week to model out the database and the relationships and all that stuff in Python, you run this one command line thing and then you have all the classes and then you can tweak them a tiny bit if you see fit.
OK, so this is OK.
You probably said this and I missed it.
But so you already have data in a database and you're trying to hook up an application to it.
Yeah.
Which is why I went on my theoretical theoretical example.
I have a database.
I have code that talks to it, but it's not Python.
And so there's not really something to work from.
But I've got a really complicated database that's been around for a while.
It doesn't have to be complicated.
But the more gnarly the database, the more you will appreciate this tool making, you know, doing it for you.
I think I have this situation.
I totally want to use this.
Yeah.
So it does a bunch of neat things.
It's written to read the structure of an existing database and generate the appropriate SQLAlchemy model code using the declarative style if possible.
So deriving from SQLAlchemy declarative base.
It's also there was some other tool called SQL Auto Code, which apparently has some limitations, such as, for example, it doesn't support Python 3 or recent versions of SQLAlchemy.
That seems like a pretty large limitation, but whatever.
So this supports the newest version.
It produces PEP 8 compliant code, tries to make it look like you're writing code by hand so it doesn't look auto-generated.
It automatically detects join table inheritance and all kinds of things.
So if I scroll down here, it's got these different generators.
So you can generate table objects for people who don't want to use the ORM because SQLAlchemy has these two flavors, like a low level, slightly above just raw SQL, and then the ORM, which is the one that I use all the time.
By default, it uses the ORM one, but you can also use, like I said, data classes, which is pretty excellent.
Yeah.
Instead of, you know, in case that's what you want your code to look like, or even better than that, you can use SQL model models or using SQL model, which is the project.
I'm sure we've discussed it before by Sebastian.
It's based on Pydantic and Async, but then it's built really on top of SQLAlchemy.
So if you're looking to do the newer version of that, you'll get this.
By the way, just thinking about it while I'm looking at this, maybe I have actually a SQLAlchemy generated database, but it's written in the older style of SQLAlchemy.
And it's not using SQL model and I want to just upgrade to SQL model.
You might be able to use the database to just go rewrite it for me again.
But in this, in this flavor, you know, or use it to generate the data class version.
That actually looks pretty cool.
Or do all of them and look at it and see which one you looks, looks like it's more fun to maintain.
Yeah, exactly.
So there's a whole bunch of options and stuff that you can use, but you can basically pass a bunch of command line arguments and stuff to change how it works.
Cool.
Like change how it names objects or change how it names fields, et cetera, et cetera.
People, if they really want to look into it and use it, I think they all got the idea from this.
Okay, cool.
What do you think?
Sound cool?
Yeah.
Looks really cool.
Yeah.
Anytime you've got a database, they're so hard to model because you've got to get the SQLAlchemy code to match it just right or it won't work at all.
And yet, you know, do you really want to do that by hand?
No, I don't.
And so SQL A code gen.
Thanks, Josh.
Well, I am going to talk about package.
I've been, my headspace is in packaging lately because I'm preparing a talk for next month and it's going to have some packaging stuff in it.
So this is really exciting.
I heard from Juan Luis Cano Rodriguez.
Rodriguez?
Sorry.
SetupTool664.00 is out and it ships with PEP660 editable installs.
So this, the big headline is not that, although that's really cool.
It's that most projects don't need a setup.py or a setup.cfg anymore.
Those can be gone.
And not that setup.py was evil, but it kind of was evil because what it does is it runs Python, runs Python while you install something.
Like when used normally, it's fine.
But it has this tremendous gaping hole for abusing things at different levels.
Yeah.
And the, the, okay.
So the caveat on this is the reason why it has that is sometimes it goes out and compiles stuff if it's not just pure Python stuff.
But you don't need that for that.
You, you, a lot of projects, most projects don't need that anymore because they're not really compiling stuff.
If they're on during pip install, they're, they're compiling stuff ahead of time and they have their separate wheels for different architectures.
So I like that model better.
So anyway, the, I'm like pretty excited about this.
So there's a, so yeah, congrats to the pipe PA for getting that done.
We've got, there's an article called development mode, editable installs.
So here you've got pip install editable that works with setup tools without a setup.py.
Used to have, have to have a shim.
So everything can be in piproject.toml now.
And, and so one of the cool things, and I actually discovered this also at the same time I was researching packaging stuff.
The pipe PA has this really cool guide packaging Python projects.
And they, what's neat is they keep it up to date fairly well.
And this whole tutorial, it's a simple, so you got a simple Python project and you want to try to learn how to package.
They have this, this page here.
It's nice.
There's no mention of setup.py or setup.cfg.
It's all pyproject.toml.
Oh, wow.
That's awesome.
Here's how you do it.
And you don't even talk about the older, more troublesome way.
Yeah.
And since setup tools and pip are not part of Python proper, they're separate things.
Well, I mean, you get pip when you, when you download Python, but you get a version and you usually upgrade anyway.
But setup tools is separate.
So they can move at a faster pace than Python itself.
Oh, right.
Okay.
Excellent.
Well, this is great news.
Anything that makes the supply chain side of Python stronger is good.
Yep.
Indeed.
Well, before we move on to the next thing, Brian, let me tell you about our sponsor.
All right.
So this episode of Python Bytes is brought to you by the IRL podcast, an original podcast from Mozilla.
If you're like me and Brian, we care about ideas behind technology, not just the tech itself.
So we know that tech has an enormous influence on society.
Many of these effects are hugely beneficial.
Just think about carrying all of the world's information in our pockets sort of thing.
But other tech influences can have negative effects.
And I really appreciate that Mozilla is always on the lookout for and working to mitigate negative influences of tech on all of us, all the tracking stuff they're doing, but a bunch of awareness things as well.
And so if these ideas resonate with you, you should definitely check out the IRL podcast.
It's hosted by Bridget Todd.
And this season is very much in the focus of Python.
It's AI in real life.
So who can AI help?
Who can it harm?
The show features fascinating conversations with people who are working and building more trustworthy AI.
For example, there's an episode about how our world is mapped with AI.
And it's the data that's missing from those maps that tells as much of the story as the maps themselves.
Another one's about gig workers and how they're pushing back on algorithms to create better working style.
And for political junkies, there's an episode about how the role of AI plays when it comes to spreading disinformation about elections.
Obviously, huge concern as just across the world for all the democracies.
I also just listened to the tech we won't build, which explores when developers and data scientists should consider pushing back on projects that can be harmful to society, even though the machine learning can easily be turned on them.
If this sounds interesting, try an episode for yourself.
Just search for IRL on your podcast player or visit pythonbytes.fm/IRL.
The link is in your podcast player show notes.
Thank you so much to IRL and Mozilla for supporting the show.
I've been listening to it.
It's a really great show, too.
Yeah.
I enjoy it as well.
It's not super, super technical where it's all about APIs and stuff.
You can kind of just kick back and enjoy it.
Not like this podcast where we're super technical.
Exactly.
Yeah.
We talk about a bunch of technical things, sometimes not too deeply, huh?
Oh, I like it.
I like our level.
Yeah, I do, too.
I do, too.
Before we get on to the next topic, I just want to do a quick audience comment from Anna here.
It says, hello from London, UK.
SQL code gen sounds like it could save a lot of headaches.
Yeah, I think it's going to be great.
Yeah.
And feedback for the tutorial that you highlighted, Brian, on python.org.
Yep.
Henry Schreiner says, it took around six months for my rewrite of that page to get accepted.
Well, thank you for all the hard work, Henry.
That's awesome.
Great job.
It looks great.
Yeah.
Very, very cool.
Previously, I had talked about async cache.
Remember that?
Where it's like the functools, LRU cache, but a little bit more.
However, you can apply it to async methods.
Owen Lamont said, you may also be interested in AIO cache.
What this one does is this lets you use proper distributed backends for caching.
So, for example, if you're on a web app, you might have five, six, ten, maybe many more worker processes,
either on one machine using the supervisor mode of like G-Unicorn, or it could be even across different computers.
If you're using that in-memory version of cache, every time the request goes to a different part of your site,
or different runtime, different process running your site, you've got to recompute it, right?
Well, this one also supports Redis and Memcached.
Oh, sweet.
Or Memcached.
And it has a common API across all of them, which is pretty fantastic.
And they're all async and awaitable, which is cool.
So, it aims for simplicity rather than trying to highlight all the nuances of that particular, say, to Redis versus the others.
So, it has an add, a get, a set, a multi-get if you need to say, give me the values corresponding to these four IDs,
or does this thing exist or not, delete, clear, even increment a value, like how many people view this page, increment that in the cache.
And it's shared across, like I said, ten worker processes across machines instantly.
How cool is that?
That's pretty cool.
Yeah, so, super easy to work with.
You can install it, but then you should also reference probably the specialization that you're using or the backend that you're using.
So, for example, you can say pip install AIO cache, but if you want to use Redis, it's bracket Redis.
If you want to use Redis and Memcached, you might say, you know, bracket Redis, Memcached.
They have message pack and different formatting.
So, depending on how you're using it, you might have to install some dependencies, okay?
The optional install mechanism of pip is pretty cool, though.
It is.
It is pretty cool.
So, you just import asyncIO, easy.
And then you import AOCache, and you've got to, you know, just basically run your loop somewhere.
Or if you're using something like FastAPI, just that thing's generating or managing the loop for you, so you don't have to worry about it.
So, you can just say await cache.set, key, comma, value, await, cache.get key.
Sounds pretty straightforward, right?
You can even use it as a decorator.
So, if you put at cache on a function, you can give it time to live, the target, which is Redis, the key to use for that particular thing, and so on.
And then off it goes.
It's the serializer.
You have pickles, or you have message pack, or JSON.
And then, there you go.
Pretty cool, huh?
So, does it...
Okay.
So, for a function, does it cache the input and output of that function, then?
I think it caches the output.
Okay.
But it doesn't look like it varies by argument.
At least in this example, it's not very...
At least, yeah.
And I don't see how you would...
Like, this key is the lookup value, right?
So, you might call that cache call key result or something.
I don't see how you dynamically do that.
It's got to be, like, a void.
But, you know, a lot of times, that's...
You just, like, show me all the products in this database or whatever, right?
Yeah.
Cool.
Yeah, pretty neat, huh?
Very neat.
Yeah.
And then you have different...
Three basic ideas to think about.
You have these backends.
So, you have Redis backed by AIO Redis.
You have Memcache backed by AIO Memcache.
And then serializers.
Like, you can serialize just string, pickle, JSON, message pack.
But you can also build your own.
And you can also plug in.
There's a bunch of examples and documentation people can check out.
So, this looks really neat to me.
Yeah.
Nice.
It's not quite something that I need.
But if I did need it, I would definitely go...
I know.
And I'd be all over it.
Yeah.
Regarding the level of detail we have in our podcast, SE Steve says, I only listen to podcasts
about APIs.
Nice.
Nice, nice.
What's your last one, Brian?
My last one is, well, the Python Packaging Project.
Packaging Python Project.
Same thing.
No, I have a new one.
But I got it from this.
So, when I was reading this article or this tutorial again, I came across something I wasn't familiar with.
So, I had to go check it out.
So, down with creating a PyProject.toml, one of the options is Hatchling.
Hatchling?
Yeah.
I've heard of Hatch.
Is this somehow related to Hatch?
Yeah, it is Hatch.
So, have we already covered Hatch?
Actually, no, I don't think we have here, but I love the idea of it.
Okay.
So, Hatch is a modern, extensible Python project manager with a whole bunch of cool features,
like a standardized build system and reproducible builds by default, and environment management,
which, you know, okay.
So, I'm not sure if this is similar to Poetry's environment manager or not.
I haven't played with it much.
But you don't actually have to care, which is nice.
Because poetry, you have to care about it, because that's part of the whole thing.
Anyway, publishing is easy to PyPI and other sources.
Version management, project generation with same defaults, which I haven't tried that, so
I want to try that.
And supposedly a responsive CLI that's two to three times faster than equivalent tools.
So, this I definitely need to try.
So, this is, I would think it's similar on the line of Flit, I think, but with some extra
things thrown in.
And one of the reasons why I love Flit now is because even though Setup Tools does now support
PyProject Tommel properly, completely, Flit's like twice as fast for building stuff.
But, so I definitely want to try out Hatch and try this.
I did try one little small project, just converting a Flip project to Hatch, and it took me like
five minutes just using, the documentation here is great.
So, the excellent documentation here about how to use the different pieces of it.
So, it's pretty neat.
Have you tried it?
I have not tried it.
I've looked at it, and it looks neat to me.
I don't make many packages.
I more build applications and web apps and stuff.
So, I'm less in the, what's the right tool to build packages properly?
You know, and I know you're doing that a little bit more.
So, I just want to learn from you.
I guess, good mix.
I do more packages and less applications, and you do more applications.
So, it's good.
Yeah.
Some live feedback.
Henry Schreiner says, you can use any PEP 6.21 backend, Hatchlane, PDM, FlitCore, and so
on with Hatch or with PDM2, one of the fantastic results of standardization.
And that Hatchlane does a much better job of getting source files right than FlitCore.
Okay.
Interesting.
Yeah.
Yeah, there was a lot of cool options with the Hatch that you could specify exactly which
modules and packages to pick up if you need to.
That's one of the things that's a little bit mysterious with Flit, how to figure it out,
because it just sort of knows somehow.
I think it's the stuff that's in Git, but it's interesting.
So, the main thing is, is I really like, with the standardization, that Hatch is possible,
that Flit's possible, that PDM is possible, that we can do new things, and they're not that
different.
Like, it's kind of the backend of packaging, and the frontend is the PyProject.tom.
That's a better world to be in.
Yeah, that separation lets there be a lot more exploration.
A lot more variation.
Yep.
All right.
Well, that's it for our items, isn't it?
I think so, yeah.
You got any extras?
No, but hopefully I will soon.
So, I've got something I'm working on.
Oh, right on.
Yeah.
Yes, I know.
I think I know what you're alluding to.
Very exciting stuff coming quite soon.
Yeah.
How about you?
I have one extra.
This one's quick, but quite cool.
So, I'm sitting here on my MacBook Pro with the M1, you know, MacBook Pro, the M1 Max.
And until recently, I wasn't able to use PyPy.
Now, PyPy is the JIT compiled, often faster version of Python.
Sometimes you'll hear people say PyPy when they are referring to PyPI, but all the people
who work on PyPI pronounce it that way.
And it leaves space for PyPy to be pronounced it like it should.
So, PyPy is the fast JIT compiled version of Python.
And the big news is, a couple weeks ago, they announced support for M1, which is pretty cool.
So, if you're on Apple Silicon, you can now use PyPy.
That's very cool.
Natively.
Yeah.
It was done by Fajal and supported by contributions from the Open Collective, which is pretty cool.
And it's based on support for ARCH64, which is ARM64 and Linux, with some variations on
how this works.
So, they've got 3.8 and 3.9 working on macOS ARM64 platform, which is pretty cool.
So, if you're using that and you've been waiting for this, it should make your code run faster,
maybe use less memory, that kind of thing.
Very cool.
If people are interested in PyPy, testing code on episode 190, I interviewed Carl Frederick Bowles
about testing PyPy.
Oh, cool.
Yeah.
There's a lot of testing.
I mean, it's the entire Python runtime, basically.
It's like in much of the standard library.
That's a lot of work.
Yeah.
It's an interesting story.
So, yeah.
Would you say that testing and documentation are often really good things to add to your
project that go along together in some ways?
Well, hopefully you're doing it at the same time, but yes.
Yes.
You know, we've all worked with different types of team dynamics, the sort of flat hierarchy.
People would just take over the projects, the parts of the projects that they seem best suited
for.
And there might be more hierarchical versions.
So, our joke this week is about a somewhat dominating senior developer here.
And there's a junior developer just hired onto the team.
This is a picture.
People can check it out.
Just follow the link in the show notes.
The junior asks, where's the documentation?
In a very stern face, the team says, I am the documentation.
Hopefully, you're not currently working in this situation, but it's pretty funny.
You know, there's always bits.
There's always pieces of the system that are like, well, how does this work?
Oh, you've got to ask that guy.
He's not even on our team anymore.
Yeah, but he's the one that wrote it.
And luckily, he's still with the company.
So, go talk to him.
Exactly.
No one understands that we don't touch it anymore.
It seems to still work.
Yeah.
Exactly.
All right.
Well, what seems to still be working is our podcast, Brian.
It does.
Thanks for being here.
Yeah.
Thanks for being here.
Thank you.
Yep.
Thanks for everyone to listen.
See y'all later.