Python Asyncio

Introduction

asyncio enables concurrent code using async/await. It's perfect for network apps, bots, API calls, file operations, task scheduling, and anything where you wait for external events. It is NOT multithreading β€” it’s cooperative concurrency.

1. Basic async / await

import asyncio

async def hello():
    print("Hello...")
    await asyncio.sleep(1)
    print("World!")

asyncio.run(hello())
    

2. Running Multiple Tasks Concurrently

Runs functions at the same time (non-blocking).

async def task(name):
    await asyncio.sleep(1)
    print(name, "done")

async def main():
    await asyncio.gather(
        task("A"),
        task("B"),
        task("C"),
    )

asyncio.run(main())
    

3. Creating Tasks Manually

async def worker():
    await asyncio.sleep(2)
    print("Finished")

async def main():
    t = asyncio.create_task(worker())
    print("Task started")
    await t

asyncio.run(main())
    

4. async with (Context Managers)

import aiofiles  # async file library

async def main():
    async with aiofiles.open("test.txt", "w") as f:
        await f.write("Hello async!")

asyncio.run(main())
    

5. async for (Async Iteration)

async def countdown():
    for i in range(3, 0, -1):
        print(i)
        await asyncio.sleep(1)

asyncio.run(countdown())
    

6. Timeouts

async def slow():
    await asyncio.sleep(10)

asyncio.run(asyncio.wait_for(slow(), timeout=2))
    

Throws TimeoutError.

7. Semaphores (Limit Concurrent Tasks)

Useful for APIs or rate limits.

sem = asyncio.Semaphore(3)

async def worker(id):
    async with sem:
        print("Worker", id)
        await asyncio.sleep(1)
    

8. Queues (Producer / Consumer)

queue = asyncio.Queue()

async def producer():
    for i in range(5):
        await queue.put(i)

async def consumer():
    while True:
        item = await queue.get()
        print("Got:", item)
        queue.task_done()

async def main():
    c = asyncio.create_task(consumer())
    await producer()
    await queue.join()
    c.cancel()

asyncio.run(main())
    

9. Real Use Case: Telegram/Discord Bots

async def fetch_user(id):
    await asyncio.sleep(1)
    return f"User {id}"

async def main():
    users = await asyncio.gather(
        fetch_user(1),
        fetch_user(2),
        fetch_user(3)
    )
    print(users)

asyncio.run(main())
    

10. Async Subprocess

async def run_cmd():
    proc = await asyncio.create_subprocess_shell(
        "ping 127.0.0.1 -n 2",
        stdout=asyncio.subprocess.PIPE,
    )
    out, _ = await proc.communicate()
    print(out.decode())

asyncio.run(run_cmd())
    

11. Event Loop Control

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
    

12. Async Rate Limiting

async def limited_task(i):
    await asyncio.sleep(0.5)
    print("Done", i)

async def main():
    for i in range(10):
        await asyncio.sleep(0.2)
        asyncio.create_task(limited_task(i))

asyncio.run(main())
    

13. CPU-bound Work = Use Threads or Processes

Asyncio does NOT speed up heavy CPU tasks.

from concurrent.futures import ThreadPoolExecutor

def heavy():
    return sum(range(10_000_000))

async def main():
    loop = asyncio.get_running_loop()
    result = await loop.run_in_executor(None, heavy)
    print(result)

asyncio.run(main())
    

15. Full Summary