Можете ли вы использовать асинхронный обработчик в Lambda Python 3.6?Python

Программы на Python
Anonymous
Можете ли вы использовать асинхронный обработчик в Lambda Python 3.6?

Сообщение Anonymous »

Раньше я создавал функции Lambda, но не на Python. Я знаю, что в Javascript Lambda поддерживает асинхронную функцию-обработчик, но если попробовать ее в Python, я получаю сообщение об ошибке.
Вот код, который я пытаюсь протестировать:

Код: Выделить всё

async def handler(event, context):
print(str(event))
return {
'message' : 'OK'
}
И вот какую ошибку я получаю:

Код: Выделить всё

An error occurred during JSON serialization of response:  is not JSON serializable
Traceback (most recent call last):
File "/var/lang/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/var/lang/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/var/lang/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/var/runtime/awslambda/bootstrap.py", line 149, in decimal_serializer
raise TypeError(repr(o) + " is not JSON serializable")
TypeError:  is not JSON serializable

/var/runtime/awslambda/bootstrap.py:312: RuntimeWarning: coroutine 'handler' was never awaited
errortype, result, fatal = report_fault(invokeid, e)
EDIT 2021:
Поскольку этот вопрос, похоже, набирает обороты, я предполагаю, что люди приходят сюда, пытаясь выяснить, как заставить async работать с AWS Lambda, как это делал я. Плохая новость заключается в том, что даже сейчас, более года спустя, AWS все еще не поддерживает асинхронный обработчик в функции Lambda на основе Python. (Я понятия не имею, почему, поскольку функции Lambda на основе NodeJS прекрасно с этим справляются.)
Хорошей новостью является то, что начиная с Python 3.7 существует простой обходной путь в виде asyncio.run:

Код: Выделить всё

import asyncio

def lambda_handler(event, context):
# Use asyncio.run to synchronously "await" an async function
result = asyncio.run(async_handler(event, context))

return {
'statusCode': 200,
'body': result
}

async def async_handler(event, context):
# Put your asynchronous code here
await asyncio.sleep(1)

return 'Success'
Note: The selected answer says that using asyncio.run is not the proper way of starting an asynchronous task in Lambda. In general, they are correct because if some other resource in your Lambda code creates an event loop (a database/HTTP client, etc.), it's wasteful to create another loop and it's better to operate on the existing loop using asyncio.get_event_loop.
However, if an event loop does not yet exist when your code begins running, asyncio.run becomes the only (simple) course of действие.

Вернуться в «Python»