I need to return a response from my FastAPI path operation, but before this I want to send a slow request and I don't need to wait for result of that request, just log errors if there are any. Can I do this by means of Python and FastAPI? I would not like to add Celery to the project.
Here is what I have so far, but it runs synchronously:
import asyncio
import requests
async def slow_request(data):
url = 'https://external.service'
response = requests.post(
url=url,
json=data,
headers={'Auth-Header': settings.API_TOKEN}
)
if not response.status_code == 200:
logger.error('response:', response.status_code)
logger.error('data', data)
@router.post('/order/')
async def handle_order(order: Order):
json_data = {
'order': order
}
task = asyncio.create_task(
slow_request(json_data)
)
await task
return {'body': {'message': 'success'}}
OK, if nobody wants to post an answer here are the solutions:
We can just remove await task line as alex_noname suggested. It will work because create_task schedules task and we are no longer awaiting for its completion.
@router.post('/order/')
async def handle_order(order: Order):
json_data = {
'order': order
}
task = asyncio.create_task(
slow_request(json_data)
)
return {'body': {'message': 'success'}}
I ended up with BackgroundTasks as HTF suggested as I'm already using FastAPI anyway, and this solution seems more neat to me.
@router.post('/order/')
async def handle_order(order: Order, background_tasks: BackgroundTasks):
json_data = {
'order': order
}
background_tasks.add_task(slow_request, json_data)
return {'body': {'message': 'success'}}
This even works without async before def slow_request(data):
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With