He hecho funciones Lambda antes pero no en Python. Sé que en Javascript Lambda admite que la función del controlador sea asíncrona, pero aparece un error si lo intento en Python.
Aquí está el código que estoy tratando de probar:
async def handler(event, context): print(str(event)) return { 'message' : 'OK' }
Y este es el error que me sale:
An error occurred during JSON serialization of response: <coroutine object handler at 0x7f63a2d20308> 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: <coroutine object handler at 0x7f63a2d20308> is not JSON serializable /var/runtime/awslambda/bootstrap.py:312: RuntimeWarning: coroutine 'handler' was never awaited errortype, result, fatal = report_fault(invokeid, e)
EDITAR 2021 :
Dado que esta pregunta parece estar ganando terreno, asumo que la gente viene aquí tratando de descubrir cómo hacer que async
funcione con AWS Lambda como yo. La mala noticia es que incluso ahora, más de un año después, AWS todavía no admite ningún controlador asíncrono en una función Lambda basada en Python. (No tengo idea de por qué, ya que las funciones Lambda basadas en NodeJS pueden manejarlo perfectamente).
La buena noticia es que desde Python 3.7, existe una solución simple en forma de 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'
De nada. Los controladores asíncronos de Python no son compatibles con AWS Lambda.
Si necesita usar la funcionalidad async
/ await
en su AWS Lambda, debe definir una función asíncrona en su código (ya sea en archivos Lambda o en una capa Lambda) y llamar a asyncio.get_event_loop().run_until_complete(your_async_handler())
dentro de su controlador de sincronización
Tenga en cuenta que asyncio.run
( presentado en Python 3.7 ) no es una forma adecuada de llamar a un controlador asíncrono en el entorno de ejecución de AWS Lambda, ya que Lambda intenta reutilizar el contexto de ejecución para invocaciones posteriores. El problema aquí es que asyncio.run
crea un nuevo EventLoop
y cierra el anterior. Si abrió algún recurso o creó corrutinas adjuntas al EventLoop
cerrado de la invocación anterior de Lambda, obtendrá el error "Event loop closed". asyncio.get_event_loop().run_until_complete
le permite reutilizar el mismo bucle. Consulte la pregunta relacionada con StackOverflow.
La documentación de AWS Lambda engaña un poco a sus lectores al introducir invocaciones sincrónicas y asincrónicas. No lo mezcle con las funciones de sincronización/asincronización de Python. Síncrono se refiere a invocar AWS Lambda con más espera por el resultado (operación de bloqueo). La función se llama de inmediato y obtiene la respuesta lo antes posible. Mientras que al usar una invocación asincrónica , le pide a Lambda que programe la ejecución de la función y no espere la respuesta en absoluto . Cuando llegue el momento, Lambda aún llamará a la función del controlador de forma síncrona .