Hello and welcome to Python Bytes, where we deliver Python news and headlines directly
to your earbuds. This is episode 440, recorded July 15th, 2025. I am Michael Kennedy.
And I am Brian Okken.
And this episode is brought to you by Propel Auth. I'm going to tell you more about them later, but
make Auth easy for your app and don't spend time on things that are not your core
value proposition. Get Auth by your apps with them. Links to the top of your podcast player show notes.
if you want to connect with us brian i don't even know where people should connect with us anymore
we're on mastodon we're on blue sky we're here on youtube people can comment on the youtube channel
on the youtube video that actually is a place that a lot of the feedback happens so any of those
places and if you want to be part of the live show pythonbytes.fm live usually mondays at 10 a.m
Today, we're 25 hours later, I guess.
I don't know.
Tuesday, because sometimes life intervenes, but generally Monday at 10 a.m.
And if you want a really nice summary and a little bit of extra information around the
episode, not just a rehash of the show notes, but something different, be sure to sign up
for the Friends of the Show.
Just visit pythonbytes.fm, newsletter button right in the front.
Enter your email.
We'll treat it kindly.
We won't share it or sell it.
But we will send you cool stuff.
Brian puts together for you.
Speaking of cool things, Brian,
let's switch over to you and see what we're talking about.
Okay.
Well, I want to, let's see.
First, I want to add something to the screen.
How do I do?
There we go.
I want to bring up a rehash an old episode.
So in episode 438, so just a couple episodes ago,
one of the things we talked about was I talked about Durinv.
Where was that at?
there's a lot of stuff on the show notes. Anyway, my CLI world from Frank Wiles. And one of the
things was during and, and so I've been thinking about it also while we're here, I'll
just go ahead and show people that, you can see the stuff, cool stuff like my book, your course
and, where do people subscribe again? people subscribe right at the top. Oh,
be part of the live show and scroll down and there's, newsletter right there.
Anyway, so I wanted to talk about the dir env a little bit again, and I think I may have said what it's not before.
So dir env is just a tool.
It says unclutter your.profile.
And the main thing people use it for is these.envrc files or optionally.env files that basically use that to load up environmental variables when you go into a directory.
That's really mostly it.
But in Python world, we use that also to do other work.
I guess everybody else uses it to do other work as well.
But one of the things we do is invoke virtual environments when you go in.
And that's really what I'll be using it for.
So I really want to talk about, where is this?
Trey Hunters.
There it is.
Trey Hunter's blog post called, and this is an older one from, oh, not too old, last year,
switching from virtual inv wrapper to Durinv, Starship, and uv. Well, I don't really care about
the from virtual inv wrapper because I didn't use it before. So I'm thinking this is just switching
to Durinv and uv. And when reading this, and I can't remember who brought this up, but when
reading this, it brings up a lot of the things that I didn't like about DuraEnv the first time I
tried it. And Trey fixes all of those things. So let's look at a few of the things that he fixes.
So he does talk about making it work with ZShell. I've made it work with Bash as well. So it works
fine with most of the, at least all the Linux type shells that I've used. So the first off,
the default doesn't show you the virtual environment prompt because DuraEnv doesn't
allow you to modify the shell prompt.
So how do you get around that?
And there's just a short script that Trey wrote to put in your zshellrc or in your bashrc
file.
And then now your prompt is back where it shows your virtual environment.
So that's cool.
Also, apparently the default is to put the virtual environments replaced in a different
directory, like a.durinv Python 312.
And that's not, I mean, I don't know about most people,
but at least me, I've always just stuck my virtual environment
right in the project directory that I'm working on.
So he has some switches for that.
Also, Durinv, when you enter and exit,
it is very verbose about telling you that it's loading stuff.
You can turn that off, shows you how to turn that off.
And then that's just the Durinv setup.
And he's with virtual environments,
but he's set it up with uv next.
So after that, it's uv and showing how to use all of this with uv.
The thing that I think is kind of one of the things I wanted to point out
that's pretty cool that I don't know if we've talked about
is when you're creating a virtual environment with uv,
you don't get pip with it because you're going to use
UV pip install instead of pip install.
However, some tools, some extra tools need it to be there for some reason.
And so you can say --seed, which it probably does other stuff too, but it adds
pip to your virtual environment.
So it'd be kind of cool if it just said --pip or something.
Seed works.
You just have to know that.
Anyway, that's as far as I'm going to get so far.
He's also talking about Starship.
And I guess I think I will follow the Starship tutorial too, because one of the things I like
is he is, he likes, he teaches people a lot.
So he doesn't want his shell prompt to be too crazy.
And so he's going to have a fairly boring Starship configuration.
And I'm glad because I'd like to see how to do it boring first
and then look at his other stuff.
Yeah, those things can be overwhelming.
But I really like having some of these things,
like a prompt that shows you which virtual environment is active,
which version of Python you're using.
It's really neat.
Yeah.
Yeah, anyway, so if you've tried Durinvib before and it sort of annoyed you,
maybe this tutorial might be for you.
It might be for me as well.
I haven't, I'm not entirely sure.
I recently updated, I used all my zshell plus warp,
which warp is a super cool terminal thing.
And for some reason, things weren't working quite the way that I was expecting.
And with some of my Python virtual environment stuff installed versus system Python,
That was really, it was odd.
I think I was running pytest from the wrong place
or something like that.
And it was driving me nuts.
And I didn't realize, I don't know,
I think I had pytest extensions installed into,
plugins installed into a different place
than I was trying to run it from.
And that was the challenge.
But I recently added to my profile,
this thing will automatically activate
virtual environments if you go into a place
that's got somewhere in the directory tree
of virtual environment.
And if you CD out of it,
it'll automatically deactivate it,
which is pretty dirty and V,
But I ended up doing that just with like a simple bash function.
Cool.
So anyway, I, however you go about it, I totally, totally recommend it because I
can see here exactly all the git status, all the, you know, the branch, everything.
It's great.
That's not what I want to talk about.
That was just a fun little follow up.
what I want to talk about something from them Lou and they say, Hey there,
here's a cool topic for Python.
So we've all heard of SQLite and almost all of us have SQLite
installed knowingly or unknowingly because Python itself ships with SQLite.
It builds itself as the world's most popular database.
I think Excel might be the world's most popular database, but you know,
pretty close, right?
Yeah.
They can, they're definitely Titans, but the story you're told is I'm
using SQLite for development or like a local storage, like a local settings
file for an app, but it's not appropriate for production.
This thing I'm about to talk about called RQL Lite instead of SQL Lite is pretty neat.
And that's what Demi recommended, distributed SQL Lite.
Written and go, but who cares?
You can use it however you want, right?
So come down here and let me open up their main website here.
So rqlite.io.
And if you go over here, you can see that it's got a couple of things.
Vault tolerance, high availability, SQL Lite.
How crazy is that?
So basically what it is, is it's a data access layer on top of SQLite, but it also sets up
distributed, a distributed version of SQLite with replication.
Oh, wow.
Isn't that crazy?
Yeah, that's awesome.
Yeah, I think it's super cool.
So yeah, replacing Postgres with RQLite has simplified the software we ship to customers,
says Mark Campbell.
Yeah, so you come in there and see some of the things it does.
deploy in seconds, nothing complex to run. And then it gives you basically an HTTP API to talk
to the database because it might live somewhere else in a cluster, right? But that really routes
just internally to SQLite and it integrates with Docker Kubernetes super easily. Full text search,
vector search, JSON documents, lots of different things. So if you up here to, I think getting
started, you got quick start. Yeah. It talks about you just, there's different ways you can install it.
You could brew install the thing, or this is the way I've been doing all of my database servers
lately, all my server type things, you know, Nginx, MongoDB, et cetera, Postgres is to just run a
local version using Docker. So I don't have to install it or have it mess with my machine. So
instead of brew install, I would just Docker run this thing and give it a volume and it's good to
go, right? Persistent volume. So you don't lose the data. And then you just talk to it a lot like
SQLite, but you can create a cluster of them, which is what's wild. And in the example they show,
it's like, look, this is all local hosts, but you probably would set them up to be running
in different places, which is, it's pretty wild. So you also have got like all the rules around
eventual versus strong consistency and everything you do with clusters. So they've got a nice little
write-up on trade-offs you can make for like reliability, performance, staleness, et cetera,
client libraries, Python ones,
IRQL, RQ Lite, and so on.
One for SQLAlchemy.
Yeah, a lot of neat stuff here.
If you're looking for a distributed database
and you're using SQL Lite,
I think people should look at this.
And thanks to them, Lou, for sending this in.
Actually, a hook into the SQLAlchemy
to RQ Lite is pretty cool.
Yeah, it's pretty neat.
Yeah, you got read-only nodes
and all sorts of different things
about how you can set up the clusters.
You don't have to do clusters, by the way,
if you want to just run a single instance of it,
it says plenty of people do that.
But if you want to have like the fault tolerance,
high availability, then, you know, set up a cluster.
Cool. Neat.
Do you know what else is awesome?
I would guess that it's our sponsor.
Yes. PropelAuth.
This episode is sponsored by PropelAuth.
PropelAuth is the easiest way to turn authentication
into your advantage.
For B2B SaaS companies,
great authentication is non-negotiable,
but it can often be a hassle.
With PropelAuth, it's more than just functional.
it's powerful. PropelAuth comes with tools like managed UIs, enterprise SSO, robust user management
features, and actionable insights. As your product grows, PropelAuth adapts with it, supporting more
advanced authentication features. And the best part, PropelAuth has native support for major
Python libraries like FastAPI, Flask, and Django. You can easily integrate them into your product.
When auth is effortless, your team can focus on scaling, not troubleshooting. That means more
releases, happier customers, and more growth for your business. Check them out to get started today.
The link is in your podcast player show notes. It's a clickable chapter URL as you're hearing
this segment, and it's at the top of the episode page at pythonbytes.fm. Thank you to PropelAuth
for supporting Python Bytes. Yes, definitely. Thank you. Thank you. Now, Brian, I feel like I've
snuck this one out from under you, this next one I want to talk about. Okay. We have a Python
dictionary that can report which keys you used and which ones you did not use.
Why do I feel like I got this from you?
This is like perfect for testing.
Okay.
So imagine I'm working with an API or some kind of data reporting library and you send it some
kind of dictionary, right?
And you want to make sure, like, I want to make sure that it uses these three important pieces
of information that are contained in the dictionary.
and if you run your code run either through a test or however you want to but probably through a test
then you could ask which keys were used and which ones were not used and if one you're like nope
it's really important that they take this piece of information into account and you see that it's not
used well that's a pretty big hint that something's going on and you might say like we'll just mock it
out and we can check but it's not that the function is called it's that the function is called with a
certain combination of different parameters over time, which I think is where it gets tricky,
right? It's not like get item was called or get is called. It's that get was called with these
seven values, but not this eighth value, right? And that's kind of like where I think this has,
at least as far as I know, kind of a unique idea. Yeah, that's pretty neat. Now, what I'm pointing
at is this blog post by Peter Bankson, and it's very nice, but it's also very short. And it's not
like exactly a python package you just uv pip install and then run with it instead it's more of
just a simple little dictionary that people wrote and then you can just access like what keys were
accessed which keys were not accessed and it's got some sweet uh step operations for that right like
the difference of a set and so on yeah so you might want to you might want to extend this a
little bit right like copy this in for example one of the things they note um and there's some nice
comment the comment conversation at the bottom one of the things missing is this works for square
bracket access which calls dunder get item but not dot get access but you know what if you look at
the way that get item is implemented and you rewrite the one that does get i'll tell you what
it's like three lines of code and it's super easy right like there's it basically just captures a key
that was used into a set and then delegates to the underlying dictionary implementation so there's
not a lot going on there.
Right.
So you can add that out.
Another thing that's nice is, there was a conversation about what would this
look like if it was a typed tracking dictionary?
And so, someone in the comments provided a, a typed version with
multiple generics.
How about that?
Okay.
Yeah, sure.
Yeah.
So I think, you would definitely want to add the dot get function to this, but
like I said, just, it's like three lines of Python and it's not hard.
So check that out.
But yeah, I think this is a neat idea.
If you're looking to test how a dictionary is being used on a key by key basis.
Yeah, it seems like it's ripe for a small tracking dictionary package.
Yeah, exactly.
I think this is going to be like a sweet kernel of an idea for somebody who wants to put something on PyPI.
And I put this in the show notes.
Maybe someone wants to polish it up and put it on PyPI.
That person is not me.
Yeah, yeah.
Or me, that person is Brian.
Exactly. I don't, but maybe someone else does.
Yeah. Okay.
Well, we are streaming this episode,
and I would also like to talk about streaming Markdown.
It's a transition there. Yeah.
Anyway, so Will McGugan reported a few days ago
that the textual that he and his team are working.
I guess I'm not sure if there's a team there anymore.
But anyway, textual has a new version out.
4.0.0. So what's the, what's the big change? The big change is a markdown append. So this is kind
of a neat thing. I thought it was cool to have, to be able to see if we can get this to run.
The gist of it is that you've got a markdown. You can report to a markdown widget that as you append
to it, it just keeps going. So you can in real time, add stuff to it and it just sort of scrolls
down. Anyway, that's the big thing. Maybe you don't care about this, but I brought this up.
That's like all of our topics, but I brought this up because I really like the thing that he did
in bumping the major version. So he says why, the reason for the major version bump is because
while he was implementing this, there was a different, another part of the interface,
widget anchor that already existed and that has changed semantics.
So he, and it works better also, but the semantics changed,
changed, caused the major version bump.
I wish more people did this.
I think that a lot of people only change the major version if they change the
actual signature, the API signature.
And I think that behavior changes are completely,
They're even more important to change the version
because it's going to sort of run fine.
It's just going to do something different.
And that's something you really want to point out to users.
So applaud him for doing that.
Yeah, Brian, I remember when I first learned C++
and I had some, for me at the time, complicated program.
I was so proud of myself when I got it to compile.
Yeah.
Then its behavior.
I had to figure out all the bugs.
And this is kind of like that, right?
It's like it technically still has the same API signature,
But it's down to the harder things to detect that are breaking changes, right?
Which is semantics and behavior.
Yeah.
And that's the real one that gets you is if it seems like it runs fine right away,
but there's a major version bump, you got to check a look at your test to make sure that.
And probably it's just that you're not using WidgetHanker.
And if you're not using it, you don't have to worry about it.
But anyway, so there's that.
And I was like, what can we stream with this?
What would I want to stream into Markdown?
Well, I've got another project that I wanted to highlight called HTML to Markdown.
So this is a HTML converter that apparently there was another tool, which I think I ran
across before called Markdownify that converts webpages or HTML stuff to Markdown.
And to be able to, so I thought, and one of the features of it, okay, so they completely
rewrote the fork.
But why?
There's a bunch of extra features like HTML5 support, type safety, metadata extraction.
And look at this, streaming support, memory efficient processing for large documents with progress callbacks.
I'm curious if you could take a web scraper or something or somehow take something that's streaming HTML
or use this to grab something large and have it reported to a textual widget.
That'd be kind of fun.
so that's very fun yeah nice i can also see if you are doing some kind of chat chat bot or llm type
of thing on the textual side yeah and you wanted to output the responses in markdown like that's a
real common yeah even exchange for even brings that up uh like the efficiently stream markdown
content like you might get from an llm like you might yeah okay yeah makes a lot of sense so cool
all right hey i want to jump back to your first item real quick okay did you give this article a
shout out as well because i know that you were thinking about it oh yeah i just didn't highlight
it so i didn't bring it up yet so yeah there's yeah you want to talk about it yeah sure i don't
know a whole lot about but it's very neat so um mario python by night also did uh it's the terminal
bootstrapping starship just during v and uv and talks about how you can sort of get things set up
with that as well so just it's already in the show notes just one more thing to throw out there
Yeah, and so that's what's causing me to say,
maybe I should take another look at Durinv and Starship
because other people that I admire are using it.
So yeah, maybe it's worth looking at.
Not like me, who just vibed my way to a turn it on,
turn it off automatically sort of bash function.
Yeah.
You ready?
Yeah, actually, you got any extras before we jump to the vibe?
Well, the only extra I wanted to bring up is the reason why I'm wearing an annoyingly bright T-shirt today.
Usually I do a darker color because it shows up better on the better.
But this is my Oregon Country Fair shirt that I got last Friday.
So I'm going to stand up so that you guys can see it.
And it's a lovely Oregon Country Fair shirt.
It was a blast.
But I'm definitely feeling my age a little bit.
But we got there, it's 11 to 7, and we got there right before 11 to get a decent parking spot.
But usually we get there earlier to get a decent parking spot.
A lot of people, it was pretty hot this weekend.
So it's till 7 o'clock, but like, I don't know, like 3 or 4 o'clock, we were like, I think we're fried enough.
Let's go home.
It has been very warm and very sunny in the Pacific Northwest.
Contrary to what people think about the rain and the clouds.
Yeah, no, I think there's other parts of the country getting more rain than us right now.
Oh, indeed.
All right.
You ready for the joke?
Yes.
Okay.
So let me set the stage.
I know many of you out there already know this.
We've had several jokes.
So if you've been progressing along the joke timeline with us, you will know what vibe coding
is.
Just for the folks who don't though, vibe coding is when you go to an agentic programming model
like cursor windsurf juni for the jetbrains idees that kind of thing and you just just tell it what
to do you don't need to touch the keyboard you use text to speech you just like build me this app
now i do it this way now make it that and the joke is that it comes up with a bunch of mistakes
or it works on your machine but you're not enough of a programmer to actually know okay that like
this might work here, but it's not really going to work. So that's the joke. And the joke is,
switch back, there's an announcement for this new conference. Very exciting.
VibeCon. Introducing VibeCon, the world's largest vibe coding conference. Make sure you register
today. HTTP 127.0.0.1 colon 8080 slash register. It says VibeCoding is hard to attend. VibeCon
is hard to attend. That's already funny. This is on Reddit, but if you scroll down into the comments,
So good.
Someone's just a sequel and backslash and vibe.html.
Someone's no, no, that's wrong.
File colon triple slash C colon forward slash and vibe.html.
What boomer posted this?
Modern vibe coders gather up at HEP bracket colon colon one.
You know, the IPv6.
That's funny.
Oh my goodness.
This is sweet, isn't it?
Can someone give me the prompt to generate the registration form so I can sign up?
That's funny.
Yeah, somebody said tried to register and they took a screenshot that local, the page, you know, connection refuses.
Oh my God.
Tried to register for ViveCon.
I guess my vibes weren't local enough.
Yeah, that's funny.
Yeah.
Okay, so let's say I'm dense.
Why is, what is that URL, that 127.001?
If you're doing web development locally, that's where it will run.
Okay.
I don't know what server typically picks 8080.
Maybe this is Node.js.
probably it is because like flask is 5 000 um some of them are 8 000 yeah so but it's definitely like
if you ran it locally you said build me this thing it would work perfectly locally because this is
like the dev address but obviously it's listening on the local loopback not it's not a real server
i love it yeah yeah i haven't done a lot of vibe vibing lately but yeah no definitely uh vibe con
is definitely hard hard to uh to attend and pat on the honest says they run a lot of local apis on
8080 like internal all right well fun as always yes thanks for being here brian thanks everyone's
listening and if you're not subscribed to the podcast please click follow or the subscribe for
free whatever your podcast app button says to you know keep getting automatic downloads to our free
podcast and if you're not subscribed on youtube you want to get notified you want to catch the
things and all the stuff we're doing here go over there and subscribe as well thanks and bye all