Hey Brian. Hey everyone. Hey. Happy summer. It's lovely. Been working in the garden. I know. Me too. I have six bags of leaves I've piled up outside. It's only a tiny corner of my yard that I... Yeah, there's a lot of leaves. Welcome to Oregon. Okay. Okay.
Let's do it. Let's kick off the show. Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds. This is episode 428, recorded April 14th, 2025. I'm Michael Kennedy. And I am Brian Ocken. This episode is brought to you by Posit and Posit Connect. Thank you to Posit for supporting the show. We will tell you more about them later.
If you're a social type and you want to connect with us socially, you can do so on mastodon and blue sky.com.
You can join us on YouTube at pythonbytes.fm slash live. Usually on Monday at 10 today, a few minutes later, but generally around there. You could also catch the older episodes. Every episode page has YouTube trailer or poster you can click. And finally, if you want our increasingly cool artisanal handcrafted digest of what is going on, put together by the one and only Brian Ocken, join our friends of the show mailing list, go to the website, click newsletter, sign up. People
People are more and more people are writing in Brian say they like the newsletter. That's great. Yeah. I think it's, I like it. I do too. I'm glad we're doing it. I wish maybe other people might learn how to write, get commit messages better. Well, honestly, I'm trying, I'm learning, but let's get going.
So I'm going to cover something by Chris Beams, how to write a get commit message. And, oh man, I probably write like a dozen get commit messages a day maybe, you know, from one to a dozen. Mm-hmm.
And so I was interested to see how to do it better. So there's an XKCD at the top, which is, you know, just gibberish. The first commit message is created main loop and timing control. It's pretty good. And then by the end, like the most recent is like hands, just something. Here I have code, more code. Ah, my hands are typing words. Yeah.
And one of the things that this isn't part of the article, but one of the things I enjoy is being able to be fun with my commit messages. When I'm just doing, when I'm doing it on a branch that I'm just doing it for local saves essentially. And then I squash it into a main branch and then I really want the squashed commit message. Cause that's the one that'll stay there to be really good. So they're really, when you want to write a good commit message, here's, here's what you have. And I would, there's like seven tips, but,
There are seven rules, but I was intrigued by like the first one. So like, for example, at the top, there's an example of a kind of a run on commit message that you have to kind of like scroll to the right to see all of it. Huge commit message. Not good. Um, and then some better ones that are shorter. So, um, how do we get that? It ended having included, have like good information. Well, one of the things that I didn't really, I didn't know about, and I learned from reading this is, um,
that if you separate the subject and body with a blank line, so the, the top line, uh, is get will, or get in a lot of get tools, recognize everything up to the first blank line as the title of your commit message. So, uh, in the example, there's an example with like just one line, the short line, and then, uh,
a blank line and then the rest of it that your log and everything will just show that one line and then it doesn't show the rest of it unless you should like click for details or something. Really cool, I didn't know this did this so that's great. So separate the subject and body with a blank line. Limit subject line to 50 characters. I think that's just to keep it because you're, we kind of do like the 80 character thing sometimes
And like a bunch of the characters are used for the actual, like, like the timestamp and stuff like that. So, or the, the hash, like the first few digits of the hash. So we, we want to leave some space for that. So 50 characters subject capitalize the subject line. Don't worry about a period because you know, that's one of your characters. So don't worry about it. Use imperative mood in the subject line. And if you don't,
if don't know or don't remember what imperative mood is, which I didn't. So I'm glad there's a discussion later. There's a discussion about all of these in the article, uh, wrap the body at 72 characters. Um, that was an interesting thing that I, that I, I, it's,
It just is an interesting... So I use tools that wrap it automatically, but a lot of people are using tools that don't. So to store it in approximately 72 characters. And I just think of this as keep lines short-ish and actually use new lines that don't depend on wrapping. And then the most important is number seven. I think this is the most important. Use the body to explain what and why...
and not how the code, the code changes, how you did the change the, so the commit messages, what, what did you do and why did you do it? Um, and I really kind of actually just focus on why I don't even really do the what too much. Um, so, uh,
Good information about commit messages. I also love, there's a lot of people that have talked about this before. So he references a handful of this. It says, keep this in mind. This has all been said before. And each one of these words is like this and has, are all different links to different articles. So it's kind of a fun way to reference other people's work. So good job. Yeah, this is really interesting. And I not too long ago learned the thing about one sentence and then a paragraph or two being extra. And I learned it from...
the jet brains AI in pie charm. Oh really? Yeah. Cause one of the, it's actually really quite good at writing a commit message. If you just press the AI, summarize what I did. Okay. Provided that what you're doing is focused. So if what you did was, uh,
run pip compile and update 20 dependencies, and then you ran rough and reformatted it, never click that button. But if you legitimately did something, you know, that is like a focus thing that it can look at and go, not like you, you, you remove 700 spaces in these locations and then it comes out really good. And it does that. It'll put like one sentence and then it'll summarize in detail what it, what it's discovered below. Yeah. Yeah. So very cool.
That's it. I don't use it that much. I probably should use it more, but sometimes end up in hands. Just work. Yeah.
Usually for me, when I end up writing commit messages like that, I am frantically trying to fix something I just broke in production. And I'm like, oh, I got to put it back. Just take this. I just need you to be able to get pull on the server again and try again before it disrupts too much. You know what I mean? Yeah. Well, I just realized that there's another thing that I do frequently as well is if I like...
If I commit and then push everything and then CI breaks for some reason, like because I forgot something, like I forgot to add, like I added a file and I forgot to add it and push that. I will, the second commit, I will try to have that, the message be identical to the first one so that when people are looking at, it will show up as a different commit, but then it makes it obvious that it's part of that same commit. It is intended to be together. Yeah, that makes sense. I agree with that.
This looks really useful. Cool. Who knew writing a single sentence would be so interesting. All right. Let's talk about caddy. Brian, are you familiar with caddy? Just caddy people. I mean, there's Caddy Shack. What was that?
Yeah, but this is not that. This is Caddy, the ultimate server, ultimate web server. So if people are thinking about how do I host my web apps with Python, there are a few now that the thing that runs your Python code could theoretically also be the thing that serves, that talks to the web browsers. But typically and certainly traditionally, there's been an interesting divide there. We've got static web servers and proxies and firewall type things. That's like
Nginx and others. And then you've got the stuff that actually runs your Python code, probably scaled out to be like four of them or something in a web farm with UVicorn, G-unicorn, micro-whiskey, which don't use micro-whiskey anymore. We covered that, but, you know, Gradian, all those types of things, right? So this one I want to cover, this thing I want to cover today called Caddy is actually sort of a parallel of
of Nginx. So this comes to us from Frederick L. Storm. And Storm, thank you so much for sending this in. But it's something I've been tracking as well, and I've wanted to switch over, but my world is just so complicated. I have every line of Nginx. You've got to put a little configuration YAML JSON-like combo file together.
I have 2200 lines of JSON or whatever nginx config files.
That's a problem. And I don't really want to mess with trying to move that. So it's going to stay. But if I were starting over, I believe I would be probably choosing Caddy. It's a super, super simple way to create web apps that you can run. It comes with automatic internal, no action on your fault, your behalf, HTTPS through Let's Encrypt. So for example, you set up a website, you say my website is like,
michaeldeploys.com or whatever, and you don't have an SSL certificate, you start it up. And as long as it's running on the server that actually that domain resolves to, it will just automatically get you a let's encrypt certificate and keep it up to date. Oh, wow. That's really cool, right? It has 63,000 stars on GitHub. That's pretty awesome. Yeah.
If you want to do development, sometimes you need to have HTTPS and it will automatically do a local trusted certificate for you. If you want to run on localhost, it'll just do like even localhost is over HTTPS does clusters. There's all it has a little test. You can like test it out for yourself, like put your domain to this this location or whatever and try it out. The.
Let's see if I can find the config. The config is super, super simple. We just write a couple of lines. If you've ever worked with HTTP files from PyCharm, it looks a little tiny bit like that. But yeah, it's like real simple. You just say handle slash blog slash star and you
put the details out of there. That's just how that processes that. But it can reverse proxy slash API, which actually goes over to another server and it can reverse proxy another one, which actually does like a round Robin load balancing to yet another cluster of servers. Isn't that cool? Just like all that stuff. So simple.
Yeah, it's really cool. It still doesn't look simple to me. Well, try the alternative, right? So people can check this out. I think it's really neat. The caddy files are super easy to work with here. What was I showing? I think, yeah. Anyway, there's a bunch of different examples. Some of them are simpler than others like this.
Easy to run. Yeah, but one of the other things that's cool is if you're coming from somewhere else, like I was complaining that I have all this Nginx config, you can actually just pass it an Nginx configuration file and go, I'm not ready to rewrite this in your world, Caddy. Just run this Nginx configuration. But you'd be our server for that. So you could slowly migrate over into that. Yeah. Anyway, you can even use apparently a MySQL database.
as a source of definition of your front end web server, which sounds kind of wild, but then again, you can write code and APIs and stuff to control it then, right? Just change the database and then you change the web server. So all pretty cool. Anyway, I think people, if they're thinking about engine X or something like that, should maybe give this a look. I don't remember what it's good. Oh, it's written in go. That's what it's written in. So it's, you know, pretty high performance. It does HTTP one, two and three. So the two is most important, but three is also interesting. Anyway,
98% go. 2% HTML. Nice. Indeed. So if you ever got stuff to host and you're not doing platform as a service, there you go. Cool. Speaking of which, let's talk about, before we move on, let's talk about our sponsor, huh? Yeah. Yeah. So a couple of weeks ago, Brian, you told people about PositConnect. Yeah.
And I want to talk about it again, but for a slightly different reason. So you talked about how easy it was to use. I want to talk about how you can use it to share your data science projects and how you can do that securely with things like single sign-on and so on. So this episode is definitely brought to you by the folks at Polycom.
at Posit. They've made a huge investment in Python, originally known as being an R shop, making RStudio and others. They've been putting maybe the majority, certainly a ton of effort into things for Python people these days. So if the words of, the mentions of words like HIPAA, GDPR, or
or other privacy policies make the hair on your neck stand up, you'll know you want a trusted partner to help your data become shareable, but also follow those safety rules that we all have to live by. So PositConnect can help. And PositConnect lets you securely develop, deploy, and share what you build with Python. If you build it with Streamlit, Dash, Plotly, Bokeh, FastAPI, Shiny, Flask, Quarto, and other APIs. So here's how it works. You or your team set up PositConnect
PositConnect on a secure server within your org or behind some VPN in the cloud amongst your cloud servers and using your existing authentication system. Then when you publish a piece of content, PositConnect lets you set user level permissions for that content, making it visible to some users, not others. But what's even more interesting, I think here is that you can set credentials on a per user basis.
So imagine you write code that then goes talks to a database that then accesses a bunch of data. And depending on who is doing that, they can see some of the data, but not all of it are different things and so on. Different team reports or whatever. So in PositConnect, you can actually per user set how they can access other things like your database or your APIs or external APIs or whatever. That's pretty cool. So if you work on a data science team where security matters, you owe it to you and your org to check out PositConnect.
Do that by going to pythonbytes.fm slash connect today and get a three-month trial to see if it's a good fit. That's pythonbytes.fm slash connect. The link's in your podcast player's show notes. And yes, we all know you can just Google AI, Bing, whatever, Posit Connect, but please use our link so they know that it came from us. That way they will continue to support the show. Thanks, Deposit, for supporting Python Bytes. Awesome. Yeah. All right, back to you.
What's your third item? Well, not third item, your second item. I am going to talk about, let's see, I'm going to talk about peps. So we've got actually a couple of peps coming in. That's good because I need a pep talk. Sorry, go ahead.
So a couple of peps that just recently got accepted. So these are, one of the peps is for packaging and one is for Python 3.14. So pep seven, let's do the packaging topic first.
pep 770 is improving measurability of python packages with software bill of materials and that's a mouthful but it's about s-bombs and if you don't know about s-bombs you probably ought to know a little bit um so this is a good thing to read and if you do know about s-bombs they're stressing you out probably um so we're this is something that we're in the corporate world um a lot of people are trying to
think about and SBOMs, I'm probably gonna massacre this definition, but generally are a way for us to, 'cause we're using a lot of open source projects and third party libraries and like a Python package isn't just the Python code, it's also possibly some Fortran code in it or whatever and some other things inside or Rust that you wanna try to track all those dependencies.
And the SBOM system is a way to get that right so that you can make sure that you know where all of the code's coming from. And this was, there were some different ideas about how to do this within Python. This 770 came from Seth Larson, sponsored by Brett Cannon.
really kind of a neat way to look at, Seth has looked at the different ways that we're already specifying a lot of this stuff with our packaging metadata. So how do we use that to try to fill out a lot of the SBOM fields automatically? And this is just really some great work. So I'm glad this is going in. Again, since it's part of packaging, it doesn't really attach to a relationship
release. So I'm not sure when we'll get like, I didn't look through if this is something that's already implemented or not, but it's just accepted. So, and if, even if we did do get it, we'll get it through tools and stuff. We won't get it through the Python release versions. So next one that I'm, I'm also a little confused about, but excited about is pep 750 template strings. So we're
We've got F strings. These are like F strings on steroids. The T strings will replace the, when you do a template string, you'll won't say F string, you'll say T string. And so it builds, so like, for example, if you had hello name with the name in curly braces, with an F string, that would fill in the name with whatever variable.
but we want it to be like just to just hold that thought and we'll fill in the name later sort of a thing. And I still like, I'm just sort of getting into this. I don't know really how to use these, but I'm really excited that a lot of this has been thought out. Now there's a whole bunch of authors, Jim Baker, Gwydon Van Rossum, Paul Everett,
uh, three other people, Dave, Dave Beck, Dave Peck, sorry. Uh, Lisandro's Nicolaou and Caudiano. I'm sorry about massacring your name. I'm sure. But, um, a lot of people working on this, uh,
really well thought out also, um, some really cool stuff about being able to combine, uh, they thought about like with F strings, you can do math on it or, you know, sort of like adding and concatenating and stuff like that. All that stuff's been thought out. How do we deal with like, uh, displaying them, uh, using them, uh,
the whole shebang. This is going into Python 3.14 or 3.14. So that's just, you know, right around the corner. So really, really excited about this one. So many pie jokes are coming in that version. I think this is really interesting. I talked to Paul a few times about this and I know he's really excited from
from a web developer's perspective. So think about Jinja templates, Django templates, Chameleon templates, like that kind of thing. Yeah. But with more flexibility and they're being supported by the Python runtime itself, not a third-party library that parses and processes it separately.
Well, that's what I was thinking. Like, would we need, with this in place, would you need Jinja templates or could you just implement your stuff with this? Theoretically, I think you could just do it with this. I mean, I think it's somewhat inspired by components and stuff from the JavaScript libraries where you've got your JavaScript, but then there's a string in there, like some weird HTML fragment in there that's actually the...
the template that you would use and they're just kind of interwoven so they can have a little bit more locality of behavior with each other. I think that that is a part of the motivation here. I do believe. Yeah. I'll probably have to have Paul and maybe some of the other folks on the Talk Python to talk about it. Yeah. I'm sure we're going to have lots of articles about it and everything. So we will talk about it more for sure. Indeed. Awesome. Indeed. All right. Well, let's...
round things out with a little data science. Have we spoken about UV before? People out there, do you know UV? Have you heard of this? It's a library for managing dependencies and projects. Actually, I'm probably going to get my jacket signed by Charlie Marsh when I go to PyCon because that's how much we talk about it. No, definitely a fanboy of UV. And I want to talk about a pretty new project
called, you want to pronounce it as Juv, J-U-V, but I think it's J-U-V is probably the way to say it because it's based on UV. And what this is, this is a toolkit for notebooks where the virtual environments and the dependencies and such of it are managed by UV, which is pretty cool. So what can you do? Hey, by the way, this is a pretty new project, 222 stars. I don't know what's the, you know, it's only been created once.
six months ago and it's not too, not too well known, but I want to shine a light on it. So you can create, manage and run Jupyter notebooks along with their dependencies, which is cool. You can pin the dependencies with the pep 7, 2, 3 inline script metadata, which has been, have been accepted. It must be right. Yes. Final.
You can launch ephemeral sessions for multiple front ends like JupyterLab or Notebook or MB Classic. Okay. And it's all powered by UV. So pretty cool. You can, as you would expect, UV tool install JV, or you can also PIPX install it. And then once you've done that, you can just say UVX JV and it'll run. But more importantly, if you look at the different things you can do to it, you can say things like,
JV init some notebook, or you can init a notebook with Python three and give it a name, which is cool. You can go to that notebook and you can add a dependency for pandas and numpy to it. Like that's not something you can normally do to notebooks, right? Or you can say, I have a requirements.txt file I've created with pin versions using UV pip compile. Then I can say dot
J-U-V add dash dash requirements and give it a full on requirements file. So in case you have a ton of requirements with versions and stuff, you want to manage separately. You don't have to keep typing them out. You can also do interesting things like
put a timestamp for reproducibility onto your dependency. So I can say JV stamp this thing, and then it won't get dependencies that are released after now, which is pretty cool. I think, right. I don't know if anything else like that, like I want to just have it, whatever the latest of everything I'm using is as right now, that's what I want. They ship something new. I don't want it until I change my mind. So that's pretty cool. But now here or now there, anyway,
Yeah, I know time zones. I'll make you want to cry. You can also say run dash dash width and it'll run those. Even if you don't want to put them in as a particular dependency and, um, you can lock it to create a lock file, right? All sorts of the UV types of things, but you can have it run there. You can also say run notebook with like Jupiter notebook rather than Jupiter lab and give it a notebook, give it a version. Like there's a lot of different things you can do. So, uh,
I think I've been talking enough, but there's like quite a bit more you can go on here. So this is a pretty comprehensive project for being six months old. Yeah. Anyway, if you notebook and you like UV, you know, consider giving JUV a look. It looks pretty cool. What else you got that's cool, Brian? That's it for our main items. I just have a couple extras and I have a feeling we've covered this, but I don't remember. So I'm going to go ahead and cover it anyway. So, uh...
going to take a look at the status of Python versions. So this is on the Python developers guide, dev guide.python.org. And I just, there was within the last couple of months, there was a re reformatting of this. I think this is my memory. So the, the big list is at the bottom with like the full chart of all of the
all the different versions and what's left. And what we see about the full chart is most of them are end of life because it starts at 26, 27, 30. And so that's not really that interesting. So the new format highlights the ones you might be caring about right now. So the last few end of life, there's two sevens end of life, but then three, six, seven, eight are all end of life. So hopefully you're not using Python three, eight anymore.
But one of the interesting things, so there's a couple of interesting things about here. So highlighting, there's where we're at with, so currently three nines is still getting security updates, three, nine, 10, and 11. And then like right now, as of it looks like right, it's a hairy, it's hard to tell where the green and yellow start with the blue line. So there is, there's dates around, but there's a link to,
in here for end of life date dot date slash Python. And so I took a look at that and that is like very clear as to what the timeline and what we got left. So, uh, three 13, uh,
the active support. So it was released six months ago and it's all, so these relative relative times are really nice. It was released six months ago. We have a year and five months left in active support and then security updates for four more years, four years and six months. So this is,
The timeline's really nice. This also highlights the, so in the first graph, we just had like this difference between green and yellow. So we've got bug fix and security. It doesn't seem like that big of a deal, but when you look at it with the, the, uh, the, the reality of it is, uh, three 12, which I'm using a lot of lately, um, that active support ended a week ago. Uh,
uh we're not like right on the edge we're past it so active support ended for 312 um we still have security supports um so there's security problems we still get three years of security but we're not going to get like bug fixes and stuff like minor bug fixes are not going to go into 312 so 313 is where you probably ought to be
Anyway, so I like both these graphs. And these are really great graphs to pull out if you want to help convince your management chain that you can switch to a different version sort of thing, if you need that. Actually, the second one that you link to here, the endoflife.date slash Python, is really good for that sort of motivation. Yeah. Look, we've got one year and six months left.
how do you feel about that? Maybe we should change in the part where if you pull up 2.7, it just goes, what are you reading this for? Stop right now and go back to migrating. And then 2.8 just says never. No, I'm just making it up. No, it should say that. I've never done it. Oh, okay. It should though. Yeah, it should just go stop. What are you doing now? It has all the, um, the unsupported versions from three, seven and older just collapsing, like unsupported go,
Go away. Yeah. Well, you can expand it, but it's collapsed. But having the relative time is really nice. How much time do you have left? Yeah, I agree. I think that's very powerful as a mental model. Yeah. Anyway. Cool. Cool. Well, let's carry on with that theme because I just want to point out that 3.13.3 is out. And some of the changes don't matter too much to you. Oh, if you use the Mac installer, this happens. Like, well, okay, well, I installed UV, so next. And then Windows has things like updated SSLs.
Tests have been updated a little bit, but it's got a few security fixes here, which is none of them are like run for your life sort of thing, but avoid unbounded buffering. That sounds like you want to avoid that and so on. You don't see the word CVE. You're probably safe, but still it's good to have a fix. And then a bunch of changes to the library things getting better. Yeah.
And so might as well upgrade, right? Might as well upgrade to the new one. I just have to rebuild our base Docker container and UV will find the new one, download it. And then, uh, all the websites, including Python bytes, I'll be off to the races. I think I'm most excited about the update to TCL TK. I know. All right. A couple, one more really quick. Siam, uh,
uh yala marty thank you so much for sending this in because somebody i think in the comments mentioned oh we just used dot get dash blame dash ignore dash revs for the rough format and we were somehow complaining like uh this you're looking at diffs and basis especially looking at blame whoever ran rough format and you said brian don't run format on this because you're going to own it then what you can do is you can create this dot
git blame ignore revs, put probably the SHA of the commit, the hash, and then that will not show up. It'll be like, okay, we're not going to consider that when we compute the blame. Oh, okay. So in that file, you can do a list of revisions to not part of the report. That makes sense now. Yeah, and they also pointed out that git blame has a flag, dash dash ignore revs.
If you want to pass another one, that's a different file. Oh, it's not automatic. Okay. Or use. Yeah. I guess you got to use it with that. Probably. Yeah. Maybe not automatic, but you can. So anyway, yeah.
I am learning about this. This is all news to me. Yeah. Interesting. Cool. Indeed. Thanks for sending that in. That's always appreciated. All right. So let's close this out with a joke. Brian, you've heard about BC and AD and sometimes referred to as BCE before the common era and Western calendars, you know, so we don't have negative numbers because negative is hard in calendars. Apparently I don't, I never really thought, why don't we just have like negative 400, but whatever. Yeah.
BCE. So I want to introduce you to a different calendar. It's such an important epoch, a different thing here. There's BGPT and AGPT. So before GPT, chat GPT, and after chat GPT.
So before, if you're debugging a problem, the developer's probably sitting there for two hours working really hard and going, oh, okay, how's this going to work? They finally think it's working. And then hands to the face, six hours of debugging. Yeah. That's before. That's BGPT. AGPT is chat GPT generates code in five minutes, 24 hours debugging, even more tears. Yeah. What do you think?
Yeah. Well, so 24 hours, if you're, if you're, if you're being good with your body and working three to only eight hour days, that's three days. So, yeah. See, it saves you time. This is how you save time with it. Yeah. No, I've, I've both saved time and lost time with, with this so far. So, yeah, I feel like that's more vibe coding than it is just like, I asked GPT for a little help with a function. I mean, it's like, I still haven't jumped on the vibe bandwagon. I haven't tried that yet. So try that. Yeah.
Neither have I. It's both amazing and terrifying all at the same time. But I haven't done it either. It's like jumping off a cliff. Just do it. It'll be fun for a while. Yeah. And Ro out in the audience asks, where's the Stack Overflow step?
Oh, yeah. Yeah, that's got to be in there somewhere probably. You're like, I'm sorry I left you, Stack Overflow. I will not stray from you again. I will go back and maybe you can help me get out of this. Probably not. You just find the same answer generated by ChatGPT over there as well. Well, Stack Overflow is changing their name, right? They're going to go by training data now? Training Underflow. Okay. Okay. You know what doesn't waste your time though? What? This show and us. In a good way. Yeah. So let's get out of here.
Thanks, everyone, for listening. Thanks, Brian, for being here, as always.