AWS Lambda / Asyncio:Coroutine从未等待过

时间:2017-11-16 18:40:53

标签: python multithreading amazon-web-services aws-lambda python-asyncio

目前正在尝试将报表自动化工具上传到AWS Lambda,该工具使用asyncio创建多个线程,从API收集数据。以下是该问题的相关代码:

def campaign_report(config):
    print('Setting Campaign Report Details . . .')
    futures = []

    # fields determine what data to pull from the API
    fields = [
        'campaign_name',
        'actions',
        'impressions',
        'spend'
    ]

    # params determines what type of data to pull from the API
    params = {
        'limit': '10000',
        'date_preset': 'last_30d',
        'level': 'campaign',
        'breakdowns': ['device_platform']
    }

    # general columns that we want to get from insight that have a single layer of data
    general_columns = {
        'campaign_name': 'campaign_name',
        'impressions': 'impressions',
        'spend': 'spend',
        'device_platform': 'device_platform'
    }

    # action columns that we want to get from insight['actions'] that have a multi-layer of data
    # format is action.action_type_returned_from_api: column_name
    action_columns = {
        'action.link_click': 'link_click',
        'action.like': 'like',
        'action.app_install': 'app_install',
        'action.landing_page_view': 'landing_page_view'
    }

    # action videos that we want to get from insight videos that have a multi-layer of data
    # format is action_video_returned_from_api: db_column_name
    action_video_columns = {}

    loop = asyncio.get_event_loop()
    loop.run_until_complete(handle_report(config, fields, params))
    loop.close()

    print('Configuring Data . . .')
    configured_report = CampaignReport().get_insights_values(
        insights=data,
        general_columns=general_columns,
        action_video_columns=action_video_columns,
        action_columns=action_columns
    )

    return {'campaigns': configured_report}


async def handle_report(config, fields, params):
    with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
        loop = asyncio.get_event_loop()
        futures = [
            loop.run_in_executor(executor, fetch_report, account['id'], account['name'], fields, params)
            for account in config['accounts']
        ]

        for response in await asyncio.gather(*futures):
            global data
            print('Exporting %s Data . . .' % response['name'])
            data.append(response['name'])
            data = data + list(response['report'])


def fetch_report(account_id, account_name, fields, params):
    print('Fetching %s Report Data . . .' % account_name)
    report = CampaignReport().get_insights_async(
        account_id,
        account_name,
        fields=fields,
        params=params
    )

    return {'name': account_name, 'report': report}

首先,调用campaign_report()来构建报告详细信息并实例化asyncio线程池执行程序。执行程序根据需要的帐户数创建池,并且应该并行执行池。完成每个报告后,数据将映射到更大的列表并从那里进行配置。

我将在此前言,这完全在本地工作,没有明显的问题/错误。但是,一旦我将其上传到AWS Lambda,我就会收到以下错误:

START RequestId: 977dfaeb-cafa-11e7-9e9e-fdf67b36edf2 Version: $LATEST
Setting Campaign Report Details . . .
A Future or coroutine is required
**** Program Execution Complete --- 1.1237462361653646e-05 minutes ****
A Future or coroutine is required: TypeError
Traceback (most recent call last):
  File "/var/task/lambda_helper.py", line 206, in lambda_handler
    raise e
  File "/var/task/lambda_helper.py", line 198, in lambda_handler
    report = campaign_report(config)
  File "/var/task/lambda_helper.py", line 77, in campaign_report
    loop.run_until_complete(handle_report(config, fields, params))
  File "/var/task/asyncio/base_events.py", line 296, in run_until_complete
    future = tasks.async(future, loop=self)
  File "/var/task/asyncio/tasks.py", line 516, in async
    raise TypeError('A Future or coroutine is required')
TypeError: A Future or coroutine is required

/var/runtime/awslambda/bootstrap.py:264: RuntimeWarning: coroutine 'handle_report' was never awaited
  errortype = "unhandled"
END RequestId: 977dfaeb-cafa-11e7-9e9e-fdf67b36edf2
REPORT RequestId: 977dfaeb-cafa-11e7-9e9e-fdf67b36edf2  Duration: 2.40 ms

声称除了TypeError之外没有声明await。当我查看我的代码时,我似乎无法找到设置asyncio时出错的地方。

这里的任何帮助都会很棒!

1 个答案:

答案 0 :(得分:0)

您的代码适用于Python> = 3.5.1,请确保您运行的版本正确。