Python Bytes - #439 That Astral Episode
Episode Date: July 7, 2025Topics covered in this episode: * ty documentation site and uv migration guide* * uv build backend is now stable + other Astral news* * Refactoring long boolean expressions* * fastapi-ml-skeleton* ...Extras Joke Watch on YouTube About the show Sponsored by Sentry: pythonbytes.fm/sentry Connect with the hosts Michael: @mkennedy@fosstodon.org / @mkennedy.codes (bsky) Brian: @brianokken@fosstodon.org / @brianokken.bsky.social Show: @pythonbytes@fosstodon.org / @pythonbytes.fm (bsky) Join us on YouTube at pythonbytes.fm/live to be part of the audience. Usually Monday at 10am PT. Older video versions available there too. Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to our friends of the show list, we'll never share it. Michael #1: ty documentation site and uv migration guide via Skyler Kasko Astral created a documentation site for ty (PR #744 in release 0.0.1-alpha.13). Astral added a page on migrating from pip to a uv project in the uv documentation. (PR #12382 in release 0.7.19). Talk Python episode on ty. Brian #2: uv build backend is now stable + other Astral news The uv build backend is now stable Tim Hopper via Python Developer Tooling Handbook From Charlie Marsh “The uv build backend is now stable, and considered ready for production use. An alternative to setuptools, hatchling, etc. for pure Python projects, with a focus on good defaults, user-friendly error messages, and performance. When used with uv, it's 10-35x faster.” “(In a future release, we'll make this the default.)” [build-system] requires = ["uv_build>=0.7.19,<0.8.0"] build-backend = "uv_build" I believe it’s faster, but I agree with Brett Cannon in asking “What's being benchmarked? I'm not sure what a "backend sync" is referring to other than maybe installing the build back-end?” See also: uv: Making Python Local Workflows FAST and BORING in 2025 - Hynek Brian #3: Refactoring long boolean expressions Trey Hunner This is applied boolean logic, and even folks who learned this in a CS program probably did so early on, and may have forgotten it. How can you improve the readability of long Boolean expressions in Python? Put parens around the whole expression and separate clauses onto different lines Where to put boolean operators between clauses? at the end of the line or the beginning? PEP8 recommends the beginning if (expression1 and expression2 and expression3): ... Naming sub-expressions with variables Odd downside that wouldn’t occur to me. All expressions are evaluated, thus not taking advantage of expression short-circuiting. Naming operations with functions Less readable, but takes advantage of short-circuiting Using De Morgan’s Law : replacing a compound expression with a similar (and hopefully easier to read) expression # neither: we want both to be false not (a or b) == (not a) and (not b) # never_both: at least one false not (a and b) == (not a) or (not b) Michael #4: fastapi-ml-skeleton FastAPI Skeleton App to serve machine learning models production-ready. This repository contains a skeleton app which can be used to speed-up your next machine learning project. The code is fully tested and provides a preconfigured tox to quickly expand this sample code. A sample regression model for house price prediction is included in this project. Short write up on "What does set -a do?" Extras Brian: OCF Michael: via Wei Lee Extra Airflow ruff rules: Starting from Ruff version 0.11.13, most changes from Airflow 2 to Airflow 3 can be automated using AIR3. (It’s still in preview so a “—-preview” flag is needed) e.g., if you have the following Airflow 2 code import datetime from airflow.models import DAG from airflow.operators.empty import EmptyOperator with DAG( dag_id="my_dag_name", start_date=datetime.datetime(2021, 1, 1), schedule_interval="@daily", ): EmptyOperator(task_id="task") it can be fixed with uvx ruff check --select AIR3 --fix --unsafe-fixes --preview import datetime from airflow.sdk import DAG from airflow.providers.standard.operators.empty import EmptyOperator with DAG( dag_id="my_dag_name", start_date=datetime.datetime(2021, 1, 1), schedule="@daily", ): EmptyOperator(task_id="task") which works with Airflow 3. Joke: Front Toward Enemy
Transcript
Discussion (0)
Hello and welcome to Python Bites where we deliver Python news and headlines directly to your earbuds. This is episode
439 recorded July 6
2025 and I am Brian Ocken and I am Michael Kennedy and this episode is sponsored by
Sentry listen to their spot later in the show. Thanks sentry also connect with us if you'd like to send us items
or just say hey
we are on blue sky and
mastodon and Michael's even on X still. So, the links to all of
us, all of us run in the show notes and at Python bytes.fm.
And also speaking of Python bytes.fm, once you head on over
there and sign up for the mailing list, because we will
send an email to you soon after, hopefully
soon after we release the episode and we send out all the links for everything we cover
plus extra information and some background information.
It's really good.
We're pretty proud of the email.
So please sign up for that. And if you'd like to watch us live or just
watch the video post live after live, whatever that is, the afterlife, no, later on, you
can go to python bites.fm slash live and there's a link to our YouTube stuff. So that'd be
awesome. So thanks. Let's kick it off. Michael.
Let's do it. I want to start by saying
Thank you. T. Y. I don't know if it means thank you or not T
Y the type checker and also prefix this Brian. This is kind of gonna be the astral show. Just
Just hope people are aware. Yeah, there's a there's a couple of topics that we're gonna cover and this
Burst and second one comes to us from Skyler
Casco. So thank you Skyler for sending this in. We always appreciate when people are like,
hey, have you seen this? Probably no. Sometimes yes, but probably no. All right. So I want
to talk about TY from the Astral folks. TY is very similar and what it brings to the table is what Ruff did. So, you know, Astral, they make UV, Ruff, and now TY.
And Ruff didn't fundamentally change
how we check our code, right?
We had black, which honestly kind of did,
and a bunch of tools that that brought together.
But the real difference here was that Ruff
makes blending almost instant.
And it's like, when you run Ruff, you gotta double check and make and it's like when you run rough you got
to double check and make sure it's actually on the directory you're like
did that you know I just hit enter and it's done but there were 20,000 lines of
code like how did this did it actually do anything I'm not sure it did anything
but in fact it did and it's very similar with ty but for type checking so we've
had type checking type checkers like mypyy and so on, but they've really struggled
on super large code bases and being faster in general is also really nice, right? So we've
talked about Ty before. I've actually had Charlie and Karl Meyer on Python and me and we dove into
it. So if you all want like super detailed dive, you can go check that out. But what is the news? The news is the documentation for TY is up.
So if people wanna check out the docs
and learn more about TY,
they can go over to docs.astral.sh slash ty.
And there's even an online playground.
And of course, there's a bit of a crossover here
in the sense that you can say UV tool install ty to
have astral install ty just like I do or if you just want to simply run it and
say UVX and that'll install it in like a ephemeral virtual environment sort of
thing but there's also an online playground and this is pretty interesting
because the online playground here is written in WebAssembly. So it's
TY running against your Python code in the browser in WebAssembly. So that's
quite neat as well but that's not exactly the news. The news is the
documentation is up and along with that they also have, unrelated to TY exactly,
but in the documentation from AstralSide, migrating from a PIP to a UV project.
And it's a walkthrough on how you might go about using UV
in its idiomatic way, I guess you would say, right?
For example, like, if you use PIP,
you probably use PIP and PIP compile
to generate a requirement like TXT and so on, right?
How do you do this kind of stuff using UV?
So people can check that out as well.
Yeah, I really like the migrating thing. I actually read through it and if you're not
migrating, if you're just going to use UV, I would not recommend reading this because I actually got
confused a little bit. I've already moved on. But yeah, UV all the way. So what am I going to talk about?
Let's see.
I am going to talk.
Let's just, we have a little bit of news from UV, from Astral.
That's the UV show.
It's the Astral show.
Yeah.
So I actually picked this up from Tim Hopper and his Python developer tooling handbook. He posted the UV build backend
is now stable. And actually, I'm pretty sure I heard about the UV build backend, but I
don't remember playing with it. So I played with it. So the announcement is that for about a year,
UV has had a UV build command,
and it's kind of like an alternative of,
what do we have, Hatchling or Flit or something like that.
But now it's one of those build backends
for PyProject.toml-based projects.
And it's pretty exciting that UV build is here. So that's the announcement. And it's also that it's
stable and also fast. So Charlie Marsh posted that he posted that it's 10 to 35 times faster than
alternatives. So what is he looking at? He's looking at comparing UV to Hatchling to set up
tools and to FL flip. The thing that
we don't have an answer on is what is he timing? Because this is just sort of posting the times
for what he calls the backend sync. That is not a command that you can send to hatchling
or flip. And you actually hatchling isn't a command line thing. So I mean, I'm not sure
what's going on, but I believe him
that it's faster. So it would be kind of cool to find out what he's measuring anyway. But
UV build is now available and that's cool. I'm pretty excited about that. Along those
lines, if you're switching kind of along the lines of with that, that Michael brought up,
if you're switching to UV and you'd kind of like to know
what's so great about all of this,
I recommend checking out Hinnick's video series.
So he just released the second part in a UV series.
And this one is making Python local workflows
fast and boring in 2025.
And he's talking about UV workflows.
So it's a great video.
I mean, I assume it's a great video.
It's 40 minutes long. I haven't actually assume it's a great video. It's 40 minutes long.
I haven't actually watched it yet,
but I watched the first one.
Yeah, his videos are great.
So yeah, check them out.
Indeed.
And Brian, our sponsor, also very great.
Let me tell you about them.
How about that?
That'd be great.
Yeah, so this episode is brought to you by Sentry.
And I'm a huge fan of Sentry.
Use them with all of our software and they've been
incredibly valuable for tracking down errors in our web apps and other code that we've run.
I think everything's fine, you get a notification, there is an error, you're like,
oh I guess that is a problem, you know, and it doesn't have to be in your code. It could be
something like you've upgraded a dependency and now there's some kind of problem that's occurred.
I've certainly got that notification as well. And I've learned
about users encountering bugs over at TalkPython and for the courses and stuff
and then I'll reach out to them and say, sorry I saw you were into this bug that
we fixed and they haven't even contacted me yet. They're like, okay awesome kind
of creepy but amazing. Now it's good to know right? Right away and be able to be on top of things.
So how might you set this up?
Well, they've been adding more and more capabilities
and features.
So I want to walk everyone really quickly through the idea
of setting up monitoring and distributed tracing
for a Python web app, which means across API calls
or across the JavaScript front end and the Python back end,
you can correlate errors
so you can see like the whole operation, right?
So let's imagine we have a Flask app with a React front end
and we wanna make sure there's no errors
during the checkout process.
I don't know about you,
but anytime money and payments are involved,
I get a little extra nervous writing that code.
So knowing what's going on, very good.
So you start by enabling distributed tracing
and error monitoring on your Flask back
in and your React front end. Super easy. Just a few lines of code. Next, you want to add
enough context to the front end and back end actions that you can correlate them into a
single request. So add a little bit of information to like know what's happening. You enrich
the spans as the sentry construct across these calls with business contacts like a session
ID or a user or whatever.
And then you can see the request live in a dashboard.
So you build a real time Sentry dashboard.
You spin up one using span metrics to track key attributes like cart size, checkout duration,
and you have just one pane for performance and error data.
And that's it.
If an error happens, you
open the error at Sentry and you get end-to-end request data and error
tracebacks to easily spot what's going on both on the JavaScript and the Python
side. So if your app and your customers matter to you, you'll definitely want to
set up Sentry like we have. Visit pythonbytes.fm slash sentry and use the
code pythonbytes, all caps, just one word, that's pythonbytes.fm slash sentry and use the code pythonbytes.
All caps just one word.
That's pythonbytes.fm slash sentry code pythonbytes.
The link is in your podcast player show notes.
And thank you to Sentry for supporting the show.
Awesome.
I want to move on to something that is sort of, I guess,
maybe nerdy, bullying expressions.
As if the show wasn't already nerdy, right?
Come on.
So we've got Trey Hunter's article,
and I kind of love what Trey Hunter's been doing lately.
He's been writing some good stuff.
So refactoring long bullying and expressions.
And there's lots of reasons why I love this article,
but we'll just walk through a little bit of it.
First of all, he's introducing people to Morgan's Law,
which I love anyway.
So here's the idea is you've got a Boolean expression
and his example, it's a great, pretty good example,
is if you've got like, you've got events and users,
you've got sort of a web app sort of a thing going on,
and you wanna check to see if a user is verified and
The event they're looking at the date of the event is in the future
So it's greater than now and maybe it's not full. So maybe you're doing like people signing up for something
And this is this is a reasonable bullying expression, but how do I it's not that readable
So let's let's try to make it more readable. And that's,
that's what he's looking at here is how to break this up.
And one of the things that I love about this is this seems,
it's just sort of basic math. If you, if by basic math,
your math includes Boolean algebra and things like that. And,
but a lot of people come from Python from, not from a CS background, which totally valid, of course. And but a lot of people come from Python from not from a CS background, which totally valid,
of course. And but how to manipulate and and an or when I say bullying expression is just things,
truthy things, true and false things with and an or and things like that. So he walks through some
of the things you could do, you could you could just split up the line. So you could just use
parentheses around your expression
then you can split the different expressions
up on multiple lines.
And then he's also saying you could either do it like this
where at the end at the beginning,
or you could say user verified and,
and they go to the next line,
the event date is less than or is greater than now,
and you go into the next line, not full.
Okay, so you could put the and in the beginning or the end.
It's really up to you.
However, I didn't realize that PEP8 made a call on this.
PEP8 recommends putting things like and,
and, or at the beginning of the line.
And just so it's consistent.
I don't know if it really matters,
but I guess I kind of agree
that it's a little more readable this way.
So I like that.
The other thing that's kind of neat about this that we will lose a little bit is that
Boolean operations and expressions are short circuited in Python.
So with the ands, that means that all of these expressions have to be true for this to be the entire thing to be true.
So if I get to user verified and that's false,
if the user is not verified, I don't evaluate the rest of it.
I just know that this is going to be false then,
that Python does.
And so Python won't run it.
Hold that thought.
It's going to make sense later.
One of the things we can do to make this simpler is
to just go ahead and evaluate all of the expressions and assign those to variables, like users
verified, and then combine those with ands. That's easier to read, but if any of these evaluations
are lengthy things, we don't want to do this because we lose the short circuiting. We've evaluated
all the expressions and then we short circuit just in the ands expression and we don't get
that. However, Trey says you still can get this if you throw everything in functions.
So he's got these little is verified, is in future, things like that. Naming the expressions into different little functions.
And this is usable.
I don't think this is that readable though,
but that's just me, I think.
He makes it kind of all on one line,
so the entire function on one line.
I think that a lot of people,
style guides would kind of hate that.
You know what, I think it looks really neat
the way he's got it written like this,
where it's just one line,
you kind of call the function as the test.
But here's the thing, if you run rough against it,
keeping it the astral show, or you command alt l it
in PyCharm, it's going to wrap it and it's put spaces.
Like it's just gonna keep wrecking it.
So then you've got to wrap that in a no format command,
like directive.
And then you're like, ah, okay, maybe it's too much to bridge too far,
but yeah, I get it.
Okay. Yeah.
So the, these are, these are cool methods. Um,
and then let's jump through the math part.
The math part is kind of, kind of nice. Uh, that, um,
is the there's,
you can distribute nots and ors and stuff.
And so if you're thinking that either a few things are
like A or B is true and I want to make sure
that that's not the case, whatever that means,
that's the same as not A and not B.
So there's these distributive properties of and and or and and he shows both
whether you want neither one to be true or
what never both you want one of them to be true but or neither but not both so those sorts of things are distributed
Why does this matter it matters because like this he shows an example as a multi-line expression
And that is confusing to have a
not and then a parenthesis of a bunch of stuff.
But if you do not one thing and not another thing and not the third thing, that's actually
pretty easy to read, I think.
So this is a cool intro to De Morgan's law for some people breaking things up.
So anyway.
Yeah, very nice.
This is the kind of stuff I like to geek out on as well. How many, how
many like variations or how can you restructure stuff to be so much more readable? And yeah,
it's good.
Yeah. And I encourage people to look all the way to the end because you have to, you got
to give it to them that some of this stuff is really hard to understand to glance at.
But because like the first one, the knots just sort of hidden up at the top.
But anyway, yeah. All right.
Yeah, I would also add that, you know, even though you might evaluate two or three
things, performance usually is way less important than readability,
maintainability and so on.
Yeah, I have to say maybe but there's like one.
Sorry, maybe there's like one or two functions, but the rest of them
performance that matter. Go ahead, Brian.
Yeah, exactly.
Don't prematurely optimize because I have to admit
that the example that I sort of poo-pooed on
because it doesn't allow you to short circuit
of just naming the expressions,
I do this all the time for quick things
because it's very readable to do this
So yeah, yeah, and we have profilers that can tell us yeah if it's a problem, right? Yeah, usually it's not
All right, what you got for us? I have just an extra. I have some extras to throw out here
Oh, wait. No, I have one more item donor and then then I have an extra
So my my last main item is this thing called Fast API Machine Learning or ML Skeleton.
So this is speaking to all the data science folks out there
that have some kind of data science model or engine
or something they want to expose as an API, right?
Maybe you're not a web developer
or you're not really writing a lot of API type of things.
So which framework do you choose? How do you structure it? And so on.
So this person whose name I honestly don't know is just 8BEC.
The number 8BEC created this thing called Fast API ML Skeletons.
So what it is, is it's a template that you can start with in ADAPT
for serving machine learning models in a production-ready, fast and easy way, powered by
Fast API. But it doesn't exactly have to be machine learning models. Anything that's sort
of data science you can put behind an API I think would fit here. So it's tested with
Tox and it has example code for that and
super easy to get started. There's a few, I'll come back to some few little
interesting tips and tricks, but it comes with a sample machine learning model
that predicts home prices, right, just to have something concrete to work with.
And then over here, come through and go to the API and they're pretty
well structured, right, uses like API router and so on instead of jamming it all
into just one file, like so many of the demos do.
You're like, oh, look, it's only 10 lines of code.
You're like, yeah, but if you keep expanding that way,
it's going to be terrible.
It comes with open API documentation
by using Pydantic models for all the exchanges.
It's nice and typed and all these things.
So if you're getting it's not super new,
but if you're getting into it, I ran across this.
And I thought, you know, this is pretty neat.
Maybe this will be a real valuable system, folks.
And Brian, I learned something.
Because when it says, how do you start your app,
well, what you do is you say set-a,
and then you source your ENV file, which is your environment
variable settings.
And you set plus a.
I'm like, OK, what does that do?
Yeah, what does that do?
Are you familiar with this?
No.
I wasn't even.
I'm like, what in the heck is that?
And that alone might be worth price of entry for this,
like learning about this project.
So what set dash a does, it says anything that you basically
set as a variable in your environment
basically stays set for you, which is pretty cool.
So here, what's the right?
So set-a turns on the all export option.
Set-o all export.
From that point, every variable you assign
is automatically
exported to the environment. So if you just said set dash a then like foo equals bar,
then it's as if you had like created a script and sourced it and all that kind of stuff.
So a cool way to like quickly set some environment variables.
Yeah, I think that's so getting more and more was came up last week of of
possibly using Durian for that as well. So yeah, for sure. So yeah, that's a more structured
way right to do it for sure. But I'm glad I'm glad to know how to do it manually. That's
cool. Yeah, yeah, exactly. Like if you're creating a little alias or something, right, you could
put that at the beginning and just set a bunch of
Variables yeah, whatever pretty sweet anyway
Yeah, if you're looking for a fast API skeleton to get started with yeah could be pretty cool alright
Do you want to do your extras? I only have one extra. Yeah, sure me too, but because I tried to jump ahead anyway, okay?
so this one comes to us from Wee Lee and
I'm gonna cover this as sort of a gateway to like talk about even more stuff. Then like it's pretty specific, but it's an example of something that's pretty neat.
So back keeping with the Astral Show, Ruff has a bunch of rules for how your code should be formatted.
Right. And then things you should do, things you shouldn't do, maybe certain things are deprecated,
you should stop doing them, right?
Dirt hurts when I do this, okay, well, stop.
But there are things like Airflow-specific rules.
So Airflow is a workflow engine type of thing.
And if you pass, where is the settings?
I guess I don't have it in the docs there,
but I have it in the show notes.
So if you pass
certain commands to it such as
Select airflow 3 when you run rough check dash dash fix it will rewrite old code
That was bad into new code automatically having to do with the airflow
Framework for example in airflow 2 used to say from Airflow.models import dag.
In Airflow 3, you say from Airflow.SDK import dag,
and similar for other imports.
So if you were to say that, it will actually
rewrite the import statements to use the non-deprecated style.
Cool, right?
Well, if you scroll down a bit, you
can see there's similar things for Fast API. Bringing our two topics together, right? Yeah. Well, if you scroll down a bit, you can see there's similar things for fast API bringing
our two topics together, right?
So there are certain things that have changed with the way you work with like response model
or annotated or so on.
So it'll go through and it'll change all those.
Do we have a Pydantic?
No, no Pydantic.
We should have a Pydantic because that one changes, used everywhere.
But anyway, there's like framework specific stuff that I think is pretty neat in the rough rule set.
So thanks to Weave for sending that in. And yeah, if you do Airflow or FastAPI or other things,
you can turn that on to do migration across like semi-breaking changes.
And I actually would just encourage people to look through the rough rules because a lot of these things used to be
different tools and are different tools, but rough is pulled in rules and and
Checks for lots of different stuff that maybe it's worth perusing around on a regular basis to see what's around and new to see
If maybe you should be checking things a little bit more
Closely. Yeah, like they also have like NumPy and Pandas rules and so on.
Which are pretty cool.
I just noticed that there's a pie test section. I haven't looked through that.
I'd like to see.
Oh, very cool.
So one of the things that's neat is when you go into these,
these rules and stuff, each one of these, it's not just, well, here's the rule,
but it actually tells you what it does,
why you should stop doing it, an example of how it's bad and what it fixes. So this is actually a really good
resource, which I've actually covered the rule set before, is like, hey, you should go check this out just to see,
like, what is going on with these, like, do it this way, not that way.
But yeah, the framework specific stuff and like high test specific stuff is cool.
And that's one of the,
also one of the reasons why they don't recommend turning everything on because
that's ridiculous. If you're not using airflow,
you don't need to turn on airflow. So, yeah, exactly. All right.
I have something completely unrelated to Python that I just wanted to bring up
because I'm going to head to Oregon Country
Fair this Friday and I'm totally excited about it.
Oh, that's awesome. What is it?
What? Don't you live here? Okay.
I do.
Oregon Country Fair is a what a three day celebration of art, music and food in Veneta,
Oregon once a year and it's been going on since 1969. They have their own property. Well,
they didn't, they originally like rented it or something,
but now they own the property or have for a long time, but, um,
so it can't get shut down. Uh, anyway, um, it's not a county fair.
It is a country fair. So it is, uh, it's music, um, uh,
art vendors, food and and all waste free.
So the only garbage that they take out
is stuff that people bring in.
You can throw away your candy bar wrappers if you're there.
But all the food vendors are all doing containers
that are biodegradable.
So it's a fun event.
Yeah, very cool.
I might as well check it out. I missed it last year. biodegradable. So it's fun, fun event. Yeah, very cool. So you're right.
Let's check it out. I missed it last year and I'm going to go this year. So some,
some big name. Cool. It's fun. All right. Um, that's our extras.
Are you ready for a joke? I'm ready. This is a short joke,
but I just can't stop giggling about it. Um, I saw this, uh, Mike, uh,
was on blue sky. I don't know. No, I'm asked it on. So somebody
named Mike SEC equals official. So he said it's based on an idea of somebody else, Daedalus
and pending the release of some kind of official sticker to use. I now have applied a handy
reminder label to my keyboard. What is the label? Front towards enemy.
That's amazing.
So it's a picture of the keyboard facing away from the developer.
Yeah, towards the computer or towards whoever you're talking to or whatever.
So towards enemy.
Exactly.
PM maybe.
And if you're thinking, I've seen that before. Where have I seen that? Front towards enemy. Exactly. PM maybe. And if you're thinking, I've seen that before, where have I seen that?
Front towards enemy?
That's usually on the front of the claymore mines that are directional mines.
So yeah.
Oh my gosh.
Crazy.
I love it.
All right.
That is the show for us today.
So awesome.
Thanks for being here as always.
Bye. Yeah. Thanks Brian. And
I want to encourage people who are listening. If you're not subscribed to the podcast, subscribing
your podcast player. And if you're watching the YouTube version, be sure to subscribe
and like the video helps a lot.