How to Get Started with Asynchronous Programming in Python
Async IO is a popular programming design that is supported on Python. Asynchronous development takes a program through a set of unique operations in a sequential manner. Execution flows in such development designs follow a simple step, and proceed to the next one only once the previous object is cleared.
Asynchronous programming can improve lag time, and also result in better task speed. The solutions achieved through asynchronous programming can open doors to innovation in programming, and also lead towards better management and solutions. Developers get to initiate new techniques, and also work on overall improvement in the process.
 In this article, we take a look at asynchronous programming in Python, and help you get started with the right set of codes and solutions. Stay with us for more.
Asynchronous Programming on Python
Python follows a centralized FIFO or first in first out method of data structure. The queuing structure can be complex, but heavily organized and well-managed. The program can be initiated with the code below:
import queue
2
3 def task(name, work_queue):
4 if work_queue.empty():
5 print(f"Task {name} nothing to do")
6 else:
7 while not work_queue.empty():
8 count = work_queue.get()
9 total = 0
10 print(f"Task {name} running")
11 for x in range(count):
12 total += 1
13 print(f"Task {name} total: {total}")
14
15 def main():
16 """
17 This is the main entry point for the program
18 """
19 # Create the queue of work
20 work_queue = queue.Queue()
21
22 # Put some work in the queue
23 for work in [15, 10, 5, 2]:
24 work_queue.put(work)
25
26 # Create some synchronous tasks
27 tasks = [(task, "One", work_queue), (task, "Two", work_queue)]
28
29 # Run the tasks
30 for t, n, q in tasks:
31 t(n, q)
32
33 if __name__ == "__main__":
34 main()
Each of the actions play a specific part. Line 20 is the important one to note here, as this is where the queue is actually connected and created.
Concurrency ExampleÂ
Concurrency is a type of asynchronous coding on Python, which is focused on running multiple loops at one time. An example of concurrency is mentioned below:
import queue
2
3 def task(name, queue):
4 while not queue.empty():
5 count = queue.get()
6 total = 0
7 print(f"Task {name} running")
8 for x in range(count):
9 total += 1
10 yield
11 print(f"Task {name} total: {total}")
12
13 def main():
14 """
15 This is the main entry point for the program
16 """
17 # Create the queue of work
18 work_queue = queue.Queue()
19
20 # Put some work in the queue
21 for work in [15, 10, 5, 2]:
22 work_queue.put(work)
23
24 # Create some tasks
25 tasks = [task("One", work_queue), task("Two", work_queue)]
26
27 # Run the tasks
28 done = False
29 while not done:
30 for t in tasks:
31 try:
32 next(t)
33 except StopIteration:
34 tasks.remove(t)
35 if len(tasks) == 0:
36 done = True
37
38 if __name__ == "__main__":
39 main()
Each line plays an integral role here. Line 36 marks completion of the code, and sets it aside as complete.
Concurrency with Blocking Calls
Besides the simple concurrency, there is another form as well that works with blocking calls:
import time
2 import queue
3 from codetiming import Timer
4
5 def task(name, queue):
6 timer = Timer(text=f"Task {name} elapsed time: {{:.1f}}")
7 while not queue.empty():
8 delay = queue.get()
9 print(f"Task {name} running")
10 timer.start()
11 time.sleep(delay)
12 timer.stop()
13 yield
14
15 def main():
16 """
17 This is the main entry point for the program
18 """
19 # Create the queue of work
20 work_queue = queue.Queue()
21
22 # Put some work in the queue
23 for work in [15, 10, 5, 2]:
24 work_queue.put(work)
25
26 tasks = [task("One", work_queue), task("Two", work_queue)]
27
28 # Run the tasks
29 done = False
30 with Timer(text="\nTotal elapsed time: {:.1f}"):
31 while not done:
32 for t in tasks:
33 try:
34 next(t)
35 except StopIteration:
36 tasks.remove(t)
37 if len(tasks) == 0:
38 done = True
39
40 if __name__ == "__main__":
41 main()
Concurrency with Non-Blocking calls
Asynchronous programming on Python can be used for concurrency with non-blocking calls as well:
import asyncio
2 from codetiming import Timer
3
4 async def task(name, work_queue):
5 timer = Timer(text=f"Task {name} elapsed time: {{:.1f}}")
6 while not work_queue.empty():
7 delay = await work_queue.get()
8 print(f"Task {name} running")
9 timer.start()
10 await asyncio.sleep(delay)
11 timer.stop()
12
13 async def main():
14 """
15 This is the main entry point for the program
16 """
17 # Create the queue of work
18 work_queue = asyncio.Queue()
19
20 # Put some work in the queue
21 for work in [15, 10, 5, 2]:
22 await work_queue.put(work)
23
24 # Run the tasks
25 with Timer(text="\nTotal elapsed time: {:.1f}"):
26 await asyncio.gather(
27 asyncio.create_task(task("One", work_queue)),
28 asyncio.create_task(task("Two", work_queue)),
29 )
30
31 if __name__ == "__main__":
32 asyncio.run(main())
Asynchronous HTTP Calls (Blocking)
There is a different process for HTTP calls that are blocked:
import queue
2 import requests
3 from codetiming import Timer
4
5 def task(name, work_queue):
6 timer = Timer(text=f"Task {name} elapsed time: {{:.1f}}")
7 with requests.Session() as session:
8 while not work_queue.empty():
9 url = work_queue.get()
10 print(f"Task {name} getting URL: {url}")
11 timer.start()
12 session.get(url)
13 timer.stop()
14 yield
15
16 def main():
17 """
18 This is the main entry point for the program
19 """
20 # Create the queue of work
21 work_queue = queue.Queue()
22
23 # Put some work in the queue
24 for url in [
25 "http://google.com",
26 "http://yahoo.com",
27 "http://linkedin.com",
28 "http://apple.com",
29 "http://microsoft.com",
30 "http://facebook.com",
31 "http://twitter.com",
32 ]:
33 work_queue.put(url)
34
35 tasks = [task("One", work_queue), task("Two", work_queue)]
36
37 # Run the tasks
38 done = False
39 with Timer(text="\nTotal elapsed time: {:.1f}"):
40 while not done:
41 for t in tasks:
42 try:
43 next(t)
44 except StopIteration:
45 tasks.remove(t)
46 if len(tasks) == 0:
47 done = True
48
49 if __name__ == "__main__":
50 main()
Non-blocking HTTP Calls
Non-blocking HTTP calls follow the code below:
import asyncio
2 import aiohttp
3 from codetiming import Timer
4
5 async def task(name, work_queue):
6 timer = Timer(text=f"Task {name} elapsed time: {{:.1f}}")
7 async with aiohttp.ClientSession() as session:
8 while not work_queue.empty():
9 url = await work_queue.get()
10 print(f"Task {name} getting URL: {url}")
11 timer.start()
12 async with session.get(url) as response:
13 await response.text()
14 timer.stop()
15
16 async def main():
17 """
18 This is the main entry point for the program
19 """
20 # Create the queue of work
21 work_queue = asyncio.Queue()
22
23 # Put some work in the queue
24 for url in [
25 "http://google.com",
26 "http://yahoo.com",
27 "http://linkedin.com",
28 "http://apple.com",
29 "http://microsoft.com",
30 "http://facebook.com",
31 "http://twitter.com",
32 ]:
33 await work_queue.put(url)
34
35 # Run the tasks
36 with Timer(text="\nTotal elapsed time: {:.1f}"):
37 await asyncio.gather(
38 asyncio.create_task(task("One", work_queue)),
39 asyncio.create_task(task("Two", work_queue)),
40 )
41
42 if __name__ == "__main__":
43 asyncio.run(main())
By following our basic guide, you are now caught up with how async programming on Python functions. This article helps give the coding tools and knowledge needed for developers to follow asynchronous programming techniques and implement solutions.
How can we help you?
We have hundreds of highly-qualified, experienced experts working in 70+ technologies.