What it is
Asyncio is Python's standard library for writing concurrent code using the async/await syntax. It provides an event loop, coroutines, tasks, and futures to facilitate asynchronous programming and I/O-bound operations.
Asyncio allows you to define coroutines with `async def`, schedule them for execution, and manage asynchronous tasks. It is ideal for network operations, file I/O, concurrency, and writing scalable applications.
Installation
Included in Python standard library (Python 3.4+)Getting started
The smallest useful thing you can do with it, and what each part means.
import asyncio
async def say_hello():
print('Hello')
await asyncio.sleep(1)
print('World')
asyncio.run(say_hello())import asyncio
async def task(name, delay):
await asyncio.sleep(delay)
print(f'Task {name} completed')
async def main():
await asyncio.gather(task('A', 2), task('B', 1))
asyncio.run(main())Advanced usage
Where the library earns its place over a simpler alternative.
import asyncio
async def my_task():
await asyncio.sleep(1)
print('Task done')
task = asyncio.create_task(my_task())
asyncio.run(task)import asyncio
class AsyncResource:
async def __aenter__(self):
print('Enter')
return self
async def __aexit__(self, exc_type, exc, tb):
print('Exit')
async def main():
async with AsyncResource():
print('Inside context')
asyncio.run(main())import asyncio
async def tcp_echo_client(message):
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
writer.write(message.encode())
await writer.drain()
data = await reader.read(100)
print(f'Received: {data.decode()}')
writer.close()
await writer.wait_closed()
asyncio.run(tcp_echo_client('Hello'))import asyncio
async def periodic():
while True:
print('Tick')
await asyncio.sleep(1)
asyncio.run(periodic())Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- RuntimeError: Event loop is closed
- Ensure you are not calling `asyncio.run()` from within an already running event loop.
- CancelledError
- Occurs when a task is cancelled. Handle with try/except around awaited tasks.
- TimeoutError
- Use `asyncio.wait_for()` or `asyncio.timeout()` to limit the duration of coroutines safely.
Best practices
- Prefer `asyncio.run()` for top-level entry points in Python 3.7+.
- Use `async/await` syntax instead of `@asyncio.coroutine` for readability.
- Leverage `asyncio.gather()` for running multiple coroutines concurrently.
- Use Tasks for background execution and long-running operations.
- Avoid blocking calls in async functions; use non-blocking I/O libraries.
Background
Why it exists, and what it was reacting to.
Asyncio was introduced in Python 3.4 (2014) to provide a built-in framework for asynchronous programming, inspired by frameworks like Twisted and Tornado. It enables efficient handling of I/O-bound tasks, networking, and high-performance applications without using traditional threading or multiprocessing.
