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
async/awaitenables concurrencygather()runs tasks in parallelcreate_task()schedules background tasks- Queues, semaphores, timeouts β real-world control
- Use executors for CPU-heavy operations
- Asyncio is perfect for bots, APIs, network apps, scraping, file ops