Login

Register

Login

Register

✆+91-9916812177 | contact@beingdatum.com

Asynchronous Programming in Python : A Brief Overview

Asynchronous Programming in Python

Asynchronous Programming? What’s that!!

We all know what “synchronous” programming means as it is what most of us started writing, and can be thought of as performing one steps at a time followed by another step.

When it comes to program execution, “asynchronous” plays very important role and has become more and more popular lately. So, what does it mean, “asynchronous” means that the program doesn’t wait for a process to complete, but it goes on. There are many different libraries in python for doing asynchronous programming. One of them is asyncio, a python standard library in Python 3.4. However, in latest versions we got async/await syntax.

An example of asynchronous programming could be writing to a log file. Its possible that it might fail due to disk space or any other reason, sometimes it doesn’t and you can write your program to call the log routines asynchronously.

Asynchronous programming means that your main program runs little faster. As per above example to write to a log file, it should be written in such a way that if disk space is full, your code should exit or stop logging rather than crashing.  Let’s see how we can write the code for this using asyncio module. The below example is from the official Python documentation:

One small example to understand why we should use asyncio module in python. Imagine you are writing a book while cooking, even if it seems like you are doing both tasks at the same time, what you are doing is switching between the two tasks, while you wait for the water to boil you are writing your book, but while you are chopping some vegetables you pause your writing. This is called concurrency. The only way to do these two tasks in parallel is having two people, one writing and one cooking, which is what multi-core CPU do. Here comes, async programming which allows you to write concurrent code that runs in a single thread. The first advantage compared to multiple threads is that you decide where the scheduler will switch from one task to another, which means that sharing data between tasks it’s safer and easier. Hence, it has 3 main components: co-routines, event loop and future.

In the below example we have used Co-routines and Tasks. Co-routines are function with an async definition whereas Tasks let you run a co-routine in an event loop which in turn simplifies the managing the execution of several co-routines. Event Loop is the object which execute our asynchronous code and decide how to switch between async functions. After creating an event loop we can add multiple co-routines to it, this co-routines will be running completely when run_until_complete or run_forever is called. A future is an object that works as a placeholder for the output of an asynchronous function and it gives us information about the function state. A future is created when we add a co-routine to an event loop.

import asyncio
import time
async def say_after(delay, what):
       await asyncio.sleep(delay)
	   print(what)

async def main():
      task1 = asyncio.create_task(
	       say_after(1, 'hello'))
	  task2 = asyncio.create_task(
	        say_after(2, 'world'))
		print(f"Started at {time.strftime('%X')}")
#Wait unitl both tasks are completed (should take around 2 seconds.)
      await task1
	  await task2
	  print(f"finished at {time.strftime('%X')}")
	asyncio.run(main())

Output:

started at 18:44:53
hello
world
finished at 18:44:55

The say_after() function has async as prefix hence it is coroutine. Here we could call say_after() function directly like:

Await say_after(1, ‘hello’)

Await say_after(2,’world’)

But this will run coroutines sequentially and takes 3 seconds. In the above example, it runs them concurrently and total time taken is 2 seconds (Refer Output). Note that defining a main() function is not sufficient but it should be async and needs to be run by ayncio.

Real World Example

Now that we know the basics of asynchronous programming in python lets see some more realistic code which will download a list of pages from the internet and print a preview containing the first 3 lines of the page.

import aiohttp
import asyncio
async def print_preview(url):
    # connect to the server
    async with aiohttp.ClientSession() as session:
        # create get request
        async with session.get(url) as response:
            # wait for response
            response = await response.text()

            # print first 3 not empty lines
            count = 0
            lines = list(filter(lambda x: len(x) > 0, response.split('\n')))
            print('-' * 80)
            for line in lines[:3]:
                print(line)
            print()
    def print_all_pages():
        pages = [
            'http://textfiles.com/adventure/221baker.txt',
            'http://textfiles.com/adventure/aod.txt',
            'http://textfiles.com/adventure/earthris.txt',
        ]
        tasks = []
        loop = asyncio.new_event_loop()
        for page in pages:
            tasks.append(loop.create_task(print_preview(page)))
        loop.run_until_complete(asyncio.wait(tasks))
        loop.close()

The above code is pretty easy to understand, we start by creating an asynchronous function which downloads an URL and prints the first 3 not empty lines. Then we create a function which for each page in a list of pages call print_preview, add the coroutine the to loop and store the future inside a list of tasks. Finally, we run the event loop which will run the coroutine we added to it and it will print the preview of all the pages.

Watch this video for deeper understanding:

https://www.youtube.com/watch?v=M-UcUs7IMIM

Conclusion

Synchronous programming is what most often begins the development of applications in which sequential execution of commands is performed whereas an asynchronous programming behaves differently. It’s still running one step at a time, but the difference is that the system moving forward, it’s not waiting for the completion of the current execution step. As a result, its an event-driven programming.

I hope this has helped you see and understand where and how asynchronous programming can be useful.

Leave us a comment for more examples or any questions.

December 26, 2019

0 responses on "Asynchronous Programming in Python : A Brief Overview"

    Leave a Message

    Your email address will not be published. Required fields are marked *

    © BeingDatum. All rights reserved.
    X