David Y.
—One of the API endpoints in my FastAPI application executes a data retrieval task that sometimes takes a very long time to complete, making my application feel sluggish. How can I cancel the execution of this task if it takes more than a set amount of time and serve cached data instead?
We can do this using the asyncio.wait_for
function that takes an awaitable and a timeout value in seconds as parameters. The awaitable is then run as a task. If the task is completed before the timeout is reached, wait_for
will return the value the task returns. If the timeout is reached before the task returns, the task will be canceled, and wait_for
will raise a TimeoutError
. In Python versions before 3.11, it raised an asyncio.TimeoutError
instead.
The following example code demonstrates using a simulated data retrieval task that sleeps for 10 seconds before returning a random number and a timeout of 5 seconds. For Python versions below 3.11 replace except TimeoutError
with asyncio.exceptions.TimeoutError
.
from fastapi import FastAPI import asyncio, random app = FastAPI() cache = {"result": random.random()} # seed the cache async def long_running_task(): await asyncio.sleep(10) # sleep for 10 seconds return random.random() # return a random number @app.get("/retrieve-data") async def retrieve_data(): try: result = await asyncio.wait_for(long_running_task(), timeout=5) # timeout after five seconds of waiting cache["result"] = result # cache the result return {"message": result, "cache": False} except TimeoutError: return {"message": cache["result"], "cache": True} # Run FastAPI app if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
A request to this application’s /retrieve-data
endpoint will invoke long_running_task
, cancel it after five seconds, and then return the cached random number. If we swap the task’s sleep time and the timeout value, a request to /retrieve-data
will wait for five seconds before returning a new random number. In both cases, the API indicates whether the value returned was sourced from the cache.
Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.
SEE EPISODESConsidered “not bad” by 4 million developers and more than 100,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.
Here’s a quick look at how Sentry handles your personal information (PII).
×We collect PII about people browsing our website, users of the Sentry service, prospective customers, and people who otherwise interact with us.
What if my PII is included in data sent to Sentry by a Sentry customer (e.g., someone using Sentry to monitor their app)? In this case you have to contact the Sentry customer (e.g., the maker of the app). We do not control the data that is sent to us through the Sentry service for the purposes of application monitoring.
Am I included?We may disclose your PII to the following type of recipients:
You may have the following rights related to your PII:
If you have any questions or concerns about your privacy at Sentry, please email us at compliance@sentry.io.
If you are a California resident, see our Supplemental notice.