hello everyone serdar yagilov here for infoworld in this episode of smartpython
i'm going to take a quick tour of trio a third-party library designed to make it
easier to use async in python async lets you weave together multiple concurrent actions
things where you spend a lot of time waiting on something else like a network call instead of
waiting for one thing to finish first and then another and then another async lets you run all
these tasks concurrently and then handle them as they complete now the downside is that async
can be tricky to work with because it requires you to think differently about your programming
trio came about as a way to simplify python's async interfaces for common tasks and it's since
become used in a wide variety of projects that employ async like httpx or starlet
let's start with a simple example and this we run multiple instances of a function side by side
and the function in question spends most of its time waiting for something
this is the case with a lot of async tasks and then when it's finished it prints to the console
so for starters we define an async function for trio the same way that we would for async
and python normally we just use the async keyword one key difference is that normally we would use
async io.sleep to sleep asynchronously as a way to simulate this function waiting for something
to happen but here since we're using trio we use trio's sleep function that's not really much of
a change but it does give you an idea that we are doing things a little differently now
now when we get to the main function of our program we do things very differently than
we would with conventional async and python for starters the way we launch async tasks
works completely differently trio uses an object called a nursery to start tasks
a nursery works as a context manager so it provides us with a handy metaphor for starting
up a bunch of async tasks and for waiting for them to finish before we do something else
within the context manager we start a task using the start soon method and the tasks
that we launch in the nursery will then run to completion inside this context manager block
so everything below this async width block will only run after all of those tasks have
run to completion now to kick everything off we use trio.run down here in the
in the in the top level context of our program to execute our main function and if we want to
pass parameters to that function if we need to we can do that but we're not doing that right
now we're just going to execute main as is so if we run this code you'll notice that each of the
separate wait tasks complete separately and then the program exits once everything has finished
and as you can see from this code that we've shown you this is on the whole it's a lot
cleaner and it's more pythonic as the saying goes than the way async i o tends to work
async i o is designed to provide a lot of granular control over the way tasks run
by default trio by contrast is a little more high level by default but you can dig into its
behaviors if you need to it's just that most of the time we tend to deal with these things at a
higher level and we don't tend to want to generate a lot of boilerplate for these types of actions
trio also makes it a little easier to do some other common things with async
one example would be canceling a task or enforcing a timeout on a task here we have another version
of the same program but each instance of the message function will automatically
quit after three seconds and we do this with a context manager using the trio.moveonafter
object so everything inside this block gets terminated after three seconds have elapsed and
we can also inspect this status variable returned by the context manager to determine if the code in
blue block ran to completion or if it timed out and either way we can take appropriate action
so if we run this code we have a couple of our long waiting processes run to completion
but the rest of them because they take too long automatically get cancelled
so this is a very handy way to ensure given tasks don't run indefinitely
another thing that trio provides us with is mechanisms for communicating between tasks
one common mechanism for this is a one directional channel where you have one
task sending a message into a channel and another task receiving that message from the same channel
so in this example and i've adapted this with some modification from trio's own documentation
i'm setting up two tasks named producer and consumer the producer uses a context manager
for send channel to send messages with random delays between them
now the reason we're using a context manager for this is because when that contacts manager closes
the whole channel is also shot automatically now we could if we wanted to hold the channel
open indefinitely by just omitting the width block but i'm leaving this in here because i
wanted to demonstrate that you can use that as a technique here the consumer on the other hand
uses two contexts one is to open the channel itself so that'll quit when the channel closes
and the other is to handle each of the messages as they come through the channel now when we set up
our tasks we create this channel using trio.open memory channel and that will return two objects
one for each end of the channel we pass those two objects to each function in the nursery
so now when we run this code the messages will be sent between channels each with a random delay
associated and they will be received immediately and once the channel closes the program quits
automatically and everything gets everything gets shut down so again you know if i wanted to i could
have this running indefinitely but i wanted to do it this way to make it clear that we have
mechanisms for automatically closing and cleaning up channels once a certain task is completed
another important thing to know about trio if you use it for project you have to use it
as the metaphor for async for that project you cannot mix and match trio with async i o which
is the default library in python for working with async and this is because of the way trio kind of
commandeers asynchronous operations to work in its own way if you elect to use trio in a project you
need to commit to using it entirely now i've only covered a small stretch of trio's functionality
in this video but this should give you an idea of how trio approaches the subject it takes python's
async metaphors and it wraps them in a higher level interface that's easier to dive into and
get started with and it also provides convenience functions for doing things like sending messages
between tasks or controlling timeouts for tasks i'll probably dive deeper into more of how trio
can work for you in the future especially for things like networking but for now this should
give you a good idea of how it operates so that's it for this video if you liked it please leave
a comment below don't forget to subscribe to the tech talk channel on youtube and for more
smart python and more dev with serdar be sure to follow me on facebook youtube and infoworld.com