Можете ли вы использовать асинхронный обработчик в 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'
Примечание. В выбранном ответе говорится, что использование asyncio.run не является правильным способом запуска асинхронной задачи в Lambda. В целом они верны, поскольку если какой-либо другой ресурс в вашем Lambda-коде создает цикл событий (база данных/HTTP-клиент и т. д.), создавать еще один цикл нецелесообразно, и лучше работать с существующим циклом, используя asyncio.get_event_loop.
Однако, если цикл событий еще не существует, когда ваш код начинает работать, asyncio.run становится единственным (простым) способом действие.

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