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