Search code examples
pythonpython-3.xamazon-web-servicesaws-lambdapython-asyncio

how can I handle both coroutines and regular functions in aws lambda


I'm writing an application inside an AWS lambda function behind an api gateway

some functions can be asynchronous (co-routines) and other are regular functions

how can I handle this in the "main handler"

# here I'm mapping different paths / resources to different functions
main_router = {}
main_router.update(first_router)
main_router.update(second_router)



async def main(event):
    try:
        payload = {}
        resource = event['resource']
        payload['resource'] = resource
        payload['path'] = event['path']
        payload['method'] = event['httpMethod']
        body = event.get('body')
        query_params = event.get('queryStringParameters')
        if body:
            payload.update(body)
        if query_params:
            payload.update(query_params)

        if resource in main_router:
            return await main_router[resource](payload)
        return "not in main router"
    except Exception as e:
        return str(e)


def lambda_handler(event, _context):
    return asyncio.run(main(event))

this fails if the path was directed to a regular function and not an async one,

I'd like something like

    if regular_function:
         return main_router[resource](payload)
    if coroutine
         return await main_router[resource](payload)

with the lambda handler just having

return asyncio.run(main(event))

this is an example of a router

postmortems_router = {
    "/services": get_services,  # a regular function
    "/services/{proxy+}": get_specific_service, # an async def function
}

EDIT: Found a way to do this from python side:

import inspect

if inspect.iscoroutinefunction(main_router[resource]):
    return await main_router[resource](payload)
else:
    return main_router[resource](payload)

currently both are running just fine with the lambda_handler just being

return asyncio.run(main())

I'll update the post if I faced any issue with this


Solution

  • Found a way to do this from python side:

    import inspect
    
    if inspect.iscoroutinefunction(main_router[resource]):
        return await main_router[resource](payload)
    else:
        return main_router[resource](payload)
    

    currently both are running just fine with the lambda_handler just being

    return asyncio.run(main())