#389: 18 awesome asyncio packages in Python Transcript
00:00 If you're a fan of Pythons Async and await keywords and the powers they unlock, then this episode is for you. We have Timo Fur here to share a whole bunch of Async IO related python packages. Timo runs the awesome Async IO list and he and I picked out some of our favorites to share with you. This is Talk Python to Me episode 389, recorded November 3, 2022. Welcome to Talk Python to Me a weekly podcast on Python. This is your host, Michael Kennedy. Follow me on Mastodon, where I'm @mkennedy and follow the podcast using @talkpython, both on fosstodon.org. Be careful with impersonating accounts on other instances. There are many. Keep up with the show and listen to over seven years of past episodes at Talk Python FM. We've started streaming most of our episodes live on YouTube. Subscribe to our YouTube channel over at Talkpython.FM/YouTube to get notified about upcoming shows and be part of that episode.
01:09 This episode is sponsored by Microsoft for Startups foundershub.
01:13 Check them out at 'talkpython.fm/foundershub' to get early support for your startup. And it's brought to you by Sentry. Don't let those errors go unnoticed. Use Sentry. Get started at talkpython.fm/sentry. Transcripts for this episode are sponsored by Assembly AI, the API platform for state of the art AI models that automatically transcribe and understand audio data at a large scale. To learn more, visit talkpython.FM/AssemblyAI. Hey, Timo.
01:43 Hello, Michael.
01:44 Hey, it's great to be here with you. I'm super excited to talk about Async Python.
01:48 Yeah, same. Good to be here.
01:49 We've spoken a little bit through GitHub. I think it's odd, but also kind of awesome how many connections are made through places like that. Right. Like, we've never met in person, but we previously chatted about some Async things on GitHub.
02:03 Yeah, it's always nice to kind of see the same people again, which you met, like, online in a call or something.
02:09 That's why I really enjoy going to conferences. Because you're like, oh, yeah, you're the person I've been talking to for six months now.
02:15 Excellent.
02:16 Yeah, cool. Well, I'm super excited to talk about all the awesome Async Python things that you've curated before that, though. Let's just get into your background. What's your story? How did you get into programming in Python?
02:27 Yeah, so I started programming, I think when it was around ten years old. At the time, I was exploring at an offline computer from my parents, which didn't have a lot of things on it, but there were a few applications, and one of those were, I think it's called Front Page, like Microsoft Front Page and Publisher, which is like yes.
02:46 It was like Microsoft Word for creating websites. It was insane.
02:49 Yes, exactly. So I was playing around with this and just exploring whatever was there because I didn't have any Internet. And that's how I got interested in how things are built in a computer and at some point I got the Internet. I kind of browsed around to see how these websites really look like and that's how I got into PHP, HTML and did some website stuff.
03:11 Couldn't you open a website in front page? Couldn't you point it at a URL and say, open this and it would pull it on the HTML into the editor? I think I remember, I don't know if you remember what a weird piece of software that was. Sorry, I don't need to do it. I just thinking back of like the early web was a weird time.
03:26 I more use publisher than I used Front Page because it was a more complex for me at the time and I didn't really have any documentation or tutorials, so it was more like fiddling around and getting something to work and something to happen. Cool.
03:40 So you found your way to PHP?
03:42 Yeah, then I went to PHP, did some very basic websites like guest books and these kind of things with PHP, but nothing really big. And then after mandatory school years here in Switzerland, I started an apprenticeship at Roche, it's a pharmaceutical company. So if you've done any PCR tests lately, you probably have done that on an instrument of them. And there I was in a team where we did hardware simulation testing for software, which is running on these instruments and all these like the testing framework around. The simulation was in Python and that's basically how it started. In Python?
04:16 Yes.
04:16 It's mostly like testing code and providing frameworks in Python for testing.
04:22 That's cool. That's a neat way where you can connect your code to physical things. Testing.
04:28 Yeah, it's super nice.
04:29 Like a lab equipment and stuff.
04:30 The simulation at the time, it also had some 3D visualization, so you could see motors moving around. They kind of see pipefense colliding and these kind of things, which was pretty awesome for me at the time because it was my first job, basically.
04:45 It was super cool. We also built with Python like a distributed testing framework or testing system, kind of like you would have in Jenkins these days, or any other CI system.
04:57 They probably don't have as easy integration to actual hardware.
05:01 When I pushed to this branch, I wanted to fire up that robot. Okay, exactly.
05:06 And also a huge problem is like error case testing. You can't just break a needle in an instrument while when you're running something, because either you get hurt or it just costs you $1,000 just for breaking something for testing. So you need some kind of simulation to actually do that.
05:22 Yeah, very fun. How about now? What are you up to now?
05:25 Yeah, I started a new job at gitlab. I'm a senior backend engineer in the Configure group, and what we're doing is we provide Kubernetes integration for Gitlab, Gitlab projects and groups, these kind of things, and also are responsible for the infrastructure as code features like the TerraForm State, Backend and TerraForm Provider, which also I've been maintaining for a year now. It's just like an outside contributor, but this is mostly Go, maybe. You know, Ruby is a big player in GitLab, so the entire GitLab rep was mainly a Ruby application.
06:00 Give us the elevator pitch on GitLab. I should use GitLab instead of GitHub or something else.
06:07 What's the value proposition for GitLab?
06:09 It's a good question. What do you see here also on the screen is that it's called the One DevOps platform. So it provides much more feature, I think, than GitHub in terms of like front planning to production, then monitoring an application, get all these insights, which you cannot really do on GitHub. So you have all you basically have features for all the DevOps lifecycle stages. Here, for example, you see the verify where you have a very powerful pipeline integration. The open source world is happening on GitHub, but a lot of enterprises are using gitlab these days for developing their applications.
06:44 Yeah, it's definitely an important piece of the puzzle out there. And how long have you been in GITLAB?
06:50 Just one month, actually. Today marks my one month being at GITLAB.
06:54 Wow.
06:54 Yeah.
06:55 You're probably just starting to get comfortable with how stuff works and how you deploy things and so on.
06:59 Exactly. It was a lot of onboarding, but I've been contributing before, so not everything was new. And I've been using Gitlab as a user, so sure, it wasn't that hard. I would say cool.
07:08 All right, well, let's go ahead and jump into your project. Sure. It's one of these awesome lists, and it's about one of my favorite aspects of Python because at Async IO Async and Await, they let you write such neat software that really takes advantage of latency, and when other parts of the system are busy, you can just keep on going without rethinking how your code works all that much. So I'm a super fan of Async and Await in Python and all the languages that use it, I suppose, because I just like the idea. But tell us about your project and maybe first start with like, what the heck is an awesome list anyway?
07:42 An awesome list is just a curated list of projects or whatever the awesome list is about. It could be recipes or whatever, and it's just trying to collect awesome pieces of that theme. In this case async I O, which are Async IO packages or projects, and you basically showcase them to the readers and they could take inspiration for the next project stack or can just explore what's out there and what people feel that is awesome.
08:11 I'm not an expert in all of these by far, so I'm more like librarian off the list and rely on people contributing actually their awesome projects or ideas or whatever.
08:23 Yeah, neither. Just as a disclaimer upfront, neither of us are maintainers of all these projects. We're not super experts. It's more of a survey of all the cool things. And I do think that's one of the really cool powers of the awesome list. I remember the first time I found awesome Python, I was like, wow, look at all these things I didn't even know existed. Right. It's not necessarily that you use the awesome list to make a decision about what you use, but it's like a good starting point for research, depending on whatever area. Like you've broken your list into stuff about databases and about networking and about web frameworks. And as we'll see and you go to that section you're interested in, here's my ten research projects to figure out what I want to do.
09:04 I think it's also nice to just once in a while to browse to it and see where the ecosystem is at and what new things have been popping up.
09:12 So another thing I think maybe it's worth touching on. I get the sense, although I'm not 100% sure because I'm asking you now that these things that get put there, it's not an exhaustive list. It's more of things that the community thinks reaches some threshold for interestingness. So under the PRS, I see you got a new one an hour ago. Yeah. So that's under the PRS you have please vote before these are accepted. Because what it means to accept a PR is really to add a line to a reading. It's not like a super, oh boy, how does this affect our overall performance? There's not a lot of considerations in that regard, but the question is sort of let's talk about whether it belongs on the list. Right. How do things make it on your list?
09:56 It's a very good question, and I've never been really strict about these rules, and maybe I should be, I don't know. But I usually put this please vote label on pull requests just to see if people are interested in this. Usually I also check things like the stars, when was the last contribution, like, how many contributors are there? Because if we put something here on the list and then people start using it and burn out some maintainers of the library, we just wanted to publish something. I don't know if that would be a good idea.
10:26 Right. On the other end of the spectrum, you've got maybe there are people who publish something just for the heck of it, but there's one person, they've touched it two years ago, and it's not necessarily something you want to recommend. If there's five stars and no one's using it, is it really going to be good enough? Okay, cool. So I'm guessing it's open for people to go and do more PRS and suggest more things if they listen to the show and they're like, but you forgot about this awesome thing.
10:52 Yeah. If people are listening and have something awesome, please create a pull request. Always great to have some additional
10:59 All right, well, let's go through it. So I think we'll just take it section by section or topic by topic. And I know you pulled out a couple of things that are interesting to you. I grabbed a couple as well, and we'll just touch on them, kind of work on that awareness and cover the broad spectrum of what's available. So we'll take it, I guess the top section that you have here, probably the most important section, I would say, is Web frameworks. Right. There's some interesting ones. First of all, it's kind of notable. The ones that are not there yet, maybe actually, maybe there's some PRS that should be making their way there. The really traditional web frameworks that people think about are not there. Right. We don't see Flask directly, although through court it's there, which is kind of its full Async implementation. Django is not listed. Bottle, Pyramid, a bunch of these older ones, but the really hot new ones are here. Right. Like, we've got FastAPI and Sanic and some of the others as well.
11:53 I guess people are just probably more excited about those, and then they're kind of hyped and at those, and that's probably why they end up here and not having, like, Pyramid or the other ones.
12:03 Yeah, well, Pyramid doesn't have an async version, but it's interesting that Django does. And I think maybe somebody should do a PR for Django now that it actually properly supports all the way to the database layer, but until recently it didn't. And what's notable, I think, about all of these frameworks that are here on the web one and pretty much for many of the others as well, is not just they have a capability to do Async, but they were kind of born to be Async. Right?
12:31 Yeah, you're right. And I think also some of them, I mean, they're all they're not all on the same level, I would say. Like, we have Starlet, which may be like a very lightweight framework that others kind of build on top, like FastAPI, which started maybe more comparable to Quart than Quart to FastAPI.
12:51 Right.
12:51 So you have these kind of different layers or people could build upon. And so it's some variety here. Yeah.
12:56 And you've got a couple of WebSocket style ones in here as well that are maybe not full frameworks, but they work in that regard. Yeah. So notable to me here, certainly FastAPI is definitely taken the world by storm. It only came out a couple years ago, and it's already got 50,000 GitHub stars, and that's close to what Flask and Django have. It's certainly a popular one. Have you gotten any chance to play with FastAPI?
13:22 I do, yeah. I did my last job. We built some applications on top of FastAPI, and we also had at Roche open source one, which is kind of nice. I always like the FastAPI experience overall, like the documentation is super nice. I think Sebastian did a great job and also taking the extra mile to explain more general concepts in a FastAPI like introduction to Async IO and these kind of things which the others do not have. They don't need to, but it's just that you can see that they really care about the community and the users of FastAPI to make it very easy to put something into production.
13:58 It definitely stands out in that regard, for sure. So FastAPI is notable. I also think another one worth giving a shout out to is Starlette. Now, Starlette is not as popular, right? Having 7000. Github Stars. Not that this is like a popularity contest, but it gives you a sense of how many people are using it. Right. And so Starlette is its own web framework, but it is also something that can be used for the building blocks of other web frameworks, which I think is unusual for Flask, isn't like, well, take us apart and just use us. Don't actually use Flask, but FastAPI itself actually is built on Starlette. So much of what people love about FastAPI, they actually love it about Starlette. It's just kind of like a pass through.
14:41 Yeah, I think for a lot of things, FastAPI is just a pass through to startlette. And that's what I meant before with a lot of people are, like, comparing blog posts like FastAPI versus Flask or Cord and these kind of things. But it's an unfair comparison because they're like starlette cord. I think they're meant to be extended into something like going from the microframe or to your web application afterwards. And I think you will have their start using FastAPI if you need all these features.
15:13 It depends on the use case, I guess.
15:15 Very cool to learn about that one. Also, Sanic. I hadn't really been tracking Sanic until recently. I had been and then kind of didn't pay too much attention. But this is a pretty popular framework, 16,000 stars, and yeah, it's kind of got its own philosophy. It's a little bit like Starlette, actually, in its style.
15:32 I've never used it. I've seen it around, but I never really looked into it. So what is it that it has a different style? What do you mean?
15:39 Well, so many of the web frameworks it's a great question. So many of the web frameworks these days are like, we're a brand new web framework. We look just like Flask, except we're just like Flask, but we're API oriented, and we come with auto documentation. We're just like Flask, but we do this other, slightly different thing.
15:58 They're all like, you create an app and then you say app get or app route on your and you kind of build up out of a blueprint or API router style of separate.
16:10 There's so many of these new web frameworks that are highly inspired by Flask but they don't carry over the same runtime. They carry over kind of the shell API concepts. Right. And Sanic is not so much like that. So if you go and check out Sanic, they have, like, a good getting started. Let's see if I can pull up an example. There's a huge button that says Get started. Maybe I should click that. So if you look at the way that it works is you just create functions. They're using this app gets I saw some I believe that you just say, here's a function, here's the URL. Go and call it right. Where it's a little more assemble it back together. But yeah, anyway, it's an interesting web framework as well, a little bit different. And I think it's really nice that there's all these people attempting different perspectives on solving the same problem.
17:00 It's cool. And it probably depending on the use case, one suits you better than the other. I mean, it's not that FastAPI just because it has so many stars that it's always the best choice, right. Maybe for your use case want something very realistic or something you can extend in your own ways.
17:15 Yeah, and some of these, like, Sanic just added this ability to have background workers that are managed so you don't have to go all the way to, like, a celery worker type of infrastructure. Just the web framework will manage it. And I believe Starlette also has that. I guess one more thing to give a shout out, too, is the stuff from the Encode folks. There's a lot of those appearing here. So they've got Starlette, they've got httpx and UV Acorn. Right. Once you get one of these frameworks, you got to run it, right?
17:42 Yeah. And probably it's one of the most popular for production, I think. At least we've been super happy words. Great if you use it with UV loop.
17:54 UV loop will make an appearance a little bit later as well. But I've been using UV acorn for production. Also. Loving it. Okay. And I guess also one thing I'll put into the show notes here is remember which framework had this that I pulled it up. It might have been Sanic or Starlette, one of those two. But they created a filter across the Tech power web framework benchmarks that just highlight the Python ones, because there's how many 290 frameworks in this? I don't really care what this obscure Rust, the super lightweight thing does because it's not a full web framework and I will never use it and so on. So it's kind of interesting to compare just the raw basic ones or whatever, but if people doesn't necessarily matter too much, but if you kind of want to get a sense of what performance looks like across all of these, I'll put a link to the tech and power benchmarks. I don't know, what do you think about these things? Does this influence you to see all Sanic is above FastAPI or do you not care?
18:52 It's nice to see those comparisons and kind of see how the theory optimization in these frameworks kind of translate to practice. But in the real world I would say that it doesn't really matter too much because it's probably your business logic which is slowing you down and these kind of things or latency to your database or whatever and not the framework itself. So I would take those with a grain of salt.
19:16 Yeah, it's kind of like asking well, if I have a tight loop and I increment a number, how fast can I do that? Like OK, well sure, C++ is super fast for that, but that's not what real software does. Real software interacts with all these things and that difference you think is so huge is like a little marginal bit over the real work.
19:36 This portion of Talk Python to me is brought to you by Microsoft for Startups Founders Hub, starting a business is hard. By some estimates, over 90% of startups will go out of business in just their first year. With that in mind, Microsoft for Startups set out to understand what startups need to be successful and to create a digital platform to help them overcome those challenges. Microsoft for startups founders hub was born. Founders Hub provides all founders at any stage with free resources to solve their startup challenges. The platform provides technology benefits, access to expert guidance and skilled resources, mentorship and networking connections, and much more. Unlike others in the industry, Microsoft for Startups Founders Hub doesn't require startups to be investor backed or third party validated to participate. Founders Hub is truly open to all. So what do you get if you join them? You speed up your development with free access to GitHub and Microsoft cloud computing resources and the ability to unlock more credits over time. To help your startup innovate, Founders Hub is partnering with innovative companies like OpenAI, a global leader in AI research and development to provide exclusive benefits and discounts through Microsoft for Startups Founders Hub, becoming a founder is no longer about who you know. You'll have access to their mentorship network, giving you a pool of hundreds of mentors across a range of disciplines and areas like idea validation, fundraising, management and coaching, sales and marketing, as well as specific technical stress points. You'll be able to book a one on one meeting with the mentors, many of whom are former founders themselves. Make your idea a reality today with a critical support you'll get from Founders Hub. To join the program, just visit Talk Python.FM/Foundershub all one Word the links in your show notes thank you to Microsoft for supporting the show.
21:26 Yeah, I would also say that most of the people don't actually need that feed. If you may need it, you may also choose another language or if this really is a thing for you, then I don't know if this microautimizations between Sanic and FastAPI really brings you much better.
21:43 I would certainly say pick the API that makes you happy, programming API and the framework that makes you happy, and just go with that. Yeah, good advice. All right, let's see our way on to the next section. We are message queues.
21:54 Yeah, I haven't been a big user of any of these. I've been using the MGP one a while ago, so I don't really know where it's at these days.
22:02 Message queues are interesting. They're a way to add crazy scalability if you've got a lot of stuff that takes a while, but you don't need the answer right away. They're pretty interesting, but I just haven't had them much myself either. I did not too long ago speak with men Reagan Kelly about Zero MQ and Python. And apparently they're doing a lot of cool stuff for powering Jupyter with Zero MQ. So it's way more interesting than I initially, in my mind, gave it credit for. But, yeah, it's a cool project.
22:34 So they're hosting Jupyter or what they.
22:36 Didn't they're using for something for, like, the client server communication.
22:41 But it's been what I think I remember, but it's been like, quite a long while since I talked to him about it. But, yeah, we've got the Aioamqp AMQP one. That's the one you talk about, right?
22:51 Yes, it's the one you would use if you use RabbitMQ, for example, right? You start using the MQP protocol and then that's where you can use this library in particular, right.
23:00 You have the PYZMQ. That's the zero MQ one I was talking about. And then some others one for, like, Apache Kafka, for example. But again, any time you're talking, these are usually separate processes. Sometimes on separate machines, you're doing network.com. Like, if you have the word I'm talking over a network, then Async and Await, I mean, Async IO, like, what does the IO stand for? Right?
23:24 And the point being also here is that you have Async IO libraries for pretty much all message queues out there these days. I mean, every time I looked and looked for a library, it was so something was out there and you could use.
23:36 All right, let's move on to the next one, which is the database stuff. So I think this is another area where you spend, especially on the web apps, you're spending a lot of time waiting. So thinking about your Asynchronous database driver is super important, right?
23:53 Yeah, absolutely. And I think it's not too long ago when there wasn't really good support for Async IO and databases. It's great to see that a lot of projects are now supporting it. And also you mentioned Django, which has an all the way to the degree I'm not a Django user, so I don't really know. I also guess that's a huge deal.
24:12 Yeah, I mean, that was the main blocker, I believe, is the Django orm didn't have an Async interface and I think it was four one. Again, not doing a ton of Django myself either, but I think Django Four One, which just came out, kind of completed the whole cycle and added that very cool. Yeah. So what database drivers stand out on this list for you?
24:30 Well, I think Asmpa is a very popular one. If you use postgres, I've been using it, and usually you don't really see much about them, actually, because you may use SQLAlchemy on top of these drivers as the end user. You may not have seen them, but you may have used them.
24:47 The only way you might see them is you put the Async connection string in a SQLAlchemy and it complains that it doesn't have this package. Like, Well, I guess I got to install that. Here we go. Right?
24:56 Exactly.
24:58 Yeah. So certainly the Async PG one I think is pretty interesting. This one is from the Edge DB folks, right? From Magic, I believe, the Magic stack, like Yuri and crew over there. So the same people that do UV loop, right. He did a lot of the original Async IO work in Python itself, I believe.
25:18 Yes. I think there's also a nice, interesting talk Python to me episode about with Yuri. I think it was on.
25:25 Yeah, I think I spoke to him about a year ago as well, and that was a great chat. Let's see what else stands out to me here. So, Motor, if you're doing MongoDB, then Motor is often the building block, much like Async PG would be the building block for Sql Alchemy's. Async then Motor is the building block for a lot of the Python MongoDB Async libraries.
25:45 Yes. I also noticed for Reddit, which one is that?
25:48 The redis?
25:49 Yeah, exactly. So I noticed a week ago or something that these IO redis was included in the official Redis Py Library. I don't know when that happened. It may have been a while ago, but I still think it's nice to have not a separate package, but like the same package you have to sync API for. And you can kind of use similar APIs so that you don't have to, like, re sync everything. If you want to switch to a sinking, it just makes it easier to migrate if you want to also move back for some reason.
26:18 I agree. Some of these have both APIs. Like, for example, Sql Alchemy you can create an Async set up connection string engine sequence, or you can do a synchronous one. And depending on what you're doing, you might like, this utility doesn't want to be Async, so we're just going to go and use the Async API. But your web app or API might want the Async version. Let's see a couple more notables here. The piccolo one I think is pretty interesting because I really think the query syntax for this one is quite expressive. Have you played with Piccolo? I have not, but. I still admire its query style.
26:53 I recently checked it out though, and I also had the same impression that the query syntax is super nice because compared to others like prisma I also looked at lately and while they have type safety with like type fix here you actually have the python symbols or variables you can use, which is, I think, a little bit nicer than having strings, even though they can be all the auto-completed.
27:16 Yeah, and when you do refactoring, like it understands what's going on. So just for people listening, for example, to do a select statement, I would say await because it's Async band would be the class. You say band select, then band type name, and then where band popularity greater than 100. A lot of these Orms and ODMs have like janky syntax to push operations into it. So for example, in Mongo engine you would say popularity underscore GT equals 100, so popularity greater than 100. But you're saying equals you don't want equals, you want the greater than symbol. Right. This is like exactly the same meaning in sql as it is in Python, which I just really like that.
28:00 Yeah, and it's also super cool if you're entering a code base and you see these kind of things. Because even if you don't know Piccolo, like, you would understand what's going on.
28:09 Yeah, exactly.
28:10 Which I think is good aspect of a nice API.
28:13 It is. So Brandon on the audience has a question, says so we can use Async PG in place of Psychopg2. I haven't done enough with this, but what are your thoughts?
28:24 I'm not sure if the later one really is Async.
28:27 Yeah, I think the deal is the latter one psychoptwo is not Async. And so that's what says Sql Alchemy would use if you had created a synchronous connection. But if you wanted to do the Async version, then you would have to use the Async PG foundation for it, basically. I think that's my understanding. But I do know MongoDB than postgres.
28:46 I think so too, but I wouldn't really know because I've always lately been using Async only.
28:52 Yeah, exactly.
28:53 It's not the only thing you would have to change, right? You would also have to adapt your code and put the weights here and there and make your code as. You can just replace the query string and then expect it to work.
29:04 So one other one here that I think is probably noteworthy to put in the database drivers, and I'd like to hear your thoughts on this as well. Is the AIO Sql Lite on one hand interesting? Because sequel light doesn't really do much concurrency. So you're like, well that's silly. Why would I ever want to use Aio the Async IO with it if it doesn't really do that? But if you're writing a web API or website or something that uses SQLAlchemy and you want to on Dev, use SQL Lite just for a simple test and you want to use Postgres in production. Well, guess what? Your Async code will fail to run on Sql Alchemy unless you have AIO SQL Lite as the foundation like we just talked about. So it kind of allows you to still test your code and run it, even though you wouldn't necessarily directly use it.
29:49 Yeah, I think we've always been using AOI for testing purposes. Super nice, because you can use, like, in memory databases and don't need to worry about the set up too much and it just works, basically. I need to be careful, though, for a few features.
30:03 Yeah.
30:05 Because it's not exactly a match. Right, exactly.
30:07 But we had the case where it worked in testing and NCI and then broke in production or testing against Postgres.
30:15 All right, let's move on to the networking section. So what stands out? There's not that many other one. This is not overwhelming, like the database thing, right?
30:23 Yeah. I think probably a lot of people know is httpx, which is a super nice request, like, package for making Http calls. It has a similar API. And the good thing or what I really like is that you can use it in sync and Async, and the API looks pretty much the same. So if you want to switch from sync to Async, I think it's the delay to use it.
30:46 You can just say httpx get, just like you can with requests, which is great. And then if you want the Async version, do they have an Async example? It's super easy to click. I think you just create, like, an Async client and then call the same functions on it. Yes, much like request, where you create like, a client, you just say or a client session, I guess it's called. You say create an async client, then you await the client get. It's always interesting to me how libraries decide to add on Async and rephrase that a synchronous and a nonsynchronous version. They both variants into the same library. Right. Do you see people doing that successfully? Do you see any patterns that you really like when they do that?
31:28 I think actually like how httpx is implemented in regards. I didn't take much in the code base, but you have the same, like, protocols for the API so that you can reuse them easily interchange. I think the transport layer in this case, yeah, it's super nice, but for my own libraries, it always bothered me to there's no really nice API to provide both in, like, the same function. Like, you couldn't reuse the function name in an Async version or the message name.
31:59 Right.
31:59 You need to have another class.
32:02 But I guess that's just how it is.
32:04 I think a lot of these probably grow up, they come into existence to be one or the other, and then they're like, all right, well, we'll kind of both how do we add it? And if personally if I was going to start from the very beginning, I would like to see what they're doing. Just for the synchronous version of httpx, where you just say httpx get instead of saying import httpx, you'd have to say from, like, httpxynchronous import httpx or from httpxasync import httpx and then it's just exactly the same API, but you have to await everything versus not await. I don't know. I think if you said we'll control it at the import level, and then what you get is either all waitable or it's all blocking.
32:47 It will be much better.
32:48 Yeah.
32:48 By the way, could you update this yet? Not true. Or is there like, you always need a client that you want to have async support.
32:56 I'm pretty sure for httpx, you have to create the client, and then you have to create an Async client. Then you can await it. I've also seen other APIs. You have Get, and you have, like, a Get underscore Async, but I kind of don't like that since you could just do one import statement and fix it. So I don't know. I'm going through all these examples that you've curated. I'm thinking, like, okay, some of these have both APIs. Like, how are they making that clear to people? Right? What else is noteworthy on that list? I think maybe we could just super quick touch on it. You've got an Async SSH library, like, literally, that's his name, and a DNS and a ping, right? I haven't either.
33:33 It's nice to have, like, here at least to have some well, if you want to do a ping, it may not be obvious what to use. So I think it's a good one, or at least people consider it a good one. So I think it's nice adding those to the list. So there are a few, like, niche libraries on the list which wouldn't make a huge like, they wouldn't get many votes, probably if you do this because.
33:53 They're not broadly useful, you're like, oh, my goodness, I've been building a DNS system. I'm so glad I found AIO DNS, but it's not good. Actually, some of the frameworks, like, I believe Httpx uses that under the covers. Pretty sure something I played with recently was, like, using AIO DNS under the covers to make it to work a little more Asynchronous.
34:13 Yeah, it makes sense.
34:14 Excellent. All right, tell us about the testing story.
34:16 I mean, here, of the ones we see on the screen, there's IO mock, there's Async test, Pytest async I-O-A responses, and AI O responses. And I've been only using Pytest asyncio to be honest. And it basically app gives you, like, a decorator to mark your Async pi test or your tests Async so that they run in an event loop. There is also now a mode you can set in the configuration where you don't need that marker. So if you have a test, like, you would say, async test underscore Sum, underscore Async IO code, and then your normal test code. And you would decorate this function with a Pytest mark async I O decorator. But yeah, okay. I think not necessary. Basically configure it to have it in auto mode, where it basically just detects a coroutine I've scheduled on the event loop. Yes.
35:07 And this is not about trying to say, well, I've got a bunch of Async test functions, so let's try to run them all in parallel, like Xtest or XDist or any of those types of things. It's just I have some function I want to call and test its results. It's Async, so I have to await it. In order to await it, the test function itself must be Async, and then how do I run it right now.
35:28 What I think the other way would be kind of cumbersome to create an event loop every time and then schedule your core routine in there and Pytest Asynch, which does that for you.
35:37 Sure, you could do it, but it would make the code not look normal. It'd be like all these weird things you have to do to like, Async to sync file, and we'll see some frameworks that might even do something in that regard for you. But this is really nice. It just seems like if you're testing code that is Async, clearly this is something like this is what you want. Also mocking. I hadn't really thought about mocking Async methods, but I guess you need some.
36:00 I've done this. I haven't used this. IO mock. So there is, I think, even in unit test Mac, there's an Async mock like class, which you can use. I'm not really sure why you would need this.
36:12 This has changed six years ago. I wonder if the Asynchronous mocking capabilities were not in the framework itself when this got created. And then probably like, you know what, we should just be able to test our own stuff, so let's fix that. Yeah, I'm guessing. OK, pretty nice. You mentioned UV loop before in one of the sections. This is maybe the only section that has a single item in it, but it's a big one, UV loop, right? Yes, for alternate loops.
36:36 Yeah, exactly. So you could use, if you run Async I O, you can just use the one which is in like C python you could just use that. But there is other implementation like this UV loop, which is based on Lit UV, which is another event loop in C. And it just is super fast compared to the built in implementation. I think it's for production use cases.
36:57 It's so nice because in order to use it, a lot of times, if it's just literally installed in the environment, things will use it. Like, I believe you, Vic Horn will use it if it finds it. And some other things you don't even have to say, please use it. Just like, oh, it's available let's go. And if for some reason you need to explicitly use it, like in your code, you just say UV loop, you say Async IO, set event loop policy, and you pass over the UV loop policy class. And now the rest of your program just uses that. It's really nice.
37:25 And don't do not many other alternative implementations.
37:28 Actually, yeah, I don't either, but it's really nice. And it basically bundles up, as you said, libuv. They've got some nice performance graphs. It says, UV loop makes Asynch IO two to four times faster. Who wouldn't want your Asyncho code to just go two to four times faster with no effort?
37:43 It's super easy to install and use, so there's no real downside to that.
37:48 Mario has a totally reasonable question. Why wouldn't UV loop be the standard Async IO plantation? Then what's the catch?
37:55 Well, I don't know what the catch is, but I could assume that it's easier to change outside of the CPython development cycle. And probably that's one of the reasons. I don't know.
38:07 That's a good idea. Also, do you want Python itself to take on Lib uv as a C dependency? And then, third, when I played with UV loop originally, it's been a few years, it didn't work at all on Windows. Like, its implementation of Lib UV was, for whatever reason, it just wouldn't install on Windows. And that obviously is a breaking change or a stopper. So maybe even if it works on Windows, maybe there's some obscure place where Python runs, but the UV won't think of some small device like a Raspberry Py or whatever. I don't know.
38:43 Yes, and I think we're coming down to the discussion we had before about the benchmarking again, that maybe not everyone actually wants this feed or needs this feed. Yes, maybe just for, like, very optimized production use cases, and you actually need this four times faster. And for all the other use cases, maybe it's your code that is slow anyways. You don't really care too much.
39:03 Yes, there was a discussion about a few years ago about why is requests not just built into Python, right. They're like, well, there's URL of stuff in there, but it's way less obvious how to use it compared to just request get done and response JSON when you get your response back and whatnot. And they debated that at the Core Dev Summit, and they decided, if we put requests into CPython, kind of like you were saying, it will actually slow the progress and the evolution of requests itself. And they wanted to keep this nice library its own thing that could go at its own pace.
39:42 This portion of talk Python to me is brought to you by Sentry. How would you like to remove a little stress from your life? Do you worry that users may be encountering errors, slowdowns, or crashes with your app right now? Would you even know it until they sent you that support email, how much better would it be to have the error or performance details immediately sent to you, including the call stack and values of local variables and the active user recorded in the report with this is not only possible, it's simple. In fact, we use synthy on all the Talk Python web properties. We've actually fixed a bug triggered by a user and had the upgrade ready to roll out as we got the support email. And that was a great email to write back. Hey, we already saw your error and have already rolled out the fix. Imagine their surprise, surprise and delight your users. Create your Sentry account at Talk python.FM/sentry and if you sign up with the code Talk Python all one word. It's good for two free months of Sentries business plan, which will give you up to 20 times as many monthly events as well as other features. Create better software, delight your users and support the podcast. Visit Talk Python FM/sentry and use the coupon code. Talk Python.
40:58 Yeah, makes sense. I think there I also heard that the security there, it's easier to patch the library on Python and make people want to update than shipping a hotfix release or whatever Python to fix those security issues.
41:12 Absolutely. And Brandon just says, I just learned that FastAPI startlette use UV loop by default. Yes, it's one of those things I was thinking of. If it's installed in the virtual environment and has access to it, it will just take it and go. No need to make any changes there. Alright, awesome. So that's just one the one thing in the alternate loop section, but quite neat indeed. And then there's got to be a miscellaneous right. There's got to be a utils, there's got to be a helpers. There's got to be something that's just like, well, what the heck is this? Tell us about the grab bag at the end here.
41:43 Yeah, there's a few here which I find very interesting. The first one here is IO chan, which adds a CSP style concurrency features. So if you've done some go programming, you came across channels. I would say this AIO Chan brings these kind of patterns into Async IO. So basically what you will have is you can create a channel and then you can have multiple coroutines, like a producer and the consumer listening and writing to this channel, and you can have it buffered or not. And these kind of things can select on multiple channels and react on incoming data, these kind of things. So it's just an other way to communicate between your coaches than what you would probably do with the built in mechanisms.
42:26 Sure. And a lot of those patterns are incredibly hard to get just right with the event signaling and all those things. And so if you can just hook it in, then it's good to go.
42:36 You could probably make this work with queues and events and all these, but it's nice to have the abstraction of these primitives.
42:45 Yeah, it's a sort of equivalent to saying, well, you've got Http server built into Python itself, like why do you need flask?
42:53 No, we don't want to do this. Other notable ones here, like one that stood out to me, is AIO cache, which is pretty straightforward, like it's just a cache, right. Add, get set even has a cool increment and so on. But it's async I o and it talks to Redis, memcache, Redis and mem Cache message pack. A bunch of different capabilities it has, right?
43:13 Yeah, it looks super cool. I haven't used it, but yeah, it's nice that you can just switch out the back ends and do something else. Also, the API looks very straightforward, like.
43:22 Just set, yet it's pretty straightforward to await a cache. set. It seems like a really nice API.
43:33 Decorators will look interesting so that you can catch up our coroutines, probably.
43:39 Yeah, exactly.
43:41 I didn't really catch that before, you're right. So people are probably familiar with the Funk Tools LRU cache. LTS cache. The LRU cache. Yes. I'm like it's not a T LRU cache. Thank you. But this is that idea. But instead of saying well, where you cache, that is in memory, as you just say cache equals redis, which is like, wait a minute, okay, that's cool, that's really cool.
44:01 It's cool. Just make sure the latency is lower than actually your execution time.
44:07 It looks very nice.
44:09 It's a really good point if you call this a bunch of times and the redis as far away, like it actually might just be slower, but the CPU will be nice and low, so you'll be fine. Yes, this is a cool project. Another one that I really like I think adds some important capabilities is AI files. Tell us about that one.
44:27 Yeah, basically provides you file API support like you have with normal open this kind of functions and do it async with Asyn IO. But I'm not sure if I read it here, but I think on some platforms like Linux, it's hard to actually implement this correctly with like a pole and stuff. I don't know if you know more about this, but I heard it's not a big benefit actually to run async.
44:53 Yeah, I don't know either. What it claims here is I don't think it tries to do fancy work with truly hooking into Asynchronous stuff in the file. It just says it's going to run it on a background thread, basically.
45:04 Oh, yeah.
45:05 So it probably creates like a worker thread and whenever you ask to read it just in the back it goes open and then when you say await read it just on that thread, maybe sets an event and then does a read or something, a little bit of a juggling background threads.
45:21 In a sense, it may make it actually tiny bit slower. But if you're doing an API and the API's got to read or write a big file, that could be a problem. The other one is we'll see this in a couple of things we're discussing in this section file. Sometimes it might be Users, whatever, but it could be backslash networkservernetworkdrive. Right. It could be very, very slow where all of a sudden, unlocking that access is a huge deal.
45:52 Yeah.
45:52 Does this actually support us talking network files?
45:55 Oh, yeah. It mounted the trafficv.
45:57 Okay. Yeah, exactly.
45:59 The thing you're talking to might actually be far away.
46:02 Exactly.
46:03 It does say handling local disk files, but I bet if you mapped it in your OS, it wouldn't know.
46:09 Yeah, it probably would work. What I also like here, there is also an Iopath package, which that one.
46:17 Actually looks maybe even cooler. Right?
46:20 Yeah. Because I think a lot of people are using Path Lit these days. And I Oath basically gives you an Async Path type which you can just wrap around your strings or paths objects and you get the same methods. You can obtain them, basically. So you can have your path open, path exist, and you have each using a rate. It does it for you. I don't know. Here how it's implemented. If it's also using background threads or if it doesn't match it.
46:48 Does it actually hook into the true IO completion ports and all that kind of business? Yeah.
46:53 Yeah.
46:53 So this is really cool. So you could create we all know about Path from Path Lib. It's super neat. And you can ask it questions like, does it exist? Or, you know, create this directory or is it a directory? Or you can actually say read bytes, write bites, read text. There's a lot of things that you would do with the Context Manager that becomes one liners with Path lib. And this Async Path lets you make all those Asynchronously like, await path that exists await, right. Bytes and so on.
47:20 And the cool thing is they really, I think, try to be a drop in replacement for pathlib in the Async I O world. So if you've been having a code base or have been using Pathlib in an Asynch cobase, it's super easy to just switch to an Async version of Pathlib.
47:35 Excellent. It says the implementation here. Let's see. Does it tell us it inherits from pure path, which is cool. So you could use it as an argument to some of these some of the pieces that will take path objects directly. It takes advantage of Lib AIO for Async IO on Linux, which is probably where you care most about performance because that's where your server is, right?
47:56 Yeah.
47:56 I don't know anything about Lib AIO, but that's probably some sort of native type thing going on there. Like Linux native asynchronous I o access library. Yeah, that's okay. So maybe this is not just a little bit better. Yeah, maybe it's not just a little bit better than AIO files because, well, you can work with path objects, but it has like an OS level implementation as well. That's pretty cool. All right. I'm using it. I'm using it.
48:18 It looks good.
48:19 Those are all the ones that jumped out at me. Those two that you called out there. The cache in the files and the path history, I guess. Anything else worth mentioning real quick.
48:28 Thanks. So, I mean, the Misc one is just a miscellaneous package. In the miscellaneous packages, I would say.
48:37 Maybe someday it's like the meta miscellaneous squared or something like that. Then there's a bunch of random helper things in there. That's cool. Then you have some stuff and we just got to quickly flip through it. Like there's some stuff on writing like tutorials and articles and then some video talks about Async IO in there. Right.
48:57 I think they're good ones. I think a lot of them are actually from David Beasley.
49:03 Yeah, David Beasley has done some cool stuff with kind of recreating asyncio live in the early days. And then you're already who we spoke about.
49:11 Yeah. If you really want to know how you can think about a mental model of Asynch IO I think these are very good talks to better understand.
49:20 Absolutely cool. I don't know about this guy though. All right. The last thing you closed it out with is alternative implementations to Async IO. Not just like a tool you can use within Async IO, but there's curio and Trio are like probably the big two there. Right.
49:34 I think Curio I think it's from David Beasley as well, but I don't think it's maintained really. But I think it's been a nice experiment. And at the time I looked at it, it was kind of minimal in the implementation, so you could kind of digest and see how something would be done like Async IO.
49:49 Okay.
49:50 There's Trio, which I think is still out there. And that's also why any I O exists. Probably because you can use any IO as a front end for Trio or as I IO and add some more high level features on top of Async IO.
50:04 Yeah, I recently had Alex from any IO creative neo on there. And just real quick shout out for some of the things I thought was cool over there is it could run on top of Async IO or Trio, which is cool. It also has some really interesting aspects for converting threads into converting regular functions into await of things by running them on other threads. And it can either do that on a thread or it can even do that on a subprocess. So you can go and say a wait run process and then you get it's value back. Right. Or you could do that with sort of multiprocessing or even create a synchronous for loop over the output stream like standard out of some process.
50:47 I could have used this a few times in the past.
50:49 Yes, I know. This is really, really neat to be able to do that. The other thing is the synchronization primitives like events and semaphores.
50:57 He says, I haven't tried it out, really, but they're supposed to be a little bit less likely to get deadlocks or race conditions because they're not reentering, basically.
51:05 Okay, nice.
51:06 Yeah. So there's a bunch of cool little helper type things in any IO there? Well, that's pretty much it, I think, for the list. That was a lot. But a lot of good stuff. A lot of awesome stuff, wouldn't you say?
51:18 Yes, and I'm sure there's more awesome stuff out there. Like the Esco last one we've covered, you added one five minutes before the.
51:26 Talk I was going through. I was like, oh, yeah, this one, I was looking at motor. I'm like, oh, well, the stuff goes on motor. There are some good ones there. Let's throw those in and people can vote for them if they want. But yeah, I'm sure that people listening, if they maintain one of these libraries to their big fans and use one a lot that's not on the list, go make a PR. Right, absolutely.
51:45 Yeah. I also plan to add some more automation so that we can, for example, check for dead links. It would also be nice to kind of catch outdated libraries. Like which one? Like the IO mock we've seen before.
51:56 Yes, exactly. Like, you know, if it hasn't been touched in six years, it probably isn't needed anymore. Right. Could fade.
52:01 Exactly.
52:02 Awesome. I mean, this is a great resource, and I sort of shouted out the popularity. Some of these projects, to give a sense. You list has got 3.7 thousand stars. That's pretty awesome. That's a lot of people who got value from it.
52:13 It is. And I can only recommend to look at these lists, whatever list it is. There are gems in there and it's kind of nice to discover them.
52:21 Yeah, absolutely. Really quick out of the audience logic says Starlet. Sorry? Starlite is an async framework built on top of Starlit and Pydantic, which is a good candidate. I didn't actually give a shout out to it, but I thought, oh, no, it's not on there. Okay, well, PRS are accepted and reviewed. Starlite. There you go.
52:43 Cool.
52:44 All right, Timo, this is really excellent project here. A ton of people are getting value from it, so thanks for putting it together.
52:50 Yeah, thanks to all the people who suggested the awesome stuff. So I'm, as I said, merely the maintainer of the list. So keep them coming and we'll make it even better.
52:59 Excellent. All right, before you get out of here, final two questions. I feel like you could just randomly pick one from your list, but the notable PyPI project you want to give a shout out to, I think it's.
53:08 Not even on there, but it will be. Tenacity.
53:11 Oh yeah, tenacity is good. Yeah.
53:13 The library for retrying stuff, I think it passed Async. I'm pretty sure it passed Async.
53:19 Okay, let's see.
53:20 But it makes it super nice if you have like network you need Asynch retries.
53:24 There you go.
53:24 Yeah. So it's even the same decorated, which is cool from an API perspective. I don't even think you have to import something else, like something differently.
53:31 Right.
53:31 Because you can actually inspect the function which is being decorated and you can decide what you're on. Pretty cool. I suggest you use it if you want to retry something or have like unstable endpoints or whatever and all the features you need to call it.
53:44 This is a great library. If you are consuming someone else's API and that thing is flaky, what are you supposed to do? Right. You've got to call it potentially, but you can't count it always working. I've run into that problem on a lot of my projects as well. And I've either done something like tenacity or you just say retry it with some kind of exponential back off or I'll go through and cache it in my database and say I'm going to try it. If it fails, I'm going to go get it from the database and go. It might be a little bit stale, but at least if it's something kind of stable, like a currency lookup like, okay, an hour ago the dollar to Swiss francs, the lookup was this. And it might not be perfect, but it's better than just going $500.
54:28 I don't know how many while loops I've written in my life to kind of check a timeout and then retry and sleep and these kind of things. It's hard to get this right because you want to catch termination of the program and cancel these things. So it's nice to have a live preferable. Yeah.
54:45 Cool. And the fact that they support Async is like perfectly blends in as well. Yes. Actually it would belong to where it now. All right. And the other question is if you write some Python code, what editor are using these days?
54:58 These days VS Code. It's important though that it has been key bindings. I've been user for quite some time, so I certainly need that. But VS Code was my editor to go these days.
55:09 All right, final call to action. People are interested in your awesome list. What do you tell them?
55:14 Please contribute to your awesome ideas. Make it PR. Also, if you have ideas around automation, please send them our way. Create a pull request and as a.
55:24 Maintainer, that's a very welcome thing, right?
55:26 It is fine.
55:27 Things you don't have to maintain, I'm sure.
55:30 Absolutely.
55:31 Awesome. Alright, well, thanks so much for being here. Thanks everyone to listen.
55:34 Thank you for your time with that.
55:35 Bye bye.
55:37 This has been another episode of Talk Python to me. Thank you to our sponsors. Be sure to check out what they're offering it really helps support the show. Starting a business is hard. Microsoft for Startups Founders Hub provides all founders at any stage with free resources and connections to solve startup challenges. Apply for free today at Talkpython.FM/Foundershub take some stress out of your life. Get notified immediately about errors and performance issues in your web or mobile applications with Sentry. Just visit Talk Python FM/Sentry and get started for free. And be sure to use the promo code Talkpython all one Word. Want you 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 talk python FM.
56:49 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.