📖 Scenario: You are building a simple FastAPI web service that runs multiple tasks at the same time to save waiting time. This is like asking several friends to do small jobs for you all at once instead of one by one.
🎯 Goal: Create a FastAPI app that runs two tasks concurrently and returns their results together.
📋 What You'll Learn
Create a FastAPI app instance named app
Define two async functions named task_one and task_two that simulate work with asyncio.sleep
Use asyncio.gather to run task_one and task_two concurrently inside a GET endpoint /run-tasks
Return a JSON response with results from both tasks
💡 Why This Matters
🌍 Real World
Running multiple independent tasks at the same time improves speed and responsiveness in web services, like fetching data from different sources simultaneously.
💼 Career
Understanding concurrency in FastAPI is important for backend developers to build efficient APIs that handle multiple operations without delay.
Progress0 / 4 steps
1
Create FastAPI app and async tasks
Import FastAPI and asyncio. Create a FastAPI app instance called app. Define two async functions named task_one and task_two. Each should use await asyncio.sleep(1) and then return the strings 'Task One Complete' and 'Task Two Complete' respectively.
FastAPI
Hint
Remember to import FastAPI and asyncio. Use async def to define asynchronous functions.
2
Add endpoint to run tasks concurrently
Create a GET endpoint /run-tasks using @app.get. Define an async function run_tasks for this endpoint. Inside it, use asyncio.gather to run task_one() and task_two() concurrently and store the results in a variable called results.
FastAPI
Hint
Use @app.get('/run-tasks') to create the endpoint. Use asyncio.gather to run both tasks at the same time.
3
Return results as JSON with keys
Modify the run_tasks function to return a dictionary with keys 'task_one' and 'task_two' mapping to the respective results from results list.
FastAPI
Hint
Return a dictionary with keys task_one and task_two using the results list.
4
Add docstring and run instructions
Add a docstring to the run_tasks function that says "Run two tasks concurrently and return their results.". Also add a comment at the bottom with the text # Run with: uvicorn filename:app --reload replacing filename with your script name.
FastAPI
Hint
Add a clear docstring inside the run_tasks function. Add a comment at the end with the uvicorn run command.
Practice
(1/5)
1. What is the main benefit of using asyncio.create_task() in FastAPI?
easy
A. It stops all tasks from running until manually restarted.
B. It makes the code run slower by adding delays.
C. It converts synchronous code into synchronous code.
D. It allows running multiple tasks at the same time without waiting for each to finish.
Solution
Step 1: Understand asyncio.create_task() purpose
This function schedules a coroutine to run concurrently as a separate task without blocking the main program.
Step 2: Identify the benefit in FastAPI context
Using it lets FastAPI handle multiple operations at once, improving responsiveness and efficiency.
Final Answer:
It allows running multiple tasks at the same time without waiting for each to finish. -> Option D
Quick Check:
Concurrent task execution = run tasks simultaneously [OK]
Hint: Remember: create_task starts tasks without waiting [OK]
Common Mistakes:
Thinking create_task slows code down
Confusing async with sync code
Believing tasks stop until restarted
2. Which of the following is the correct way to run two async functions concurrently and wait for both to finish in FastAPI?
easy
A. func1(); func2()
B. await asyncio.create_task(func1()); await asyncio.create_task(func2())
C. await asyncio.gather(func1(), func2())
D. asyncio.run(func1(), func2())
Solution
Step 1: Understand how to run and wait for multiple async tasks
asyncio.gather() runs multiple coroutines concurrently and waits for all to complete.
Step 2: Check each option's correctness
await asyncio.gather(func1(), func2()) correctly uses await asyncio.gather(func1(), func2()). await asyncio.create_task(func1()); await asyncio.create_task(func2()) starts tasks but awaits them separately, not concurrently. func1(); func2() runs functions synchronously. asyncio.run(func1(), func2()) is invalid syntax.
Final Answer:
await asyncio.gather(func1(), func2()) -> Option C
Quick Check:
Use gather to run and wait multiple tasks [OK]
Hint: Use gather to wait all tasks together [OK]
Common Mistakes:
Awaiting tasks separately losing concurrency
Calling async functions without await
Using asyncio.run inside async code
3. Given this FastAPI async endpoint code, what will be the output?
A. Calling task1.result() before task completion causes an error.
B. Using create_task is not allowed in FastAPI endpoints.
C. The tasks should not be async functions.
D. The endpoint should not be async.
Solution
Step 1: Identify how task results are accessed
Calling task1.result() immediately after creating the task tries to get the result before the task finishes, causing an error.
Step 2: Understand correct way to wait for task completion
You must await the task or use await asyncio.gather(task1, task2) before accessing results.
Final Answer:
Calling task1.result() before task completion causes an error. -> Option A
Quick Check:
Access task result only after await [OK]
Hint: Always await tasks before accessing results [OK]
Common Mistakes:
Accessing .result() too early
Thinking create_task is forbidden
Making endpoint synchronous
5. You want to run three independent async tasks in a FastAPI endpoint and return their results as soon as all finish. Which approach correctly handles errors in any task without stopping others and returns all results or error messages?
hard
A. Use asyncio.create_task() for each task but do not await them before returning.
B. Use asyncio.gather(task1(), task2(), task3(), return_exceptions=True) and process results for exceptions.
C. Use await task1(); await task2(); await task3() sequentially and catch exceptions globally.
D. Run tasks synchronously in a loop and catch exceptions inside each.
Solution
Step 1: Understand error handling in concurrent tasks
Using asyncio.gather() with return_exceptions=True lets all tasks run concurrently and collects exceptions as results without stopping others.
Step 2: Compare options for correct concurrency and error handling
Use asyncio.gather(task1(), task2(), task3(), return_exceptions=True) and process results for exceptions. correctly runs all tasks concurrently and handles errors individually. Use await task1(); await task2(); await task3() sequentially and catch exceptions globally. runs tasks sequentially, losing concurrency. Use asyncio.create_task() for each task but do not await them before returning. does not await tasks, so results are unavailable. Run tasks synchronously in a loop and catch exceptions inside each. runs synchronously, blocking concurrency.
Final Answer:
Use asyncio.gather(task1(), task2(), task3(), return_exceptions=True) and process results for exceptions. -> Option B
Quick Check:
Gather with return_exceptions handles errors concurrently [OK]
Hint: Use gather with return_exceptions=True for safe concurrency [OK]
Common Mistakes:
Awaiting tasks sequentially losing concurrency
Not awaiting tasks before returning
Ignoring exceptions stopping all tasks
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.