Phase 3: How the Internet & APIs Actually Work · ~35 minutes · Python · asyncio
async/await in Practice
Forget await and Python doesn't crash. It hands you a coroutine object instead of your actual result — a real value, just entirely the wrong one.
Hiring signal: Recognizes a coroutine object where a real value was expected as a missing-await bug, instantly
What you will learn
- Use async def and await correctly to convert a synchronous script
- Explain the event loop as a single-threaded scheduler juggling waiting tasks, not parallelism
- Diagnose a real, reproduced missing-await bug
- Predict what a snippet missing an await actually returns
Introduction
Type: Learn Languages: Python, asyncio Prerequisites: Lesson 03 (Why Blocking I/O Is a Problem) Time: ~35 minutes
Objective
Learning objectives
- Use
async def and await correctly to convert a synchronous script - Explain the event loop as a single-threaded scheduler juggling waiting tasks, not parallelism
- Diagnose a real, reproduced missing-
await bug - Predict what a snippet missing an
await actually returns
What you're building
Take a synchronous script you wrote for Lesson 03's lab (or write a fresh one with 3+ independent simulated API calls):
- Convert every relevant function to
async def/await, and combine the independent calls with asyncio.gather() - Verify the converted version produces identical results to the original synchronous version
- Measure and print both versions' real elapsed time, confirming the speedup still holds after the conversion
- Deliberately reproduce this lesson's missing-
await bug in a separate, clearly-commented example: show the RuntimeWarning, the wrong type(), and then the corrected version with await restored
async def get_price(item):
await asyncio.sleep(0.1)
return 19.99
async def main():
price = get_price("widget")
print(f"Price: ${price}")
What does this actually print?
price is a coroutine object — get_price was never awaited, so it never actually ran and never produced 19.99. f-strings, like print(), work on any object by calling its default string representation, so f"Price: ${price}" doesn't crash — it silently produces something like "Price: <coroutine object get_price at 0x...>", visibly wrong to a human reading the output but not an error Python itself catches. This is precisely this lesson's most dangerous case: no crash, no warning a busy log would surface clearly, just an obviously-broken-looking but non-fatal result.
Unlock the full lesson
You've read the first 2 sections. The rest of this lesson covers The Problem, Check Yourself, Key Terms & Next — plus a hands-on lab, quiz, and project artifact.
Create a free account to unlock Phase 0 and Phase 1 of every course — no credit card.
Browse all courses · View pricing · DeVenture Academy