import asyncio # To make it easier to read the output after the fact, we add # timestamps to all messages, using the monotonic clock from the # ‹time› module: def stamp(): from time import monotonic stamp.start = getattr( stamp, 'start', monotonic() ) msec = int( 1000 * ( monotonic() - stamp.start ) ) return '[' + format( msec, '5' ) + ']' # First, we obtain an instance of the event loop. Since no loop is # running yet, ‹get_event_loop› will create a new one for us. loop = asyncio.get_event_loop() # An example function that we are going to pass into ‹call_soon› to # run it on the event loop. All it does is schedule itself again one # second later, until the counter drops to zero, at which point it # stops the event loop. def foo_func( counter ): print( stamp(), 'function foo', counter ) if counter: loop.call_later( 1, foo_func, counter - 1 ) else: loop.stop() # The following code will run 3 iterations, sleeping 1 second # between each. The ‹run_forever()› method simply enters the # scheduler and does not return until we call ‹loop.stop()›. loop.call_soon( foo_func, 3 ) loop.run_forever() print( stamp(), 'loop with foo_func done' ) # Of course, we would much prefer to use actual coroutines. That # will give us ‹await› so we can use all the ‹asyncio› goodies. # Notice that ‹asyncio.sleep› does not need the ‹loop› specified # explicitly: it'll ‹yield› into it instead (recall that only one # event loop can be active at any given time). Again, we explicity # terminate the loop when we are done. async def foo_async(): for i in range( 3 ): print( stamp(), 'async foo iteration', i ) await asyncio.sleep( 1 ) print( stamp(), 'end async foo' ) loop.stop() # Again, we start the event loop / scheduler explicitly by calling # ‹run_forever()›. loop.create_task( foo_async() ) loop.run_forever() print( stamp(), 'loop with foo_async done' ) # Another example with ‹create_task›, but this time we will use it # within a coroutine scheduled by the event loop. Notice that they # task run (seemingly) in parallel, because whenever one is # sleeping, another can execute. async def multi_async( counter ): if not counter: await asyncio.sleep( 5 ) loop.stop() return loop.create_task( multi_async( counter - 1 ) ) for i in range( 4 ): await asyncio.sleep( 0.5 * counter ) print( stamp(), 'multi_async(', counter, ') iteration', i ) print( stamp(), 'end multi_async(', counter, ')' ) # Notice that not all iterations of all tasks get to run, because # the loop is stopped after 5 seconds by the task that is created # last. loop.create_task( multi_async( 4 ) ) loop.run_forever() print( stamp(), 'everything done' )