I’ve recently had to serve some data via an endpoint that relies on a background task because it takes a while to process. Here’s my solution.
It uses two endpoints - one to launch the task and then redirect to a second endpoint which will display the status of that task and the result once it completes.
@anvil.server.background_task
def long_running_task():
sleep(30)
anvil.server.task_state["result"] = "Hello World"
@anvil.server.http_endpoint("/task")
def launch_task():
task = anvil.server.launch_background_task("long_running_task")
response = anvil.server.HttpResponse(303)
response.headers["location"] = f"{anvil.server.get_api_origin()}/results?task_id={task.get_id()}"
return response
@anvil.server.http_endpoint("/results")
def results(task_id):
task = anvil.server.get_background_task(task_id)
status = task.get_termination_status()
responses = {
None: {"status": 202, "body": "Your dataset is being generated. Wait a few moments and then refresh this page."},
"failed": {"status": 500, "body": "An error occurred whilst generating your dataset. Get Owen to have a look."},
"killed": {"status": 500, "body": "The background task to generate your dataset has been killed. Get Owen to have a look."},
"missing": {"status": 500,"body": "The background task to generate your dataset is AWOL. Get Owen to have a look"},
"completed": {"status": 200, "body": task.get_state().get("result", None)}
}
return anvil.server.HttpResponse(**responses[status])