Flask is one of the most important Python web frameworks, and it powers a bunch of the
internet.
David Lord, Flask's lead maintainer, is here to give us an update on the state of Flask
and palettes in 2024.
If you care about Flask and where it is and where it's going, you'll definitely want
to listen in.
This is Talk Python to Me, episode 472, recorded July 9th, 2024.
Are you ready for your host, please?
You're listening to Michael Kennedy on Talk Python to Me.
Live from Portland, Oregon, and this segment was made with Python.
Welcome to Talk Python to Me, a weekly podcast on Python.
This is your host, Michael Kennedy.
Follow me on Mastodon, where I'm @mkennedy, and follow the podcast using @talkpython,
both accounts over at fosstodon.org, and keep up with the show and listen to over nine years
of episodes at talkpython.fm.
If you want to be part of our live episodes, you can find the live streams over on YouTube,
subscribe to our YouTube channel over at talkpython.fm/youtube and get notified about upcoming
shows.
This episode is sponsored by Sentry.
Don't let those errors go unnoticed.
Use Sentry.
Get started at talkpython.fm/sentry.
And it's also brought to you by us over at Talk Python Training.
Did you know that we have over 250 hours of Python courses?
Yeah, that's right.
Check them out at talkpython.fm/courses.
Before we jump into the interview, I want to let you know that we still have some spots
left in my Code in a Castle event.
If you're looking to learn some of the premier frameworks and techniques in Python, and you'd
like to have a bucket list type of experience while doing so, then check out talkpython.fm
slash castle.
In October, I'll be running a six-day Python course for an intimate audience in a villa
in Tuscany.
Half the time we'll be learning Python and the other half will be exploring the best of
what Italy has to offer.
Check out the course outline, the excursions, and all the details at talkpython.fm/castle.
Or if you'd like to just shoot me an email, michael at talkpython.fm, or find me on the
socials, and I'm happy to talk about it.
I hope to see you there.
David, welcome back to Talk Python to me.
Great to have you here.
Yeah, hello.
Going to be super fun to talk about Flask and more broadly, Palettes.
Just all the different projects around Flask and tools and variations like Quart and so
on.
And you gave a really nice talk at Embedded FlaskCon.
Talk a bit about that in a second.
About the state of Palettes.
And I thought, you know, let's just take that idea and share it with everyone.
So looking forward to talking about that.
Yeah, there's been a lot going on.
I bet there has.
So yeah, it's been, I can't remember exactly when you were on.
I think it's about a hundred episodes ago, which puts out like a couple of years.
What have you been up to the last couple of years?
Just more Flask.
It's all Flask all the time.
Seems like such a simple API, but you can work on it forever, right?
I've acquired a few more libraries, so like written more libraries and stuff as well.
But still same job.
Well, I guess I got a house.
I got married.
Okay, congratulations.
Two times.
Yeah.
That's awesome.
So a little bit of life changes.
Life keeps marching on.
It's amazing.
Flask is certainly one of the most popular web frameworks.
It's, I guess we could start with like giving people a sense of the popularity, but my thought
is just like, wow, the pressure of working on something that affects so many folks.
Like if you push out a change, you know?
Yeah.
I've had a weird thought before that like, I try not to think about the numbers too often
because it's like 100 million or more if you add up all the different libraries and stuff
a month.
And I've had a thought before, like if I push out something that doesn't work for enough
people, like that probably has some like very minor but noticeable like effect on the tech
like sector for that day or hour, which is scary.
Yeah.
It's not quite an AWS US 1 East downtime, but it's also not that, you know?
Yeah.
I think a lot, I think over the past, definitely since I've started, a lot more people have
become aware of like better practices around like pinning their dependencies, that sort of
thing in part because we did make some, you know, deprecations and then breaking changes
in Flask and the other libraries.
And people came to our issue tracker saying, oh, you know, you broke something.
And ultimately, you know, I had to tell them like, you need to be using a tool.
There's quite a few tools out now, although we don't have like a lock file standard yet,
but there's pip compiled, there's PDM, there's Rai.
You need to use a tool and pin your dependency tree because then you can see when there's
updates and you can like update them deliberately and test and make, adapt to those changes.
And I was giving that message a lot in the beginning.
And over the past like five years or so, it is, I've definitely had to post it less often.
I feel like more people are like aware of those tools and practices now.
Well, I would also add that the tooling has gotten a lot better at that.
It used to be, okay, so what you're going to do is you're going to write a requirements.txt file
and then you set your versions explicitly.
And that for many people only addressed the primary dependencies, not the transitive depensity,
you know, right?
They might pin Flask, but did they depend Vexo?
I don't know.
They may have, probably they didn't, you know, unless they use pip freeze,
but then you gather a bunch of like garbage that isn't actually about your project
that got sucked in from some other thing that got, you know, it's like,
it was really sort of funky before.
And I think, I don't know, you mentioned pip-tools and pip compile.
I am loving that workflow these days.
Yeah, that's what I've switched all the projects themselves to.
So if you go look at Flask or Vexoic or any of those,
we have like a requirements folder with different environment files that say like,
here are our direct dependencies.
And then we compile those into like fully locked dependencies and all our tests run off of those.
Our build and publish workflow runs off of those.
So it's not quite the same because like those are our development dependencies instead of our runtime dependencies.
But it's still really helpful just to know that like, if we don't do anything,
our process will continue to work because it worked last time.
Yeah.
And if we give, if we have like contributors at sprints, now like it's much easier.
Like I had, like I had a problem the first few sprints I was running where, you know,
every developer would try to set up their own machine and get like different versions of things or have different versions.
Point in time snapshots of just whenever they got started, right?
Yeah.
So now they like all install the exact same list of dependencies.
So everybody's development environment looks exactly the same, which is a lot more usable.
Yeah, that's excellent.
I have the same workflow.
I have a top level dependencies that I actually would consider my dependencies.
And then I pip compile, the unpinned and I pip compile those to a pin dependencies.
And I just do the upgrade when I feel like, oh, let's, let's go get some new dependencies and see how that goes.
Yeah.
Very nice.
Okay.
Well, let's start with FlaskCon.
Okay.
I called it the, I called it an embedded conference and this is different than it has been before.
I think FlaskCon at one point was a purely online one, or maybe that was just COVID.
Yeah.
It was just a matter of time.
I remember.
It was, it was timing really years ago, like right as COVID, right before COVID started or quarantine
started, I had been like, like working myself up to do an in-person conference.
It's something I've wanted to do for a while because I love attending conferences.
I love the community around it.
Uh, Django con happened in San Diego a few times and that was really fun.
So I just crashed it.
It was the Flask person.
I was the Flask person.
Um, and, so I was like getting ready to do that.
And then, COVID happened, but some other members of the community, the, the palettes
team and he stepped up and said, Hey, we can do like an online one.
Um, running a conference, even online is very hard.
There's a lot of stuff to keep track of.
Oh yeah.
But it was, we ran three online conferences.
Um, I think 2020, 2021 and 2023.
Um, I think we skipped one, but those are all on like, pivideo.org.
If you want to find it.
And now Flask on 2024 is there also.
And, so I finally got the opportunity with, PyCon.
They, they previously had this hatchery program, where you could kind of propose, I want
to do this event.
And, the, the hatchery program will say like, that sounds great.
We'll give you, you know, we will handle the venue, the food, the insurance, the legal
stuff.
Um, you get one of our rooms and you can do whatever you want in it or whatever you propose
in it.
Uh, and so last year at PyCon, I talked to some of the organizers.
And they suggested, Hey, the hatchery is coming back.
This would be a great way to do it.
So that you don't have to learn everything at once.
Right.
You can practice.
Um, yeah.
So, we managed to do some advertising.
It's hard to advertise new conferences in general.
And then especially now that, like most of the Python, a lot of the Python community
is not on Twitter anymore.
I'm not.
Um, and even if they were, everything is kind of fragmented more.
Um, so it was hard to get the reach and get enough, like, CFP.
Um, so we had a lot of the proposals, but we did get, a few and, ended up accepting
two people from the community that gave just wonderful talks.
Um, and it, I saw one on doing PWAs.
And what was the other one on the talks?
Was it progressive?
Um, no, there was one on single page.
Sorry.
And there was one on observability and then, yeah.
PWAs or single page apps and, extension, the extension ecosystem and kind of like the
idea around defining plus plugins.
And then there's my talk, which was just, the subject of this podcast.
Yeah.
Welcome people.
Yeah.
That's cool.
Uh, will it maybe be a PyCon next year?
Um, or are you going to branch out?
I don't know yet.
I think they would accept me back, but I wouldn't want to like, I always, I kind of view the hatchery.
I mean, I don't know if this is true, but I kind of view the hatchery as like, we're
going to help you get started, but not like keep coming back for the same thing.
Um, but I don't want to like, right.
Right.
I'm a 10 year rookie.
You know, you're not a rookie anymore.
Get out here with the, or let me, I would still love to run, a conference somewhat
selfishly so that I can run one like in San Diego or on the West coast at least.
That's what I was going to say.
How about San Diego?
Then we can, I'm going to come down there and stay by the beach.
Yeah.
I mentioned DjangoCon before, but they, they stayed in San Diego for three years straight at
this, little hotel that was really nice.
Had a pool.
People just kind of, congregated and it was like 15 minute drive for me.
And, so yeah, next year at PyCon, I might not be there.
Um, we're expecting our daughter to be born in January next year.
Congratulations.
And that might take precedence over PyCon.
I'm going to have a lot less time in general, which will be, which will come up in other things
we're going to talk about, but yeah, I probably like for the first time since 2016 or 2015, I
will not go to PyCon probably.
Um, yeah.
Yeah.
But there was a, conference, right?
This was the last conference I went to before quarantine.
Uh, two weeks before quarantine hit, I went up to Los Angeles for PyBeach, which was this
very, very small, first time conference.
Um, and I just love those like little ones.
Yeah.
And, I met the organizer, Nick Cantar at, North Bay Python a few times now.
And I've told him like, we should try to bring that back.
Like I bet, like, I think there's a few other people who are interested as well.
And I'm like, it doesn't have to be FlaskCon specifically, but if I could like run some sort
of local conference and I can do some flat stuff or attract some flat stuff, you know?
Well, I'm pretty excited that, PyCon is going to be in Long Beach, year after
next.
Yeah.
Two years from now, that'll be really nice as well.
So that'll be really nice, but maybe you can drum up a bunch of interest and connect with
a lot of people who are conference goers of that place, but like encourage them to sign
up for a list and like get notified about whatever this other thing is, cause it'll be in the same
basic neighborhood.
Yeah.
So, Jazzy out in the audience asks, can we attend FlaskCon online?
Um, this year or this in-person one in 2024, we weren't able to do that, but all the talks
are available now on our YouTube channel.
If you just search FlaskCon 2024, you'll find it.
Um, or pyvideo.org has all of them listed.
Um, the last, the first three we ran were purely online, so you could watch them streaming.
Um, this year we just didn't have the infrastructure for it.
So we couldn't really manage to do a live stream and the recordings at the same time.
I was lucky enough to get, Elaine Wong's help doing the recordings and she brought all
her special, cool specialized equipment.
So we were able to get the recordings up really fast at least.
Yeah, that's really good.
Are the ones for PyCon even up yet?
I don't think they are.
Not that I'm aware of.
Maybe they're going like really slowly, but yeah, it was really nice.
Like we just recorded this hard drive and like, she was like, Oh, you guys timed that,
you timed all your starts and stops really well.
So all I have to do is like do these like simple cuts and it's all up.
From the edges and upload.
Perfect.
Yeah.
Yeah. That's really cool.
So yeah, I'll link to the playlist of FlaskCon 2024 for folks in the show notes.
They can check that out.
Awesome.
Well, we'll see what 2025 brings.
Hopefully some more good conference.
Yeah.
We might have other like members besides me, attending PyCon as well.
So we'll see what happens.
Right?
Sure.
If nothing else, I usually just run out of space or something.
So there's always something going on.
Yeah.
Yeah, for sure.
Now I want to talk about the state of pallets in 2024, but surely there are, you know, quite
a few people out there who listen, who are really new to Python and programming.
You'd be surprised.
A lot of people say they use it like this podcast, like language immersion.
Like you want to learn Portuguese.
You used to move to Brazil.
You want to learn Python.
You just put on your earbuds and listen until it makes sense.
So especially for those folks, like what is pallets?
Um, pallets is an open source organization.
So we're not a company.
Um, but we do have like a team of volunteer open source maintainers who volunteer their free
time to work on flask and the libraries that make up flask.
So, this portion of talk Python to me is brought to you by Sentry.
Code breaks.
It's a fact of life with Sentry.
You can fix it faster.
As I've told you all before, we use Sentry on many of our apps and APIs here at talk Python.
I recently used Sentry to help me track down one of the weirdest bugs I've run into in a long time.
Here's what happened.
When signing up for our mailing list, it would crash under a non-common execution paths, like situations where someone was already subscribed or entered into a
invalid email address or something like this.
The bizarre part was that our logging of that unusual condition itself was crashing.
How is it possible for our log to crash?
It's basically a glorified print statement.
Well, Sentry to the rescue.
I'm looking at the crash report right now, and I see way more information than you'd expect to find in any log statement.
And because it's production, debuggers are out of the question.
I see the traceback, of course, but also the browser version, client OS, server OS, server OS version, whether it's production or Q&A, the email and name of the person signing up.
That's the person who actually experienced the crash.
Dictionaries of data on the call stack and so much more.
What was the problem?
I initialized the logger with the string info for the level rather than the enumeration dot info, which was an integer based enum.
So the login statement would crash saying that I could not use less than or equal to between strings and ints.
Crazy town.
But with Sentry, I captured it, fixed it, and I even helped the user who experienced that crash.
Don't fly blind.
Fix code faster with Sentry.
Create your Sentry account now at talkpython.fm/sentry.
And if you sign up with the code TALKPYTHON, all capital, no spaces, it's good for two free months of Sentry's business plan, which will give you up to 20 times as many monthly events as well as other features.
That was kind of its purpose when it was created was, hey, Flask has these set of libraries.
Armin, the original author of them, was not as involved in them anymore.
And like the community, he wanted the community to be more involved in them.
So he created this organization.
This was right around when I was becoming maintainer two, eight years ago.
And so it's kind of the organization that holds those projects and like the team that kind of maintains and sets policies and that sort of thing.
So Flask is like the most popular library that everybody ever heard of, followed by Jinja and Click.
But then we also have Verksoig, which is the lower level stuff below Flask.
And then MarkupSafe and It's Dangerous are two little helper libraries for those things.
And then now we've also got Cort, which is the async version of Flask.
That's an official palettes project now, even though it started as just kind of a separate thing made by Flask.
Yeah, it was an outside thing that Philip Jones worked on and now it's coming closer and closer to being official.
Yeah.
And like we're doing a lot of work on that to kind of try to unify Flask and Cort as much as possible.
So behind the scenes, they're sharing a lot more code now.
Cort, like Verksoig is all the low level request response handling for the Flask uses.
And Cort wasn't using that at first because it needed like much more async things.
But we've managed to develop a lot more things called the term is called sans IO, like without input output, where we have all like the behavior that's common to both.
That doesn't require asyncio versus sync processes shared between Cort and Flask.
And eventually we're slowly moving in that direction.
The idea is that at some point you will not pip install Cort or import Cort anymore.
You'll just pip install Flask and then do like from Flask import Cort instead.
Oh, interesting.
So the library as well once we get to like a point that we're really comfortable with.
See you're shipping shipping one thing.
Yeah.
Will you be able to use the same app?
You know, we say add app get or will that be a, will there be a.
Yeah, that's, that's the one thing.
App F equals Flask and app Q equals Cort.
Yeah.
You'll still have one single app, but you're going to have to pick ahead of time.
We've tried to think of ways around this, but just the way that Flask is constructed means that so much of it is customizable by extensions.
And that, that, that those hook APIs that extensions can customize all the extensions out there expect that they're sync, they're deaf, whatever, not async deaf.
Right.
And, maybe we'll figure out something, but so far we can't figure out a way to unify that into a single object.
So you're going to have to still pick.
I want to be async first or sync first.
And yeah.
Yeah.
Uh, but at least it'll be in one place.
Like you're not going to have to decide, oh, I need to know about Cort.
You can just look at the Flask docs and see like, oh, I'm going to be doing mostly like, like web requests or like video processing or something that's like the IO intensive.
I should pick court or, or I'm just doing like the basic API that everybody makes for their, you know, data science project.
I just need Flask.
Hopefully it makes it a little easier.
Yeah.
Really interesting question out in the audience.
Will it, it sounds like it'll work both WWSGI, WSGI and ASGI ASGI.
Um, any future where it just goes all, all async, not likely in the short term.
It sounds like great.
Um, yeah.
Like Flask will always be WSGI.
Um, because it's so tied to how sync processes work.
Um, ASGI has an ability to, and so like, if you use like HyperCorn, which is a popular, ASGI server, which is also by Phil from Cort.
Um, you can run a WSGI application as an ASGI application.
Um, you don't necessarily get all the benefits of ASGI, but you can at least run it with that.
Um, and some, and kind of like in a similar vein, like if you're using Cort, you can write both sync and async things and they all just work together.
Yeah.
You just, and, and with Flask, you can write async stuff in Flask right now.
Uh, you just don't get the benefits of ASGI's connection pooling.
Um, so you're still doing one worker per request response, but you can in that worker kick off like async, code.
Right.
Okay.
More easily.
Interesting.
Yeah.
I've written a decorator that it decorates both sync and async methods.
And it's pretty tricky.
There's just basically.
Yeah.
Jinja has two, two.
Yeah.
Two rappers.
It goes, all right, well, which are you, we're going to actually apply that one to, you know, it's, it's a, it's tricky to juggle.
And then the, well, the plugins, like it's gotta be a gnarly combination.
Yeah.
We're, we're, we're like, basically we're just like taking it in baby steps and we're hoping like, as we keep unifying their code, like their shared code more and more, we can start like discovering.
Like discovering like good patterns for writing an extension that works in both, for example, and documenting those and maybe helping, some extensions, that are popular update to that.
Um, yeah.
And so it's a slow process, but like it's surmountable.
Yeah.
Maybe you get to a point where they're close enough.
You're like, oh, now it's really obvious how these things.
Yeah.
You know, by the beginning it wasn't right.
Okay.
So what's the state, how are things?
What's the state?
Um, maybe start with the big, the big boy flask and inbox zero is like one of the biggest takeaways.
Inbox zero.
That was, it was actually, that wasn't 2024.
That was the 2021 or 22, I think.
But, I, yeah, we don't have like true zero most of the time, although I do get down to it every now and then.
Um, but, I did hit inbox zero.
So when I first started maintaining all these libraries, I think combined, there was probably over a thousand open issues and PRs.
Um, and that's a nightmare.
If you know all the code, like if you, if you were the author, but I was not the author of this code.
Like, so I was both unfamiliar with the internals of all these libraries and like had to keep track of all these issues.
So I was like learning libraries, learning how to be a maintainer and trying to keep track of like all these requests.
Going back and forth and like competing PRs and all that sort of stuff.
So it was, early on, it was a goal I identified of like, I just need to make this manageable.
And, once I got there, it's become a lot easier.
Like once you're at inbox zero, it's a lot easier to keep it.
Hovering.
I really feel in, I'm feeling rough about my true inbox.
I'm looking at like five or six persistent emails.
I really got to get back to you, but it's a whole different deal than if it's 10,000.
Did you declare, any sort of bankruptcy equivalent of like inbox bank or you just go like archive.
A good, like if it's two years or older, I'm just going to archive it and it'll come back if it matters.
Or did you literally go through everyone and deal with it?
Um, I did go through everyone individually.
I didn't just blanket say everything older than two years is closed.
Um, yeah.
But I did kind of treat things as like, I don't like stale bots.
So we don't run a stale bot.
Like, yeah, I don't like those either.
Yeah.
Like I, I don't object to things being closed, like as the resolution versus fixed, but I want like somebody to be making that decision.
Um, right.
Right.
And put a reason behind it.
Uh, so yeah, I tried like going through every single issue.
Basically my workflow is just every single day, pick an issue, work on it, like pick another one.
Okay.
It's been a couple hours.
Wait until the next day.
And, yeah, just like had to keep making calls on them.
Yeah.
Like, all right, two come in a day.
I'm going to do 20 a day until I catch our sounds like that.
Right.
There was a lot of stuff also where it was, it had just been sitting open for years, you know, and nobody had really commented on it besides like, or maybe they had the most people that commented on was saying like me too, but they hadn't actually like moved the discussion forward.
And yeah, I, you know, it would be nice if open source, if like more people like contribute, I don't blame anybody for not like contributing, you know, or being a contributor, but I would love to like attract more long-term contributors and stuff.
But that's like kind of the way it starts is you need to like help people like make calls and stuff, evaluate things.
Right.
Uh, you know, instead of saying me to start looking into it and saying like, okay, me too.
And okay, here's all the like issues that might come up when we do this, or I looked at their code base and we could do it this way.
Yeah.
Right.
Exactly.
We weren't doing that.
I also want it, but I want it.
And I think here's a path forward or here's a, you know, like they have to advance the conversation.
Um, and that wasn't like happening in a lot of the old issues.
So I did kind of like, I didn't already just close old issues, but like, I did say like, okay, this thing is old and it hasn't seen any movement or like, there's a lot of things also where it's like, yeah, it's a reasonable request, but is it necessary for flask?
Does it belong in flask or an extension?
Right.
Like this is something I'm trying to figure out.
Like, I want to be writing like documentation for other maintainers on the team, you know, so they understand like how I did this sort of stuff.
And it's really, this is like the trickiest problem.
I don't know how I'm going to document yet, but like, I got a sense over time of just like being able to really quickly make a call of like, yes or no.
One thing, like I can look at an issue and say like, okay, no, this doesn't belong in for X, Y, Z or something.
Um, because like flask had like all the libraries in palettes have like very focused core, like goal of them.
And, they try to be extensible to some degree.
So a lot of the things you can do by making extension.
Um, so really what I try to look for is like, I need this thing in flask because it is literally not possible to write an extension to do this without being able to like hook into it this way or something like that.
No, that makes sense.
Sure.
And part of the Zen of flask is that it's minimal and then you build around it.
You pick your database, you pick your whatever, and then go from there.
Yeah.
Cool.
All right.
Well, three, three open issues and incredible as, as in 67,000 stars.
That's also pretty incredible.
Uh, let's see.
So you join each one of these different ones.
You kind of gave a sense of like how many downloads.
So for flask, maybe these numbers changed, but I think it hasn't been about a couple of months.
It's around 75 million downloads a month.
That's a, that's a hefty chunk of user base there.
Yeah.
I occasionally look at pypi stats.org or pepi.tech, are the two like websites that track these numbers.
Um, so I can look at the current flask is downloads in the last day, 3.15 million downloads in the last month, 66 million.
Um, okay.
It's that much time.
People are telling.
Yeah.
Look at that.
Yeah.
And there's like, sometimes there's like random, you can see in this graph here, like there's just random times where it just suddenly drops by like a couple of hundred thousand or right or rises.
Yeah.
Like if you look at the left half of this graph, it's higher.
Like, I think that's just because like big services like come in and out of existence or like do an upgrade or whatever.
Um, so there are some like very big systems out there that are just download doing a ton of downloads.
Yeah, it's pretty wild.
It's definitely wild.
You'll probably also spot some pypi outages.
Well, I imagine in that graph, which is got nothing to do.
And like they also change the way they report over time, like pypi pip and stuff change how they report statistics.
So, okay, I usually just look at like the overall numbers pretty consistent.
Yeah.
Try not to look at it too often.
Like I said at the beginning, like it's a, it's a big number to know that like this many people are about to download any change you make.
Um, yeah, and when I think about these kinds of numbers, it's not just if you make a change to flask, then it affects this many people.
But these are themselves applications using this, each of which has many, many, many users potentially.
So there's a multiplier on top of this, right?
Yeah.
And, yeah, that's been, that's, that's been difficult.
That's one of the other state of flask.
Uh, that's the other half of the state of flask is like, we've been making a lot of progress, but like this amount of responsibility, rests.
Uh, pretty heavily on it.
It's like, it can be pretty stressful.
Um, and you did mention a baby and being potentially tired in the future and stuff like that as well.
Yeah, exactly.
Um, but like combined, you know, these numbers combined with the thought that anything I do could break a bunch of people and get them to complain at me or people will complain at me, even if I don't break a ton of people.
And, just kind of like the ever present notion of, we are not at inbox zero on some of the projects and stuff.
So there is still a lot of open stuff.
It's, yeah, it's a lot of stress for me.
And it's been, I've like suffered burnout a few times from, per year for the last four years or so.
Oh man, that's rough.
Um, are you getting some support from the other people at the Oregon potentially from?
Yeah, I, I, I, there is, there are other people on the team.
So it's not like we're a bus factor of one in the sense of like, if I was not here for some reason, other people would have access to these things and could keep them going.
But the reality is, not to downplay all the work that they do in the community and, when they, when they are working on code, but like I do probably 90% of the code and like the decision making and all that sort of stuff.
Right.
So it would definitely be a very different project if I wasn't around.
It would at minimum be a scramble.
Right.
Like when Guido stepped down, like, wait a minute, who's doing what now?
Yeah.
So like I, I, so this is what I've been like trying to work on for a long time because I've, kind of always recognized that, I've been kind of the, not limiting factor, but like the, I'm like the point of failure in this thing.
Um, and so I've been trying to grow the team and, trying to make our processes more automated, you know, try.
Um, now what I'm trying to do is, because I know I have this hard deadline in January when I'm going to have less time, is I'm trying to document how to do what I've learned to do.
Uh, like how to be a maintainer is something we don't really have a lot of, it feels like is, and we have contribute, we have a contributing guide, right.
Or we have user documentation or developer guide, like how to use flask, but we don't have a, how to maintain flask documentation.
Yeah.
It must be kind of missing from the community in general.
Yeah.
I, I presume that'd be out in public.
People interested could check it out whenever that gets written.
Oh yeah.
It's, it's not like a private, it's not gonna be a private thing, but, it's not, it's not ready yet, but it's something I'm actively working on.
It's like, identifying like all the stuff I've accumulated in my head and what I've learned how to do or decisions I've made or like services we use.
Like just the fact that, oh, you know, we're part of the PSF.
This is how you contact the PSF.
Yeah.
Right.
It's not written down.
Yeah, exactly.
Or like that we're part of Tidelift and you know, these other, donation sources.
Yeah.
Also like stuff like how, how do I make a decision on whether to keep something closed or open or, when is it time to make a new release or what is our version policy or our support policy or our security policy?
Like a lot of these things are, under documented right now if they're documented at all.
And, so that's kind of my goal for the rest of this year as is to like make pallets more sustainable, regardless of, how much availability I have.
Maybe a little more systematized maybe a little bit.
Yeah.
Uh, so before we move off of PI PI stats, Goosra has an interesting meta question.
Is PI PI stats built on Flask itself?
Do you have any idea?
I have no idea.
I know they're open source.
Oh yeah.
Okay.
So maybe you could tell that way.
I was gonna say there's not like a header or something that Flask sends.
So, yeah.
I can't find it.
Yeah.
We don't know.
It is open source.
Oh, here we go.
Here we go.
We've got a requirement.
We've got a project.tomo.
Yeah, it's flask.
There you have it.
How about that?
There we go.
Beautiful.
It's very rewarding every time I, every time I find out a new place that like, like,
just decided to use Flask and has been using it and it's just completely behind the scenes
and you can't tell like nothing's like, it's all just working.
Yeah.
But I love, like, I love going to like conferences for that reason too.
Cause so many people come up to me and like say like, Oh yeah, we use Flask to like run
the Mars Rover or, somebody, one of the, one of the people giving a talk at
Flask on it was like my company, writes the like energy management software for this conference center.
And it's in Flask.
It's very fun to learn all those new, no uses.
Have you ever gotten onto the JPL?
I know it's like a blowers drive.
That'd be fun, right?
To go out there and actually see the Flask.
I would see it.
That's what runs in the Rover and the helicopter.
Awesome.
All right.
So that's Flask.
Uh, what one do you want to talk about next?
Next on my tablets, I got Jinja.
We can go wherever you want.
So like maybe that a good foundation.
Yeah, we did, like Flask and Variksberg are pretty tied, because most of the stuff that people report to Flask is actually an issue with one of the other libraries that Flask is using.
And most often that's with Variksberg.
So you can see we're not at inbox zero.
We're at inbox nine right now.
That's still, that's incredible.
Uh, you know, maybe like I asked you to explain palettes like Variksberg, you know, that's probably not how English speaking folks would say that.
Workzoyger, Workzug or something, right?
But Armin, the creator of this is German or Austrian, but speaks German.
And so that's the German pronunciation.
And hence, that's why we're saying it that way.
Right.
That's my best approximation of the, I'm sure I'm doing it wrong also, but, pretty close.
Yeah.
It literally is like, it means like work thing, which is like, yeah.
Yeah.
Basically tool.
Yeah.
It's like tools, like work, work, work, your carpentry tools or yes.
Handyman tools type thing.
Yeah.
This is, this was written before, before flask existed.
And it's, it, I think it was written more when like WSGI was like, was becoming a spec or had just become a spec.
Um, because it is just a bunch of utilities for doing HTTP header parsing, doing all the low level WSGI, environment management, wrapping that information in request and response objects.
So you can kind of work with them a little easier.
Uh, so it's all like the underlying tools that you need, to build flask.
Um, there's also like the whole routing system, you know, so you can, in flask, you just do at app dot route, but behind the scenes, what that's doing is it's adding it to a, route map that very so like defines.
And that defines like, here's how we actually like collect that and like turn it into a bunch of rules that we can match URLs against.
And there's other things in there as well.
The reloader, the debugger, the dev server.
So one of the updates you gave on Vexo is, performance improvement by way of getting rid of the, the stir bites duopoly.
Yeah.
Um, I've been doing a lot in Vexo.
So that, that one and the, URL of one that we'll talk about, were two big things, but basically like this library, like I just described it.
It's like just a huge collection of tools and little utility functions.
And there, there was a his, there's a history there because when this, when all these libraries first started, Python three didn't exist or barely existed.
And so everything was written originally for Python two, where strings and bytes worked a lot different.
Um, it was one of the primary breaking changes.
There were other changes, but that was the, that was the long, the one that people really had a long live bug tracking, you know, if it's different syntax, you just change the syntax.
But if it's subtle behavior changes, then trouble looms.
Yeah.
Um, and so, yeah, in Python two, it was much easier to like, like, well, not, yeah, it was easier to treat like incoming data as bytes, but like treat it as a string.
There wasn't like as big a distinction between strings and bytes, which was convenient in some ways, especially for like low level tools like HTTP, where you just work in ASCII bytes.
Yeah.
So I was gonna say if you like ASCII, it's probably fine.
If you don't like ASCII, you might not like it so much.
Yeah.
But it also like cause like, like, like I, I, I first learned Python three.
So I, I like, I have a kind of difference on this, but I like, I like Python three's distinction.
I think it's much better to have that distinction.
Yeah. You and me both.
Um, but at the time, like when it was first happening, it wasn't as clear cut, like, oh yeah, this is better or this is easier because you had to support both.
And, so when Python three came out and started getting like more momentum, all these libraries tacked on, support for both Python two and Python three, which among other things meant that you had to now check for like, whether you were getting strings or bytes everywhere.
Um, because you might be in Python two land where you might be in Python three land where you're getting strings and need to like do other conversions.
So it was especially bad because it's a collection of like kind of independent utility functions.
some functions build on each other, but every function could potentially be imported and used for its own little piece of functionality.
And so every single function needed to check all its arguments for like, am I a string or bytes?
So even if most of the time, especially nowadays, people aren't using VaricsOic directly and all these tools, they're using flask, which just does the right thing from the get go, which means all those intermediate checks on the way are totally unnecessary.
You know, because you already knew from like the first function that it's already testing 10 times for the same thing down the cross.
Right. And this was just pervasive throughout, VaricsOic was just everywhere with all these unnecessary checks.
And it made the code more complex to maintain reason about made the like execution slower.
Um, there's kind of a, another thing going on at the same time, which is like we had, because we could support like, because we were working with bytes in a lot of places.
Um, there was also like a lot more support for, well, maybe the data is encoded in this encoding or this one, but nowadays everybody like I looked at before I made this decision, I looked at stats.
Um, everybody, 99.5% of people, web applications on the web right now are using UTF-8.
So they're never dealing with other encodings.
And UTF-8 can encode everything.
Yeah.
Um, and, so like BericsOic was doing all these things about letting you pass encodings all over the place.
And switch between things.
And that was also complexity.
So finally decided, okay.
I had heard some anecdotes as well, from people who had switched from using Python 2 to Python 3 or had stuck with Python 2 and old versions of BericsOic because they had noticed a significant performance difference in the first versions of BericsOic that added that 2 and 3 compatibility.
Um, and so I figured, okay, I'm going to get a similar speed up if I remove that now, now that we don't support Python 2 at all.
Um, that was very complicated.
I basically like just had to go through every single function and start removing it, run all the tests, see what failed, pick another function to keep working on and just slowly, slowly pull it all apart.
Um, but I did end up with, so now BericsOic just supports strings everywhere except in the very few places where it works directly with the request and response data, where it, like, it was like.
Right.
Like multi-part form file.
Yeah.
When you first get the request in and it's just the raw body that you might turn into JSON or form data, et cetera.
Uh, or, when you're finally producing the response and taking like either file data, which is binary or, you know, string data and turning it into the bytes.
Um, that's the only place now where it deals with bytes everywhere else is strings.
And the boundary there is always UTFA.
Um, and if UTFA isn't your thing, it's not, we're not preventing you from using other things.
It just means that when you're at those boundaries, you pick the new, you know, you can take the bytes directly and work with them.
Cool.
Um, surprisingly I have gotten, like, this was a huge, massive change and I have not gotten any bug reports about it, which I'm just, I was, I was like, I was stressing so much about like, okay, this is huge.
I mean, we tested it first and, like maybe the releases and everything, but those go to almost no attempt.
Talk Python to me is partially supported by our training courses.
Do you want to learn Python, but you can't bear to subscribe to yet another service at Talk Python training?
We hate subscriptions too.
That's why our course bundle gives you full access to the entire library of courses for just one fair price.
That's right.
With the everything bundle, you save over 80% off the full price of our courses.
And you own them all forever.
That includes the courses published at the time of purchase, as well as courses released within about a year after the bundle.
Stop subscribing and start learning at talkpython.fm/everything.
All right.
I can't leave the house for the next week.
Publish.
Yeah, no, like you joke, but like, seriously, when I hit the publish button or when I used to hit the publish button, I would be like, I want to go for a walk now because I just did a ton of work and I just want to clear my
head, but oh God, then an hour from now when I get back, what is my inbox going to look like?
Yeah.
That's great.
And you know, you talk another part of your presentation at FlaskCon was about project level stuff.
And you also talked about the systemization type of thing you're looking for.
So one of the things you switched to is the trusted publishers.
That's kind of cool, right?
Yeah.
So I mentioned a little bit about like when we were talking about, sorry, when we were talking about pinning requirements, I was saying, oh, you know, it makes it a lot easier for every contributor to work on things at sprints if every single environment is the same.
And so kind of on a meta level, I, there's a lot of like different tools and configurations and workflows we use across projects.
But they've kind of been developed over time as I've learned them.
And so I've been doing, I've been doing work on like a meta level.
So every project now, if you go look at Flask and Verksoeg and Jinja and you clone, clone all the repos, all the repos look exactly the same.
And they all have the same files, the same directory layout, the same tool configurations, et cetera.
Because just like it should be easy for every contributor to get the same environment, it should be easy for anybody who's used to contributing to Flask to go over to Verksoeg and be just as comfortable in that project.
It's the Flask way and it all goes the same, right?
Mm-hmm.
So yeah, like trusted publishing, that was another big part of this was like making workflows.
So we have a workflow for running tests, for example.
But publishing used to be a very manual process.
And it's evolved over the years too, because we were on Travis before.
And then we needed to make like Windows builds for MarkupSafe, which has wheels.
So we were on AppVayor also.
Then Travis went away and stuff and GitHub Actions became more.
And so, but like that was all for tests.
Like for building, we basically, when we wanted to make a new release, it was way harder in the past, which is why releases happened less often.
So we had to do all the little bookkeeping stuff to like set the release version and the release date and everything.
Now I have to go get my Mac, get my Windows machine, get my Linux machine, make the builds on all of them.
Oh my gosh.
So we can manually like consolidate them, upload them manually to PyPI, etc. and make sure that all worked.
So what I have now is they have a standard publish workflow on every single project.
It works exactly the same way.
And you make a PR so that you can see all the tests run.
You know, you make a PR that just does that version bump and the date, you know, says the release date.
You watch all the tests pass and then you push a tag before you merge, you push the release tag and that kicks off the build workflow.
So we run our build.
We do SLSA or SALSA out of station, say like these are, these builds are associated with these commits in Git and were built by these workers.
It's kind of like a supply chain level thing.
And then we automatic, like it will collect all that stuff, show you here is the release.
Like here's a draft release for this here.
Like you have one more opportunity to look at the files and then a maintainer can go in and click publish in GitHub's UI.
And that will kick off like, okay, maintainer said everything's good.
We're just going to upload it now.
And that's all automated.
You don't, we're using the trusted workflow, trusted publishing workflow between PyPI and GitHub.
So I no longer have to have my password stored locally for PyPI or have like tokens made for each project.
All the authentication happens between GitHub and PyPI automatically and securely.
It's pretty cool.
If you go look up like trusted publishing on PyPI has like a blog or documentation that explains it.
But it is really, really convenient.
And it makes like this whole workflow means that whenever I want to make a new release, I just make a regular PR, push a tag and then see everything pass and say, yes, we're good.
So I just basically have to push three buttons now.
Yeah, that's fantastic.
Which makes it a lot easier to just make more regular releases.
Like even bug fix releases.
I was always unwilling to make them fast because it was so much work.
Well, if it's a matter of just pushing, pushing a commit and then saying, okay, you're way more likely to quickly ship fixes and ship smaller releases and all sorts of stuff.
It's really good.
So you don't have the whole supply chain problem of your machine somehow got hacked.
But then now when you do your build, somebody's injected something gnarly into the wheel, right?
Because it never goes through you.
It just goes from GitHub directly to PyPI through GitHub actions, right?
Yeah.
And GitHub added their own.
So the SLSS attestation that I was talking about, if you scroll down on this screen, you can see that multiple.intoto.jsonl.
If you click on it, it's just a big blob of text.
But that's basically describing here are these wheel files, like those wheel files and SDISD files.
And here's like signatures and about like the GitHub environment that built this and everything.
GitHub itself is adding that similar sort of attestation.
And then PyPI is also adding more attestations.
It's not out yet though, but I'm sure I'm testing it once they're starting it and release it in beta.
So being able to attest that like our build environment was consistent with what the artifacts you're seeing and like the upload along the way was secured and like it is gaining more, like that's more getting more attention nowadays.
Yeah, that's really trying to keep it all.
It's excellent.
It's also makes it easier to hand it over to someone else and trust that they're doing it right.
Not like something new.
Oh, they only like windows seven.
So you got a weird wheel or something now.
Yeah.
I mean, this.
Yeah.
This line is on.
It's like was such an impediment to finding other maintainers because you had to teach.
Like, I think I probably had some document that explained how to do this build before.
Like all the steps I went through, but it was like it was so complicated.
And like, yeah, if somebody else wanted to make a release, I would have to make sure they did everything correctly.
I had just gotten used to it.
It was like wrote for me, but it was a lot of steps.
Yeah.
Now it's just anybody does the same, you know, make a PR, push a button.
Everything else is done for them.
Yeah.
Yeah, that's awesome.
All right.
So the two takeaways that I got from Virksog's update was this dropping of the two to three juggling
made it 50% faster for request response.
And URL lib is no longer URL lib-ish.
Yeah.
So that was the other part.
If we're going back to Virksog.
So we removed the, the string bytes, testing all over the place.
And Virksog, this was again, historically because of like Python two versus Python three differences
and then compatibility and stuff.
But another of the changes in Python three was URL lib.
In Python two, there was like URL lib and URL lib two.
And that's why there's also the project URL of three.
Yeah.
But Python three kind of consolidated that back into URL lib with sub packages instead.
And so it kind of changed the interfaces and where everything was.
So at the time it made sense for Virksog to just copy that code into our own code base
and then make our own tweaks to it to be compatible with everything.
And, but what that ended up meaning was we had an entire copy of URL lib with our own tweaks in our code base.
And then we weren't keeping up with changes.
So like CPython has a, has like a hundred different core devs on it.
I mean, they're not all paying attention to URL, but they're making regular, you know, security updates or just performance improvements and that sort of stuff.
And we're not getting any of those benefits because we now have like this vendor copy that we've changed ourselves.
We couldn't even bring in the changes.
And just like the string bytes everywhere, it, it having that our own copy of that really complex low level code made it harder to reason about the code and be like maintain it.
And all this stuff is kind of like, it's not the essential parts of Virksog.
Virksog is like trying to be the WSGI utilities and stuff.
It's not trying to be like every single possible, like it's not trying to, we don't need to make our own URL of utility, everything to be Virksog.
Yeah.
So that was another big one where identified like, okay, this is just a lot of complexity.
I didn't actually expect this to be a performance improvement, but when I actually went through and removed URL lib and our own copy and replaced it with Python's version, we got like a 30% speed up just on our own.
So the combined of those two big changes was like about a 50% speed up in our request response handling.
Yeah, that's awesome.
Like it turns out that the, like Python's implementation of all this was just faster than ours.
And it's still, you know, does all the same things.
Yeah.
So now you don't have to mess with it.
You get it for free.
Yeah, exactly.
Like everyone else.
We can, like the, a lot of these changes, a lot of the changes in all the libraries, stuff where I've been, you know, like, like I said, I wasn't the original author of this stuff.
So I've had to like, learn the code bases.
I've had to like dig into them and say like, what is written here?
Why is it written this way?
How is it all related?
And along the way, I just keep identifying like, okay, this is the actual, you know, purpose of this library.
Does this fit into that purpose or can we be doing something different?
And so kind of trying to like slim down the libraries and like focus, tighten up their, the focus on their like purposes more.
Right.
If there's parts that are, it needs to work, but it's not its purpose.
Maybe that can come from somewhere else.
Yeah.
All right.
Yeah, absolutely.
We've got about 10 more minutes.
Okay.
Probably.
So what else do you want to cover to, to, to, to, the state?
There's there, I'll mention, Jinja and click really briefly because, these two libraries are also huge.
They're used everywhere.
Uh, downloaded a ton.
Um, Jinja is a templating library.
Um, you write template files and then you can render them with, you know, variables to produce output.
HTML, you know, but also like text files or all sorts of stuff.
Um, yeah, I think people, yeah, I think people pigeonhole Jinja2 much.
They think, okay, well I'm generating dynamic HTML from a server request.
Like you can use Jinja to generate all sorts of files.
I use it on, stuff basically on, Python generate like emails.
Somebody wants to reset their password, right?
Like I'll generate an email body from it, for example.
Right.
That kind of stuff.
Yeah.
And then click is a, just like flask is a framework for web applications.
Click is a framework for command line applications.
Uh, and both of these libraries have gotten a lot of attention from me, but they are not at inbox zero.
Unlike the other libraries, I have not managed to get them down there.
Uh, because I was working on all the other libraries.
And, so these are where I'm like going to need to focus.
Uh, like I said, like, like my current focus for the rest of this year is writing maintainer documentation.
So I'm trying to do less code and all of these libraries are stable.
Everybody downloads them.
Like a ton of people download them.
They all work.
You know, we can make them better and everything, but they're not in like, it's not like they're, immediate danger or need of anything.
But I do want to like clear out the backlogs of those as well.
And, you know, looking for more contributors for that, help with that.
Uh, you said you're looking for contributors who are really psyched about typing and also for God, if anybody isn't, if anybody knows, like is an expert in typing and like type annotations and static type tools.
All the libraries do pass my PI strict tests and, export.
Um, they're like, we do do some testing against PI, right?
To some degree.
Um, but I'm just typing.
Just, it's very hard for me to understand.
Like it's a very complicated, subject on its own versus all the other stuff I have to be doing.
So I really would like somebody who's like, I am an expert at typing.
I'm going to like start fixing up what you're, cause I like had to, I had to learn typing as I was like adding it to these libraries.
Um, yeah, yeah, that's a big thing that we can improve.
Um, okay.
Yeah.
And yeah, you know, there's like, we've gotten a lot of attention, a lot of the stuff in click and Jinja also, we have PRs for a lot of stuff.
It's just a matter of me having the time to go through and review all of them to cut down that backlog, but we're getting there.
I'll get there eventually.
Yeah.
Beautiful.
Um, and then the last, so the last thing I want to mention, or we ran out of time completely is, besides pallets, the core projects itself.
Um, I've kind of mentioned this theme of trying to make the projects more maintainable and grow the community and the team.
And part of that that I've started identifying is, the, the, the greater ecosystem around these projects.
Um, so flask is great to use on its own, but it's made even better by all the extensions out there that people have written, you know, for doing email, doing database stuff, authentication, all sorts of things.
Um, and just like flask itself, you know, and all those libraries, there was a long period where they weren't getting as maintained, you know, as much attention and stuff.
And then I started stepping in, a lot of those extensions were written quite a long time ago now.
And the maintainers of those have kind of moved on to different things.
And so there's a lot of stuff in the ecosystem that isn't getting as much attention as it needs.
And a lot of the times, maintainers are aware of this and they're willing to like say, like to take help, you know, to, to get help with those things.
And so, I was really inspired by a project for Django extensions called jazz band.
Oh yeah.
Uh, we're basically they're an organization that says, are you a popular Django extension or pip or pip-tools?
For some reason they also control pip-tools, but, do you not have time to be the maintainer of it anymore?
Uh, come over to jazz band.
We'll you'll, you'll still be like, you can still be involved in the project, but we'll also help you find more people from the community.
Like we will open up the maintaining, the maintain, maintaining process to your interested, you know, users in the community.
Um, and so I'm doing a similar thing with pallets called pallets eco or ecosystem.
Okay.
Um, so if you don't go to github.com/pallets, eco, yeah.
Yeah.
Pallets, dash eco, github.
What we've started to do is reach out to, maintainers of like, well flask, SQL, Alchemy flask, admin flask, security flask, mail, blinker caching, debug toolbar, like all these huge extensions.
So many of them, have these huge backlogs just like flask and all the other projects did when I got started with them, you know, and, their, their maintainers are overwhelmed.
And so I reach out to them.
I've been reaching out to them and, you know, kind of explaining, Hey, we're, we're starting this thing up.
Do you want to add your project?
Um, so we've had some successful already.
Uh, we've had people at sprints contribute to them.
And, like I was talking about, I've kind of standardized.
How flask and the other projects look like all the tools they're using the layouts they're using the workflows they're using.
I'm taking that same approach and trying to standardize all the extensions we get to.
Uh, so the idea is that anybody who's used to contributing to one of these extensions should, it should be just as familiar to them to jump into another extension and contribute there as well.
Right.
That's a great idea.
Yeah.
Um, and so with pallets eco, we can help find maintainers, from the community, add them, but the core team for pallets themselves still has access as well.
So, you know, if we make some change to flask that finally removes something that some, like some internal thing that somebody was relying on and like suddenly this popular live extension no longer works.
We at least have access.
Like we're not, we're probably not going to take on the responsibility of being the like core maintainers of all these things, but we can step in and make an emergency release that just, Oh, you just needed to change this line here.
Make a bug fix release really quick so we can at least keep the ecosystem going while we like work on finding longer term sustainability with more maintainers.
I love that idea.
Cause a lot of times it is a really small change, but if it doesn't work, it doesn't work.
Right.
Exactly.
Like a lot of the times it's been like, I like we have made like little deprecations and then remittles and stuff, which have just, that was the one thing that some random extension was relying on that every, like half the ecosystem ended up relying on.
And we just had to let you know, change a line or change an importer or add an argument.
Yeah.
So yeah, like that's, that's my big focus.
Now, if people are interested in contributing to pallets, they're welcome to, you know, contribute to like Jinja and click or any of the projects as well.
If there's open issues, they can work on them, but like a huge new source of like involvement for people can be, what are the extensions you're using?
Let's get you involved in those as well.
Yeah, it makes a lot of sense because to make a change to flask is, it's a highly polished piece of software, but the extensions potentially are more open to just jumping in and getting into it.
Yeah.
It's really, it's really hard for people.
It's hard to tell people this, but like, you know, people come in excited, like, Oh, I want to contribute to flask.
And then they look at it and they're like, Oh, three open issues.
What do I do?
You know, or like, and these three issues are like really low level stuff or like they've already been handled or something.
Sure.
And so we like, yeah, like what we're telling people now is like, okay, well flask, not only is it made up of these five other libraries, but there's also this whole extension ecosystem out there for you to contribute to.
Like everybody's heard of flask, you know, so we can point them at the right place.
They come to us and then we point them.
Yeah.
Excellent.
Well, I'll be sure to link to that in the show notes as well.
Yeah.
And with that, I think we're out of time.
Thank you for being here.
Just final call to action.
You know, people either want to contribute or just want to use flask.
What do you tell them?
Yeah.
So like I said, we're like developing all its eco.
I'm currently writing maintainer documentation.
So it'll make it easier for people to get involved in that way, writing a new website with a lot of our policies and everything.
But the main point of contact for all of this and the way we could coordinate with our community is on our discord server.
So if you go to discord.gg/palettes, that will let you join the palette server.
It's, you know, open to everybody.
We need help, you know, not only contributing to libraries, but answering questions in our questions channel or, you know, like triaging issues and all sorts of things.
There's lots of different ways to be involved in the projects without writing code.
And it all starts on that discord server.
Awesome.
Well, thanks again for being here and catch you next time.
Yeah.
Thank you.
Bye.
This has been another episode of Talk Python to Me.
Thank you to our sponsors.
Be sure to check out what they're offering.
It really helps support the show.
Take some stress out of your life.
Get notified immediately about errors and performance issues in your web or mobile applications with Sentry.
Just visit talkpython.fm/sentry and get started for free.
Want to level up your Python?
We have one of the largest catalogs of Python video courses over at Talk Python.
Our content ranges from true beginners to deeply advanced topics like memory and async.
And best of all, there's not a subscription in sight.
Check it out for yourself at training.talkpython.fm.
Be sure to subscribe to the show.
Open your favorite podcast app and search for Python.
We should be right at the top.
You can also find the iTunes feed at /itunes, the Google Play feed at /play, and the direct
RSS feed at /rss on talkpython.fm.
We're live streaming most of our recordings these days.
If you want to be part of the show and have your comments featured on the air, be sure
to subscribe to our YouTube channel at talkpython.fm/youtube.
This is your host, Michael Kennedy.
Thanks so much for listening.
I really appreciate it.
Now get out there and write some Python code.
Get out there and write some Python code.
you
Thank you.