liveBook · Manning

Coroutine

As explained in Python Concurrency with asyncio

A coroutine function is a Python function whose invocation produces a coroutine that can suspend and resume during asynchronous execution.

A coroutine function is defined with async def. Calling it does not execute its body immediately; it produces a coroutine object that can be run by an event loop. The coroutine can suspend at await while a long-running operation completes, allowing other work to run, then resume from the suspension point. section 2.1 section 2.1.1

Keep these distinctions in mind when writing asyncio code:

  • Use async def to mark a function as a coroutine function; use await inside it to suspend while awaiting another coroutine or long-running operation. section 2.1
  • Run one coroutine with asyncio.run, or wrap several coroutines in tasks so the event loop can schedule them concurrently. section 2.1.1 section 2.3.2
  • Concurrency occurs while coroutines wait for non-blocking I/O; CPU-bound work or blocking I/O can prevent the single-threaded event loop from running other coroutines. section 1.5.2 section 2.7
  • Use a coroutine directly when one flow is enough; create a task when independent operations, such as client connections, must proceed concurrently. section 3.5.2

Running a coroutine

import asyncio async def add_one(number: int) -> int: return number + 1 result = asyncio.run(add_one(1)) print(result) # 2 Calling add_one(1) creates a coroutine object; asyncio.run schedules and executes it. For concurrent operations, create tasks and await them later. section 2.1.1 section 2.3.2

Coroutine-based echo server

An asyncio echo server can use one coroutine to accept connections and create one task per client. The client coroutine awaits socket reads and writes, so waiting for one client does not block others. section 3.5.2

Listing 2.2 Comparing coroutines to normal functions
async def coroutine_add_one(number: int) -> int:
    return number + 1
 
 
def add_one(number: int) -> int:
    return number + 1
 
 
function_result = add_one(1)
coroutine_result = coroutine_add_one(1)
 
print(f'Function result is {function_result} and the type is {type(function_result)}')
print(f'Coroutine result is {coroutine_result} and the type is {type(coroutine_result)}')

Compare a normal function’s immediate result with a coroutine function’s deferred coroutine object. section 2.1.1

How Python Concurrency with asyncio covers it

How deep it goes
Defines async def, await, coroutine objects, suspension, resumption, tasks, and event-loop scheduling, but defers custom awaitable implementation details.
Examples
Demonstrates coroutine arithmetic, concurrent delays, an asyncio echo server, generator-based coroutines, and a mixed synchronous-asynchronous task runner.
What it assumes
Assumes basic Python functions and introduces asynchronous execution, event-loop scheduling, suspension, and concurrency from foundational examples.
What you can do after
Build asynchronous applications with async def, await, asyncio.run, tasks, non-blocking sockets, and concurrency-aware API handling.
How it connects
Connects coroutines to async/await syntax, event loops, tasks, futures, awaitables, non-blocking I/O, and the GIL.

Also explained in

Compare how 8 books explain coroutine →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Python Concurrency with asyncio. The section links point to the parts of the book it draws on.