Flask is one of the most popular Python web frameworks, and they have huge news to share
with us. Flask 2.0 just released after a ton of work, and it's as big a deal as the version
number suggests. Async changes are coming, Python 3.5 and below, including Python 2 support has been
dropped, and much, much more. Join me as I discuss Flask 2.0 with David Lord and Philip Jones.
This is Talk Python to Me, episode 316, recorded May 10th, 2021.
Welcome to Talk Python to Me, a weekly podcast on Python, the language, the libraries, the ecosystem,
and the personalities. This is your host, Michael Kennedy. Follow me on Twitter, where I'm @mkennedy,
and keep up with the show and listen to past episodes at talkpython.fm,
and follow the show on Twitter via at Talk Python.
This episode is brought to you by us over at Talk Python Training. If you want to learn Flask,
we built a fantastic course called Building Data-Driven Web Apps with Flask and SQLAlchemy.
In this course, we built a PyPI.org clone from scratch using Flask and SQLAlchemy. You'll
learn many of the major ingredients needed to build most web apps. If this sounds amazing,
just visit talkpython.fm/Flask or email us at sales at talkpython.fm.
David, Phil, welcome back both of you to Talk Python to Me.
Hello. Hello. Thank you.
Yeah, it's great to have you back. David, I've had you on to talk about Flask, and Phil,
I've had you on to talk about derivatives of Flask, I suppose, about Quart, your project. And
they're both kind of approaching the same type of thing and then sort of zeroing in. So now we have
you here together, I suppose, working on Flask 2.0, right?
It's all merging into one. Not really. Just our efforts. Still separate libraries.
Yeah, but it's really cool to see you working closely together rather than just two disjoint
things, right? I think that gives a lot of credibility, especially to Quart, right? Because
Quart was kind of this experimental thing. And now it's, if not exact, is it a Palette's project
officially or is it just working more closely?
It's working more closely. And in addition, it uses VerkZeg now, which it never used before. So
it's been quite a lot of work in that project to make that possible.
Yeah, that's really cool. And VerkZeg is like one of these foundational bits of Flask.
That's what we'll get into, I'm sure.
Yeah. So the idea is because Quart was supposed to be API compatible with Flask, we want to get it
using as much of what Flask is using as possible. A long-term plan is to get it using even more
works in VerkZeg.
Yeah, yeah. Super cool. Maybe some, it's dangerous as well. Get in there. Who knows?
It's risky, but you guys can make it happen. All right. Now, before we jump into the main topic,
Flask 2.0, you both have been on the show before. Often I ask people how they got in programming
in Python or whatnot. You've both answered that question previously. People can go back and hear
it if they want. So how much is it catch up? What have you been up to since you've been on the show
last? Bill, you want to go first?
Sure. I think in open source sense, it's been, yeah, working a lot on Quart and working more.
At the time, I don't think I was really helping with the Palette's project. So I've been helping with
them since. And yeah, just kind of developing those two and doing a lot of work trying to get,
well, the async support that's now coming to Flask, which is quite exciting. On a kind of personal note.
Yeah, very exciting. Yeah.
Yeah, on a personal note, I work in London. So I've just been, I've actually worked for a few
companies, tried my own startup. It didn't work, sadly. But yeah, working in London now. So that's good.
Nice. I love London. That's a fantastic town. I haven't been there in a year and a half,
oddly. I don't know why. And David, how about yourself? Where have you been up to?
So I'm trying to remember when we did our podcast last, but it must have been like three years ago.
That's been a while.
So yeah, after that, I've just been working down the backlog of all the issues on Flask and
palettes and all that. And now we're finally at the point where I'm confident about releasing
all this stuff. So yeah, it's just been more and more open source work. And then still working for
the same company I've been working for for 10 years now. So that hasn't changed at all.
Yeah, that's cool. And I suspect they're pretty supportive of Flask.
Oh, yeah, we get to use it internally. I actually introduced Python and Flask to the whole company
way back in the day now.
Yeah. I mean, how much of an advantage is that to have somebody like you?
Yeah.
We're so familiar with everything, right?
Yeah. When we're bidding for contracts and stuff, they definitely get to use that as like,
hey, we've got one of the maintainers of the libraries we want to use. What do you bring to
this table?
Yeah, exactly. What's the advantage you have? Well, have you met David? No, that's fantastic.
That's fantastic. And check this out. You were back on episode 177 and the title was Flask
goes 1.0.
Oh my gosh.
I feel like. Yeah, yeah. This is September 15th, 2018. So it's been a while. But also,
it's time to have you back because now you guys have incremented the big number in the version.
Well, not quite. Almost.
One more day.
Is it one more day?
Yeah, it's tomorrow.
Okay. So for people listening on your podcast player, that's like a week ago.
Oh, wow.
People on the live stream, one more day. Fantastic. Super cool. So I see some really interesting
questions from people who are watching the live stream, but let's dive into a little bit of
background stuff. And then I think we'll go from there. So I kind of wanted to start with the
larger landscape of the web. And maybe also you could tell us about, I just threw that out there
as if people would know the Pallets project. We talked about it a little bit with both of you.
David, give us an overview of what the Pallets project is because we have Flask and we have
Quart and then we have these other libraries as well. What's the relationship of all these things?
I know Quart is its own thing, but it uses like Brickzoic, for example.
Yeah. Well, Pallets is the organization, like just an open source organization, not an actual
company or anything that maintains Flask and the libraries that Flask uses. And so that's Flask,
Ferkzoic, Jinja, Click, It's Dangerous and Markup Safe. And it was started, all these libraries used
to be maintained by the original author, Armin, and his other group, Poku. And eventually they kind of
grew larger than that. And the original team kind of grew to do other things. And so he formed Pallets.
And that's about when I joined and started maintaining everything. Although recently I've come to the
understanding that as much as I push the name Pallets, I will never have as much name recognition
as Flask. And so you can also refer to things as Flask and I will know what you're talking about.
Yeah, no doubt. Like the general Flask obviously is made up of the foundational bits as well.
Yeah. Yeah. And so Pallets for a very long time was just the GitHub organization that these projects
repos were under. And I've been working over time to expand that into an actual open source organization,
kind of not nowhere near this yet, but inspired by like how Django software foundation works and those
sorts of things where they do things besides just develop. So we've been working on growing the
community, getting more maintainers involved, running FlaskCon last July, I think. And another
one is coming up, I think, in November is this tentative schedule.
Nice. And this is obviously, I would guess, online at this point?
Yeah, it'll be online still. It was online last time also, and it worked out pretty well. You can go
find all the videos on PyVideo. They're up there.
Yeah. Fantastic. Do you have sprints or anything like that around it, or is it just presentations?
We didn't do sprints last time because it was just our first time running a conference. We'll see what
happens this year. No concrete plans yet.
Yeah. Fantastic. All right. I kind of wanted to start off this conversation with a wider view,
looking at the Python web space. So I put up here for us to look at the Python developer survey from
the PSF and JetBrains for 2020. Obviously, it's 2021. But the results for that was the last survey
that have come out. And over there, we've got the web frameworks being used. And these things are never
comprehensive. There's 6% of other, whatever that means. But we have Flask now clearly being the most
popular one. So first of all, congratulations on that. That's awesome. I wonder if Quart was folded
into Flask or if it went into the other, you know, in a person's mind when they clicked the button,
which did they click, you know?
I imagine it's probably in the other and a small percentage. Very small.
Yeah. Nice. Okay. Well, so this is really neat. I guess the big interesting thing here as well,
beyond, I think it was you and Django, at least in this previous survey in 2019, were just tied,
basically. So now it's, you had talked about how there's a lot of growth and a lot of momentum.
And I think it's even more than what you see here on the screen. Like I think a lot of the APIs that
Flask embraces in the way of doing web programming has been adopted by many of the other new frameworks
as well. So for example, we have FastAPI making a jump up to 12% here, which is probably the biggest
difference from the year before as well. What do you think about this picture here? And then like,
you know, what do you think about just the Python web space in 2021, both of you?
FastAPI is definitely gaining ground. Flask, I'm continually surprised that so many people use
Flask. Never. It's hard to wrap your head around like that many people. I was just looking at the
downloads this morning and it was 14 million in the last 30 days.
In the last 30 days. That's so insane.
That's just Flask. Like if you look at like Jinja, because Jinja is used by
things besides Flask, like Ansible, we're like the 20 somethings.
Very cool. And you can use Jinja just on its own for super interesting things as well. Like
I recently did a project where I needed to generate a PDF that was like out of, you know,
here's data in a dictionary and I need to make a PDF that looks formatted. And I just use Jinja
and a Jinja template to generate the HTML, then feed it off to a PDF library that made it into
PDF, right? There's all sorts of little edge cases like that.
And same with Click. I mean, people use Click to make actual command line applications,
not just to provide a little CLI for Flask. So yeah, when you look at this, like you,
like you realize that like, oh, they're also using like all these other libraries,
but I never really like think about the numbers. I guess every now and then I remember Flask having
more stars than Django on GitHub, but that was because Django joined GitHub late and they've
surpassed us now, but that's about the only joke metric I follow really. But yeah, I've seen a lot
of interest in FastAPI and I think it's a, it's nice to just see that like none of nothing's
stagnating, you know, like everything, like there's, there's new ideas out there. People are developed,
like there's stable libraries that continue to develop like us and we were still adding new features.
And then there's like completely new ideas or new formulations of libraries.
Yeah. I feel like we're in a bit of a Cambrian sort of thousand flowers blooming type of time. And
many of them won't survive that, but there's a lot of fresh ideas out there and it's pretty exciting.
Yeah. Like having a healthy ecosystem, having choice that you can choose whether a certain
framework is more appropriate for, you know, the project you're starting or working on,
I think is really powerful for like users and for maintainers.
Yeah. And you can borrow ideas too. Like, Oh, I see the way FastAPI is doing types,
like mean this, maybe that makes sense to like allow that as an option somewhere else,
you know, who knows, right?
Well, one thing I quite like to take from this list is Falcon has a really quite exciting router.
And I think it might be a little too, too much for Verksug perhaps, but I've been playing around with
taking the ideas from Falcon and bringing it to Verksug. So what makes it exciting is it's a very fast
matching system and yeah, should outperform the Verksug router if we can get it in by a good fraction.
So that'd be exciting.
Yeah. There's a lot of interplay here that I think is pretty neat. And while we're on this sort of broad
topic, Rohit asks out in the live stream, you know, what are the advantages of using Flask over Django?
Maybe that pairs them up a little bit too tight, but you know, looking at this list,
these are the ones that probably the trade-offs people are thinking about.
Yeah. This gets harder for me to answer over time because I haven't used Django in a long time,
but it's hard to compare them one to one. It's like apples and oranges, right?
Like I said a couple of minutes ago, like you're choosing the project that's most appropriate or the
framework that's more appropriate for your project and the way you want to work. So it's not necessarily
that you're going to be losing out or getting any given feature by choosing one or the other. It's
about how they feel when you're working on them. You know, like sometimes Django makes more sense to
people or FastAPI makes more sense or, and then like they also have different goals, right? Like Flask is
deliberately just the web framework and wrapping some other libraries around it. But its goal is that
if you want other features, somebody develops an extension that is specific to that and you add
that on. And I mean, Django and I don't know about FastAPI yet, but like Django has the same idea. It's
just how many batteries they decide to include is different. Yeah. Yeah. Phil, you want to take a
shot at this before I give my thoughts as well, maybe? Yeah. I think specifically Flask and Django,
I always thought it came down to a kind of a choice about how to do things like Flask doesn't really
give you an answer and you can go and choose from the extensions, whereas Django does. And yeah, I think
it's like David said, a bit of what your preference is really, what you prefer. Yeah. I mean, Django is
making huge strides in like async also, and we're adapting to that too, but they all have different
solutions to the same thing and approaching it from different directions. Yeah, definitely. There's a lot of
interesting stuff happening in Django around this as well. So the way I see it is, you know, Flask,
it's like an empty canvas and it's got just a few really nice little building blocks and then you can
build what you want, right? You want to use Postgres and SQLAlchemy? Great. That's totally easy. You
want to use MongoDB and MongoEngine? Equally easy. Go have fun, right? Like you, you can pick just the
little bits that you really like. You don't have any other bits to worry about and then you're good to go,
right? Django, it's like, well, if you want to break from the Django ORM, probably you can do it,
but it's, there's a little bit of a mismatch there. You kind of got to work around it. Its advantages
kind of become less good, right? Like it's admin tools might not work as well if you try to say
switch to Mongo or something along those lines. And if what you want is like, I'm not really sure what
I'm doing to build this website. And I just want some guidance, like just show me the main way and I'll
just do that. I don't, I just would like to go along for the flow. I think Django is fantastic for that.
It gives you like really good prebuilt tools, like the admin stuff and whatnot. But if you really care
very much about which little piece you pick and you want to put them together just so, I feel like you're
better off with a micro framework of some sort like Flask. That's my, my view. And I know some people
love one side and hate the other and vice versa. So it's, you know, it's also a personal challenge or a
personal thing you got to work out for. Where, where do you fit on that spectrum?
Yeah. I mean, I personally started with Django. Flask was just being started when I was starting
to learn Python and web frameworks. And then I eventually ran into something where I wanted to
do things that Django wasn't designed to do, obviously. And I started running into a bunch
of stuff. And so I switched to Flask.
Yeah, that's cool. I know if you come from a, an ecosystem where there's like clearly one choice
for a lot of things, you know, if you come from Ruby, you got, you got rails and the Ruby ORM.
I'm from Microsoft, you got ASP.NET in a framework, like you don't have decisions. You just do the
thing. And then eventually you build your app, right? You come to Python, there's like, you know,
20 different choices at each level. And you're like, this is like the paradox of choice. This,
even though it's in some ways, it's great. In other ways, you're like, I have no idea what to do.
And so I think that can be a challenge for people as well. Yeah. But also an advantage
once you get into it. I think your best bet, if you're asking the question, should I use Django
or Flask is to just pick one and learn enough, you know, about that framework. And I think you will
be better equipped to answer that question for your project next time you have to ask it.
Yeah. Yeah.
It doesn't really matter what you start with.
All right. Before we get into a more specific, so sort of a general Flask question as well.
Ivan says, since Flask started as an April Fool's joke, does the core team,
David and crew, have any traditions around April Fool's? I haven't thought about that.
You know, every time somebody brings up that it was made on April Fool's,
I remember that it was made on April Fool's. I always forget that.
So I'm guessing not too many ones. Okay.
We don't have like a birthday party or anything or celebration. Maybe we should.
We'll bring it up to the community team.
There you go. There you go.
I think you put out a blog for last year, 10 years, didn't you? That was quite a good celebration,
but I think that was about it.
Oh, maybe it. Yeah. It's been 10 years for a lot of libraries at this point.
Yeah. Very cool. So let's talk Flask 2.0. You know, it's been a couple of years. It went to 1.0.
It was on the zero-ver train like so many projects were before then, right? That doesn't really mean
that it was such a huge transition, but there's a lot of stuff changing, not necessarily in a breaking
way, but a lot of new things in Flask 2.0. Give us the exciting news.
Well, the biggest one is probably async. I'll let Phil talk about that.
Yeah. There's like a async for Flask directly and then like maybe tighter integration with
Quart type of next level async, right?
Yeah, exactly. So with Flask 2, you'll be able to write async root handlers, depending on what you like
to call them, before and after request handlers and teardown functions. So it won't require any
special effort other than installing Flask with the extra support, but then you can just write async
and await and carry on with your current setup. You don't have to change anything else.
Yeah. That's super neat. And you actually gave a talk May 1st or something, 10 days ago.
What was it called? It was, why isn't Flask async?
And obviously that's like leading into where things are going. You want to tell people a little
bit about some of the ideas there? You talked about the history, obviously Flask being a
WSGI or WSGI application. Those are all naturally having a hard time moving to async because
the server itself needs to know. But then you also talked about some of the things that are
happening to allow some async stuff to run directly without any server changes. And then also moving
to an ASGI server. Yeah. So what's the story there?
So, yeah. So obviously Flask started as a Whisky framework. I think it was probably Whisky from
the start, right? So yeah, I know. Yeah. So I couldn't quite remember when Whisky was introduced.
So yeah. And obviously before Async await is introduced.
Yeah. We have all these different servers and I don't want to have just this framework run on
that server. So Whisky is born, right? But born in a world where async was less common.
Yes. But what it has supported the whole time, and I think what's good to point out is Flask has
been async the entire time just using greenlets. And a lot of people use that very effectively. I think
it's absolutely fine. And that for us, I think was one of the key things to bear in mind that
Flask works async. And if we introduce async await, we can't be breaking that at the same time.
So that was one of the big constraints really. And then, so for the one side, it's keeping support
with those existing async solutions. And the other is introducing the async await keywords,
which I think everyone has heard of the color problem and the virality associated with that,
which makes it actually really hard to get a little bit deep into the call stack, if you will,
async without really having to change the whole call stack to async in one sweep.
Yeah. The challenge, maybe I'll try to give a little bit of background just for people listening
is if I've got some low level data access library or service access library for like using HTTPX
or something, in order to await the thing at the bottom, that has to be an async method.
The next level up in order to call that method, it's got to be async. Then you got to await it.
So it's method's got to be async. And it just, it goes up the entire call stack in a lot of cases,
right? Yeah. So what it came down to and what we, what we did was follow Django,
what Django have already done really. And what they, they figured out is that you can run the
async event loop in one thread and the greenlet based one or whatever you were doing previously
in the main thread. And then everything coexists nicely. You just need these wrappers to,
to move things from one thread to another. And that library, if you're interested, is called
ASCII ref, but using that allows us to have this async code in the, in the view handler,
but keep flash synchronous in the rest and keep support with, with greenlet, which is really
nice. Yeah, that's really nice. And in production in a lot of the servers, it has threaded modes
already that if like you're awaiting something and then that something talks to a network, like a
database call or a web service call or something, it's going to release the GIL anyway. And the other
threads can run. So that can probably push out pretty far just on its own, right?
Yeah. It's, I think it's been very effective to a lot of companies. I know companies that use it.
I think it's been really nice. So that's what we've, we've got to, and I think you were talking about
where can we go? Can we go fully async and ASCII with Flask? And, this is possibly more of my
personal opinion, right? I'm not sure it is possible to go there with Flask. Cause I think if you do so,
you end up breaking extension support because it's quite common for extensions to extend the Flask
Clask and change the methods, but of course they won't be async. So how are they going to deal with
that? Yeah. There's the compatibility problem. And then there's also just the, the problem of having
mark everything as async await, if you mark one thing and we might discover, I'm a little more
optimistic than Phil, but I'm also not as experienced with it, but I would like it to be possible. Like
at some point for us, you know, we're focusing on like making a Verixoy sans IO. So it doesn't
require blocking IO operations when you make requests and stuff so that you can use it in ASGI
situations. And that's going to be a slow process. We're not like a hundred percent done with it or
anything like that. But my hope is that as we make Verixoy completely like IO agnostic, we might
discover some ways to adopt Flask. Yeah. But it's also not a hundred percent necessary because
cord exists also. That's an interesting point. Maybe there's a way to implement some of those
extension. So the problem is the extensions override certain functions that are part of the life cycle
of requests. And those are expected to be synchronous functions because they had been for all of time.
You can't just make those async and have those extensions still work. You know, at best,
they're going to be kicking out unstarted co-routines. You know, maybe it's probably worse
than that, but maybe, maybe that's what they do. I don't know. Something is not going to go super well,
but maybe you can create synchronous wrappers around the async stuff that can grab a, an event loop and run
it or something. I don't know. Like some, there could be some sort of an adaptation thing where just the
sync version maybe it's not quite as fast or something. I'm not sure as much experience you
guys have. I have a way less than that. So as a caveat, I was going to say, I think with Flask
too, I think this is, in my opinion, where you want to be because the motivation in my mind is you want
to use some async based library and there's, there's some exciting ones out there. So I can fully understand
that. And you can now in Flask and it will work, will work with your existing setups. I think the only
reason you could want to go fully async is, because you're only using async libraries perhaps,
or perhaps you might see a bit of performance improvement there, which isn't necessarily
guaranteed by the way for that though. I think there's court. So I kind of think all the users
motivations might be covered now, which I think is really exciting. That is very exciting. Yeah. And
our goal is just to get court and Flask as API compatible as possible. And they're already very,
very close, but you know, moving, very exciting that. And so like, ideally it should just be a
drop in like name replace for everything to keep working. Yeah. And you could probably pull it off
with just the right import statement, import court as Flask or something potentially almost.
Possibly. I don't know how Phil feels about that.
No, well, there's a, there's some monkey patching in court where you can tell everything else that
court is Flask. So you can use some of Flask extensions with court by allowing court to be there.
And it is Flask. It's just kind of, kind of fun.
Yeah. Yeah. That is quite, quite wild.
I did see a question. Will Flask break current extensions? No. Our goal was still compatibility
and stability. We are, we are making major releases and we are adding new features, but it shouldn't break,
shouldn't permanently break anything. You know, there might be some unforeseen incompatibility that
a library needs to update for, but it's not like they will suddenly have to rewrite their whole
thing async or something like that.
It's not, if it breaks it, it's not on purpose.
Yeah. That makes it sound bad too, but.
No, no. I mean, like your intention is to have it be compatible, right?
Yeah. Yeah. That's always the intention of these libraries. They're meant to be very stable.
And it's actually one of the things I've been working on as a maintainer, as I've been maintaining
these over the years, is when I do make releases or when I make changes, I try to make everything
show a deprecation warning first and then only remove it in the version after that. So I do
want to evolve things and refactor things or, you know, identify patterns that weren't great
or that don't, aren't needed anymore since we're dropping Python 2. I do want to evolve the libraries,
but I don't want to break anybody without warning them first. And so there's a ton of deprecation
warnings in all the libraries this time that you'll see if you're running tests.
That's cool. So speaking of that, yeah, I saw this really nice Flask 2.0 is coming. Please help us test
by Stetio. I don't know who this is. If you know, maybe you can give him a shout out.
Oh, that's me. Yeah.
Oh, is that you?
Okay.
Perfect. All right. Yeah. So from you, Phil, and he said from the changelog, one of the things coming,
well, first of all, one of the things coming is Python 3 plus, sorry, 3.6 plus only dropping 2 for
sure. And even 3.5. That's pretty interesting.
Well, 3.5 is end of life now. Yeah. Yeah. It seems so new in my mind, but it's clearly,
clearly not that new anymore.
When I first made the announcement of dropping Python 2, 3.5 wasn't going to go end of life
until like nine months later, but I decided to, I was going to drop 3.5 anyway. We won't usually,
usually we're going to, our plan is to try to wait for the actual official end of lives for Pythons
from now on, but 3.5 just, it was so much more convenient to drop it at the same time. And 3.6
is still supported, but the next versions after these will be 3.7 only because 3.6 will have gone
end of life probably by the time we make new releases. Right. Right. Okay. Very cool. And how
much the five versus six, was it just that 3.5 is going out or versus f-strings? We do use f-strings all
over the place now, but that wasn't the reason. I mean, since we were doing 3.6 plus, I decided to
like use f-strings in a lot of places. I don't remember what was inconvenient about 3.5, but there,
I mean, I do remember there was something, this was a year and a half ago now when I made this decision.
I think async was slightly different. I mean, look, if you're switching to two, it's a chance for a nice
break from some of these things, even if they've got a few months left. Exactly. Yeah. I was originally like,
originally 2.0 was just going to be like dropping Python 2 and making maybe a few minor changes. And
then I got anxiety about making releases and breaking everybody's stuff. And so I just kept
working on more and more stuff into 2.0 instead of releasing it. But because it's 2.0, that also kind
of gave me the opportunity to like identify more stuff that I wanted to deprecate than normal maybe,
or make more bigger features to add. Yeah. But it's a perfect time to do it with
such a big version number change. I want to pull out a few more things from now that I know it's
Phil's Reddit post here, which got 1.3, 1,300 upvotes. That's pretty awesome. Short form of decorators.
So instead of for routes or routes for you in London, instead of app.route, you know,
specifying get or post, you can just do app.get, app.post. That's easy, but nice.
Yeah. It's just a bit of a synthetic sugar really. It's a, yeah, should make it a little nicer.
Going back to the ecosystem, it's something the other frameworks will seem to adopt
Yeah. Yeah. Yeah. That's one of the big differences I've been seeing from the other
frameworks that they're very much like Flask, but they kind of put the verbs on the decorators a
little bit more. So why not take it back? Have you inspired them in the first place? Also,
you know, blueprints, man, blueprints are something I think do not get enough attention and love because
they're so nice for organizing your code into little bits and little categories of functionality
instead of, you know, trying to associate them all with the main app, the at app.
So there's some news around that for updates as well, right?
Yeah.
One of the oldest standing open issues, Phil decided to just like, oh, I can solve this. And he like
wrote something over a weekend, I think.
It felt like that.
Way to go, Phil. Now it's blueprints all the way down.
Well, I'll let Phil describe it.
Yeah. It's exactly like you can nest blueprints in blueprints. So I think the kind of code structure
is really helpful because now it doesn't have to be all in that one blueprint, right? You can split
over a few files and bring them in, which helps a lot. And there's other structures where maybe you
want to reuse some part of something in another blueprint. So you just bring in parts, but yeah,
you can just use that. And you can use the command register blueprint on a blueprint to register the
blueprint and carry on.
Yeah. You used to have to say app.registerblueprint and you would give it the blueprint and that would
help you build up the various pieces. But now you can nest them and they can be more hierarchical,
which is great.
Right. Before it was just one layer. You had the Flask app and then the blueprints. And so like each
blueprint could have a prefix, but people haven't actually asked for it for a while, but it's still
been an open issue and it doesn't seem unreasonable. People have wanted to like have prefixes for
prefixes. And so then you get nested blueprints and now it's possible.
Yeah. Awesome. Let me take a couple of the questions out of life.
Sure.
First, Doug Farrell out there. Hey, Doug says, Hey, I'm working on a book that uses Python
Flask as a primary example application. When might Flask 2.0 be released? And should I plan on updating
the book to use it? I'm guessing Doug didn't catch the very first opening bit because you said tomorrow.
Tomorrow. If you're interested in following Pallets news in general, there's at Pallets team on
Twitter and there's also palletsprojects.com slash blog, which has an RSS feed. And so we actually
have announced this already, but yeah, it's May 11th tomorrow.
Fantastic. And then John Sheehan says, you're right. We don't hear enough about blueprints.
I love blueprints. Yes, absolutely.
Right.
So I says, in our Talk Python Training web training course, which is a Flask covers,
it says Flask basically rebuild pypi.org with Flask. Is it used as a safe to use Flask 2.0? I think so.
Like David said, there shouldn't be any breaking changes, maybe deprecations. If you see them,
let me know. I can update that, but I think it should be fine. Right. Same reason that production
apps work. The, the like example apps should work.
This is the first time we've tried to do release candidates before we've made releases.
And so we actually have had release candidates up for about a month now for all the libraries
where you could test your existing code with the new versions. But I think in the future,
when we do this, we need to do a better job at advertising that. So something we'll get better
at over time, but yeah, cool. Wow. People listening now know. Then also I think interestingly related to
both the micro framework side of the story, but also the new features like, especially the async stuff,
Rohit asks, which will be the most compatible database to supporting framework for Flask.io on
one hand, like just do whatever you want. Right. But on the other, you've got Flask SQL
Alchemy as an extension. You've got the ability to use like tortoise ORM because of the async support.
Like there are new options, right? What do you think? Yeah. I mean, Flask makes no requirement.
It doesn't affect what database you use. Flask SQLAlchemy that will have a 3.0 release
similar to these soon-ish. I think I'm going to take a little break after this release first,
but it should continue to work. What's the, you know, SQLAlchemy 1.4
just released with the first async API and they're moving towards 2.0 as well
with a new API. What's the story around their new
API and the SQLAlchemy async support with Flask SQLAlchemy?
Is there anything overlapping there? So Flask SQLAlchemy is compatible with 1.4 right now. I did make a
little bug fix release recently for that. 2.0 is just deprecating things. So, and nothing that Flask SQL
Alchemy uses is going away. So it'll work with SQLAlchemy 2.0 when that happens. In terms of the async
stuff, we might, Flask SQLAlchemy, like the extension might have to do something if we want to enable using
that pattern. But we might also not because it's using a pretty clever use of greenlets to enable
compatibility between sync and async code. And Flask's async support should support that out of the box,
or not out of the box, but it's possible to extend it to do that.
Yeah, super cool. All right. Another thing I saw in the release notes was that around Vexoig,
there's performance improvements coming in Flask and Vexoig. Want to just give people a little
insight into what's coming there?
Yeah. One of the things I think the one that got the most attention, got some interest on the Python
subreddit, was an improvement we did to the form parsing. So I think there's this issue that's about
five years old saying it was a bit slow, especially for large files. And as David mentioned earlier,
we were looking at moving that to be Sans.io. And in the work to do that, the original author of that
issue actually came back and said, Oh, if you do this, you'll make it a lot quicker as well. And when
we did that, he pointed out, we've made it about 10 to 15 times quicker than the previous form parser.
So yeah, so if you're being sent files to your Flask server, it should be a lot quicker.
Yeah. Form data in general is faster. And then if you're uploading large files, that's way,
faster than what it used to be. Oh, wow. Like multi-part form upload type of files.
Yeah. So if you were uploading even like hundreds of megabytes, it could be really slow in some cases.
And so now you can just upload gigabytes of ISOs if you want. It should work fine.
Nice. Just like streams in or something.
I mean, it'll still take as long as it takes to upload.
Yeah. It doesn't make it worse. I see. Cool.
But I don't know. I think I'm trying to think if there were any other performance improvements in
Varick Swag. I know a couple of releases ago, we made a pretty big one where to our URL building,
which made it like 10 times faster or something that's already released. So, but it has been
getting faster. Yeah. Okay.
We haven't measured it. I think the work taking out all the compatibility shims and just going pure Python 3 should be noticeable.
Yeah. Since we removed all the compatibility code for Python 2 stuff, like literally the .compat.py files are gone
and all the code that was calling that. There's still some more work to be done on that in terms of like
accepting both bytes and strings in a lot of places where it doesn't really make sense anymore.
So there's still some overhead, but there's a lot less compatibility overhead than there was before.
But yeah, it hasn't been measured, but I expect that to be noticeable because when Virk Swag and Flask first added support for Python 3,
you know, going the other direction. So it was Python 2 only, and then it became Python 3.
Some people stuck with like really old versions of Virk Swag and Flask because there was a noticeable performance degradation by adding all that compatibility code.
So now that it's gone, it should be better.
Yeah, fantastic. I know the NumPy people, they actually got a lot better. They shrunk their code a bunch by dropping 2.0 or Python 2, 2.7. And similar for you all?
Yeah, it's just, I mean, besides the performance improvements, it's just more maintainable now.
I pushed really hard to drop Python 2.0 even before it went end of life. I started thinking about how to do it because I never used Python 2.0 back then, and I still don't know.
So every time I had to fix something, I had to like, oh gosh, now I got to run the Python 2.0 version of the tests and figure out how to like make some weird compatibility shim, you know, between the two.
So it was a nightmare maintenance for like maintainers and contributors.
Yeah, I was going to say it's probably easier for contributors as well now to come in because they don't have to, you know, a lot of people these days, they don't know Python 2, right?
Right, exactly.
They don't want to come in and like learn, you know, something from 10 years ago so they can keep it compatible. They just want to add the new feature.
Yeah. If you somehow have like a Python 3.5 application still, you can stick with Flask 1.1. You'll still get your application working just fine. I mean, we're not going to be supporting it because we just don't have that capacity.
But the libraries are fairly stable, you know, like we almost never get bug reports asking us to backport something, for example.
You know, I use Dependabot like pretty much anybody who uses GitHub does, at least for security.
Right. I think people have become a lot more aware overall of that they should be pinning dependencies and how to do that and how to upgrade intentionally.
And so hopefully over time that, you know, less people will be surprised by updates and their applications will continue working with the versions they work with.
Right, exactly. And if you're worried about these changes, just pin it to 1.11 or whatever it is and just let it be until you're really ready.
But also you'll get notified of any security issues that you might need to jump in and fix, right?
So I know what I was going to say is I don't remember seeing any around Flask and Rixzoig almost ever.
So they're pretty stable, it seems.
It's pretty rare for there to be like critical bugs or security related bugs reported.
We get stuff every now and then, but we just make a point release.
Yeah. And Rohit asked previously about like, why would I use something like Flask over say something like Django?
I noticed security releases for Django more often. And I think it's because they just have so much more going on.
Like they have a whole admin section with forms and input and you guys just, if it's not there, it can't have a vulnerability in it.
There's a much larger attack surface. Yeah.
Yes, exactly.
But it's not that Django is less secure overall though. I mean, first of all, they're releasing all these security updates.
So they're staying secure, but I think they have a much larger team. And so they have the capacity to do these sorts of analysis that maybe we don't.
I'm not saying like, I think Flask is insecure, but it could be that, you know, they're just, they've just got more eyeballs on these things.
Fuck like noticing like, oh yeah, we shouldn't do this. We can make it safer or something like that.
Yeah. Yeah. And I just think the surface area is so much larger.
Yeah.
It's bound to happen.
Maybe someday we'll be in that position for Flask too.
Doug says, oh man, trying to get in Django, my new job, so much magic, too much magic happening there for me.
But he also has a question that I think maybe, you know, Phil, you spoke about in your presentation.
Like does this release change how you run in production?
Like Unicorn versus Micro Whiskey versus who knows what? Hypercorn.
The good thing to say is that, no, it doesn't change it at all. It still works the same and you can still use Unicorn
and use the async capabilities now in Flask. If you wish to use an ASCII server, you can as well. You need some middleware and adapter to do it.
And there's some examples in the Flask docs if you want to see which one we recommend.
So you can choose any server.
But yeah, very important for me to point out that you don't have to change anything. You can just carry on as before.
Yeah. So if you want, how would you categorize? You actually in your talk spoke about a spectrum of async capability.
On one hand, you have Flask with its decent async support, but not full AGSI server capabilities.
And then you've got Court, which can be 100% ASGI. And so you kind of thought of it as a spectrum, right?
Yeah. So my idea is that if your code base is mostly sync, as it may have started, then Flask is a great choice.
If you want to add a bit of async here and there, it's still a great choice.
It's only when perhaps you want to go fully async or you've mostly async with maybe a few sync pieces of code that you actually would choose Court.
But I think the really nice thing for the user is you can hopefully just go across that spectrum, eventually change the name, but then just continue.
And it's a pleasant experience is my hope.
Yeah. Awesome.
You should still be able to use the same WSGI servers, basically.
Like we've said a couple of times, like we're not breaking anything.
We're not changing how Flask works or anything like that.
So you still deploy it the same way.
And if you do want to use an ASGI framework or server for some reason, you can always use an adapter to serve a WSGI app over ASGI too.
You just don't get any of the benefits, really.
Yeah.
And Doug makes a good point out there that Flask for the Wind is still making G-Unicorn a good solution.
With G-Unicorn, you can change the worker type, right?
You can let it be the regular one, or you can say, I think it's dash K for the option.
Change the worker type to UVicorn workers, which would switch it to be an ASGI version.
So you don't even necessarily have to change anything, but like part of your command line for your startup of your G-Unicorn.
And that could be the total change you have to do.
And going back to a point that Phil made earlier, in the same way, you could change the worker to use like G-Event or something and already have an ASYNC Flask, just, you know, with an older version of ASYNC code or an older implementation.
Yeah. And Joe out there says, I had to look at the new ASYNC I-O features, but it seems from the docs that it's early days and maybe later versions will get more ASYNC I-O adoptions.
I guess that's a good direction to have a quick chat about.
So what's the, so this is 2.0.
Is this where you see it sort of landing or do you see this as a progression?
I think it's fair to say it's a, it's a progression.
Definitely.
I mean, the ideal outcome in the end would be to somehow merge Flask and Quart users, be able to use any amount of ASYNC and, or Biaski or Whiskey and everything just, just works nicely for them.
Really.
Again, as I said earlier, I'm a bit skeptical about whether that could be the one namespace I just call Flask or whether you need to split it up as it is now.
But yeah, I think it's the start.
Hopefully we can, we can keep going.
Yeah.
Like the ASYNC stuff we've gotten there so far is for supporting the most important thing that we thought people were needing ASYNC for, which is I have some ASYNC code or like I'm using discord.py, for example, to write a discord bot or something.
That's all ASYNC, right?
So if you want to write that code, you need to type ASYNC def and put your code in there.
Right.
So we're enabling that.
We've got extension points to change, you know, what ASYNC IO loop you're using, like ASYNC IO versus Trio versus Greenback.
Or UV loop or something maybe.
Or you, I'm not sure if that would tie in.
Phil might be able to answer that.
And then like, you know, addressing things like being able to do web sockets and that sort of thing.
We might be able to do that in Flask eventually, or that might be the place where you switch over to the Quart namespace.
And, but you're using the same API.
It's just a different name.
Yeah, Phil, that's something I wanted to ask you about it.
Just to let you give a quick shout out about is the web socket support that you all have in Quart.
Oh, yeah.
I mean, I don't know if there's much more to say than it.
It's definitely supported.
And you just go ahead and use it.
It supports web sockets.
You did bring some of that stuff back to Verksoig, though.
Because you're using Verksoig in Quart, you needed to be able to route to web socket URLs as opposed to HTTP URLs.
And so we now have a way to identify in our Verksoig router whether something is intended to be a web socket or not.
So it'll change based on the scheme you're using.
I think it's good to point out that Miguel has a kind of experimental support, I think, in Flask as well for web sockets, which is good to keep an eye on.
We'll have to see how that goes.
Oh, yeah, that was really cool.
I don't remember what it was called or anything, but there's a way that G-Unicorn will let you take control of the HTTP socket from an endpoint.
And so within your Flask view, you could take over controlling the socket and start treating it like a web socket instead.
Like an upgrade type thing?
Yeah.
So you still are in Flask and WSGI mode.
So you're still like sync in terms of one worker is blocked handling that one thing.
But it's pretty clever.
Yeah.
And Joe out there throws out that it's Miguel Grinberg.
Justin is the Miguel you're talking about.
Yeah.
There's also Flask socket IO, but this is like a more native thing where you can just do this directly in Flask instead of needing an extension.
So cool stuff.
Yeah.
Super cool.
All right.
We're getting sort of short on time.
So I want to ask a couple of questions.
Hit on some high notes as well here.
One of the things that I think is pretty exciting that GitHub has done, you know, GitHub, I think, continues to be pretty neat.
And one of the things they've done is they've added sponsor support for projects.
Has that been helpful to you all?
Yeah.
We've gotten quite a lot of support.
We're part of the PSF.
And so we take donations through them.
If you go to palletsprojects.com slash donate, you get the PSF donation page.
We've got lots of people, you know, making one-time donations or scheduled, you know, monthly donations.
And we're also part of Tidelift, which is a commercial sort of open source support service that we're getting funding through.
And we're also, I mean, this isn't really a sponsor link, but since we host all our docs on Read the Docs, we're partnered with Ethical Ads, which is their advertising platform to share the advertising revenue on all our docs.
So we're getting quite a bit of funding.
We're going to put it towards Flask conferences.
Yeah, that's fantastic.
That's good to hear.
I do feel like there's probably a handful of billion-dollar companies that are using Flask at the core that maybe could click that link and do a little more.
But, you know, shout out to them.
If you're using Flask at your company, take a look at the sponsor links.
Yeah.
We have lots of plans for what to do with it.
Yeah.
I was really happy to see GitHub put this in here because, like, just having, like, a little, you know, buy me a coffee link on the side of a homepage, that didn't seem like it worked.
But I think this sort of central way, and what's interesting is I didn't realize that you could link to external sponsors.
Like, my thought was that that sponsor button really was going through the GitHub sponsor channel or framework or whatever.
People recommend that we use GitHub sponsors as well because a lot of companies who are already in GitHub's ecosystem have an easier time clicking that button than something external.
So that's something I will be looking into.
Kind of like App Store versus not App Store.
Like, first go to our site to buy a type of integration, right?
I feel like it's almost like that.
I would definitely recommend it.
I've sponsored some things through the sponsor button there, and it's super easy.
Okay.
Mars.
How about that?
Yeah.
Flask is on Mars or help the lander get to Mars.
And I bet if I pull this up, let me see if I can find your user profile here.
I just have to hack the URL.
It's going to have to be that way.
And I go down here.
Here you go.
You have the official achievement, Mars 2020 helicopter contributor.
How awesome is that?
Phil, do you have one of these as well?
Yeah, I think so.
Yeah, yeah.
I'm so jealous.
I want one of these.
Everybody who's gotten a code contribution to the repositories should have that badge.
And there's been plenty more people who have contributed in other ways that should have that badge, but don't.
Yeah.
You should also have the Arctic vault contributor.
Oh, I have the Arctic one, but I turned it off a while ago because I thought it was kind of silly.
Yeah.
This one is way more.
I don't know how that whole system works, but if they had archived Flask 2.0 after all my work was done, I'd be much happier.
But they archived it like two years ago now.
Yeah.
So there's a lot of ways in which Python is being used on Mars.
When the lander first landed there and, you know, people said, oh, look, there's the F prime library that was used to power the Ingenuity helicopter.
That means Python's there.
I'm like, ah, it looks like maybe Python just trained the model and C++ was there.
But it turned out in the lander that went down, actually the cameras, all the different angles were controlled by Python.
And then getting those images back to JPL was part of Python.
And yeah, what's the story of the Flask and Mars?
This is so cool.
Yeah.
So Flask is actually part of F prime.
So F prime is like their, I'm not an expert on this, but it's like their flight control software, I think.
So it's like a monitoring dashboard for everything.
So they're using Flask to provide like all this information about the launches and flights and landings and get updates in real time.
So I think that's where our stuff came in.
But I'm sure other parts of their code are using Jinja or click in other ways, not necessarily through Flask.
Yeah.
Wow, that's so cool.
What did you all think when you heard this?
Every now and then I'll see like a, you know, some big thing like this F prime and I'll, they won't have mentioned Flask or anything, but I'll have to like, somehow I'll have like this intuition that it was used.
And so like, I, I went and just looked at F prime and I like, I'm like, oh, it's Python requirements.txt.
Flask.
I went and announced it on GitHub.
I'm like, wow, check this out.
Yeah, that's super cool.
Go to the dependency graph.
I'm sure we'll see.
Yeah.
Look what number one dependency right there.
There we are.
In Flask or RESTful.
Yeah.
Something to do with APIs here, right?
Yeah.
Cool.
All right.
Let's, I guess, round this out with two things, actually.
Real quick, though.
I want to take a question, I think, or follow up comment from Ikivu.
Might be off topic.
They say they would love to know more about how to convince a large employer to spend money sponsoring an open source project.
I wish I had a good answer for this.
I know there has been thought on this.
I'm just not the best person to talk about it.
I'm not an expert yet.
I would say, look at Tidelift.
Their company and their whole job is to be that in-between between open source who doesn't know how to convince companies to do this and companies who are using a lot of open source but don't know how to analyze their dependencies and divide up their support.
And so if you go look at Tidelift, their whole goal is to enable that sort of thing and discuss it with management and all that.
That's not good.
Tidelift.
Is it?
Maybe Tidelift.
That's not good.
They might be down temporarily.
Never seen that before.
Maybe HTTP versus HTTPS.
Yeah, so that place.
I do think this is a good option as well.
You know, they sponsored TalkByThon for a little while.
And I think they're definitely trying to be creative in this, right?
They're trying to offer something to employers that's not just put it on your charity column in the balance sheet.
They're like, we don't have a charity column in the balance sheet.
What are you talking about, right?
So doing something a little bit different there.
You can look at it, I think, as a company as part of your recruiting spend.
I think every company knows how competitive the market is.
And I do think engineers do like what interests and what you do in the open source community and look at it in a positive light.
So I think that might help.
I totally agree.
A couple other quick follow-up questions.
Olga asks, can F Prime connect to APIs on Earth?
Like, do you guys know anything about this?
I think it is used on Earth as well.
I mean, like I said, it's like a monitoring dashboard.
So it's not something that's actively running on the rover, I think, from what I understand.
I think it is accepting data from sources like the rover and other systems and then displaying that and coordinating it.
Very, very cool.
And then Joe asks if Armin Roeneker's still involved with the project, any?
Armin is not.
He's still part of the GitHub organization and he's like in our maintainer channel on Discord, but he's moved on to other things.
You know, he's working in Rust a lot and other things.
My impression is he's kind of moved on to Rust and is just enjoying his time there, which is totally fine.
Like people don't have to stick with one technology their whole life, right?
Right, right.
They make big contributions.
That's one of the things I've been trying to do, too, since I became a maintainer was get more maintainers, right?
So it's not just Armin and then after Armin, it's not just me.
You know, I'm trying to expand it so it doesn't matter if Armin or I are still involved.
Yeah.
And Box of Ninjas out there says, I need the Mars endpoint.
Yeah, I don't think they just let that out to anybody.
Yeah, there's probably...
They don't put auth in there.
It's hard to find the endpoint.
Next to the right satellite at the right time.
Exactly.
You can just tunnel over there.
All right.
So I think that's probably all the stuff we got time for.
But, you know, thank you guys for covering this.
Let me ask you the last two questions before you get out of here.
If you're going to work on Flask or Quark, what editor do you use these days?
I've been using PyCharm for almost a decade now, I feel like.
Pretty much since I started using Python.
So PyCharm, all the way.
Right on.
Bill?
I use Emacs, although I've used VS Code a few times.
If I ever record something, I use VS Code.
But yeah, Emacs is where I do the work.
I do it right down the bare metal.
Cool.
And then recommend some library package you all have come across recently that you're like,
oh, this is super cool.
People should know about X.
Any ideas?
I'm really enjoying using Pydantic to validate the incoming requests, like just as a data
class setup.
I know you can do it with different ones as well, but the syntax seems so clean just to
say this looks exactly like a data class and I just use it to validate my incoming.
It's great.
That's fantastic.
Yeah.
One of the things I've started to do as like the first line in my Flask API endpoints
is to say Pydantic model equals, you know, class star star.
What is it?
Request dot JSON.
Something like that.
Like just immediately try to convert it to invalidate it with Pydantic.
Something I learned recently, I had Samuel on the show who creates and maintains Pydantic
is, although I didn't learn about it on the show, someone else pointed out to me, there's
a, like a secrets capability built right into Pydantic that like works with like .env files
and all sorts of stuff.
It's got this whole mechanism.
So yeah, that library does a bunch of cool stuff.
I don't have a good answer for this because I've been just dealing with Flask itself for
so long and getting those ready that I haven't really been exploring new stuff for myself.
Does this mean I get another?
You can have another, but yeah.
So like hopefully I get to learn about some new libraries as soon after, you know, Flask
2.0 goes stable.
I will say at work, and this isn't official yet because we're going to, we need to write
documentation.
It's totally unusable right now because it's not documented, but we've been working on a
open source library called AutoInvent, which takes a data model, like such as your SQL
Alchemy models and produces an entire GraphQL API and React front end.
From just the data model, plus like customizations to some metadata.
Oh, that's cool.
It's super handy.
It's really cool.
It's completely undocumented.
So I will at some point, maybe half a year from now, announce the actual project.
But if you go to an autoinvent.dev, you can see all our messy code right now.
Nice.
Bill, you got one more.
Go for it.
Oh, yeah.
So Trio, if you've not heard of it, is a different Async Await-based event loop implementation.
And I think I really like it because the structured concurrency it introduces is the way, I think,
the most Pythonic way to do Async Await.
Yeah.
Trio is neat.
I had the, I don't remember the maintainer's name, but I had him on the show.
Nathan?
Nathaniel, that's right.
I had Nathaniel on the show.
And yeah, it's super cool, like how you can have dependencies between, you know, this
task, created those tasks, and you cancel one, you cancel them all.
There's a lot of interesting patterns that come out of there.
Very neat.
All right.
I think that's it.
David, Phil, thank you.
Quick shout out or a quick final call to action.
People want to get into Flask 2.0.
They want to upgrade their stuff.
Maybe they want to take advantage of the Async stuff or whatever.
What do you tell them?
Where do they go from here?
Well, look for that new version releasing tomorrow or a week ago, depending on where you listen
to this.
Follow Palette's team on Twitter if you want to see announcements for new things.
And also, if you're interested in like contributing to these projects, I would encourage more people
to go on GitHub, you know, at least star the projects you're using, but also watch them,
you know, watch for new issues coming in.
Anybody can pick up one of these things and help out.
Yeah, you know, I think star and fork are the ones that get all the attention.
You know, one thing that GitHub just recently added, I know I said that, but I just want to
give a little quick awareness to people.
I think it's super cool.
If you forked a repo, it used to be you'd have to go to CLI and, you know, add an upstream
origin.
And then you have to kind of keep that in sync.
Now they've added a button that if you go to a fork and it's yours, you can just click
a button and go sync my fork with the original now.
And I think that, you know, encourage people to fork it and just stay up to date a little
bit easier.
So that's pretty cool as well.
Phil, final call to action.
What do you say to folks?
Maybe something core focused?
I think it would be go out and use it and let us know if it solves your needs, if it does
what you want.
Yeah.
Awesome.
All right.
Thank you both for being here.
Thanks, Michael.
See you later.
Yep.
Bye.
This has been another episode of Talk Python to Me.
Our guests on this episode were David Lord and Philip Jones, and it's been brought to you
by us over at Talk Python Training.
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.
Bye.
We'll see you next time.