Sanic support background task?

Background tasks can be run after the response is returned,this is useful when a specific operation needs to be performed after the request, and the client does not need to wait for the operation to complete before receiving the response.

I know fastapi have background_task.add_task,and this is what i wanted.

Sanic’s app.add_task still will wait the task finished and will give response to client.It is not my wanted way,maybe i miss some on my code.

@app.post("/system/user/report")
@protected()
async def index(req: request.Request):
data = json.loads(req.body.decode())
data[‘time’] = datetime.now()
await AccountInfo.create(**data)
await app.add_task(task(data))
return response.json({
“msg”: “ok”
})

Any guys can help me :grinning:

app.add_task() does not require responding to a client. Please review:

Hi i just want my code can give response to client and do not need wait the task finished.But i find app.add_task() can not match my needs.I am a python beginners :sweat_smile:

Did you review the documentation?

Of course.But i still can not find my solution :joy:.

I’m not sure I can help, because I don’t understand what the problem is. Perhaps you should join the discord, and possibly someone can help you there.

Hi sorry for this.
I just want to get the parameters passed by the post route, and then execute the task in the background. The route does not wait for the task to complete, and returns the response directly.

I understand your ask. I don’t understand what is missing that can help you understand the documentation.

From the documentation I can see that this background task can be executed from before and after the app is running, but I didn’t find where can execute an asynchronous background task in a route.

I really don’t know what you’re not understanding. This works just fine:

import asyncio

from sanic import Sanic
from sanic import response
from sanic.log import logger

app = Sanic(__name__)


async def task_to_run_in_bg(app):
    await asyncio.sleep(2)
    logger.info('Starting background task')
    for item in ['one', 'two', 'three']:
        logger.info(f'Cycle {item}')
        await asyncio.sleep(2)
    logger.info('background task done')


@app.get('/')
async def default(request):
    logger.info("request handled")
    app.add_task(task_to_run_in_bg)
    logger.info("background task added")
    return response.json({'respones': 'hello'})
$ curl localhost:8000/
{"respones":"hello"}
[2022-04-20 08:01:21 -0500] [52270] [WARNING] Sanic is running in PRODUCTION mode. Consider using '--debug' or '--dev' while actively developing your application.
[2022-04-20 08:01:21 -0500] [52270] [INFO] Starting worker [52270]
[2022-04-20 08:01:25 -0500] [52270] [INFO] request handled
[2022-04-20 08:01:25 -0500] [52270] [INFO] background task added
[2022-04-20 08:01:27 -0500] [52270] [INFO] Starting background task
[2022-04-20 08:01:27 -0500] [52270] [INFO] Cycle one
[2022-04-20 08:01:29 -0500] [52270] [INFO] Cycle two
[2022-04-20 08:01:31 -0500] [52270] [INFO] Cycle three
[2022-04-20 08:01:33 -0500] [52270] [INFO] background task done

It works exactly as it is documented, what do you need help understanding?

1 Like

It works.I find my code due to await for app.add_task() and make response to client side need wait the background task finished :sweat_smile:.

1 Like