Я хочу, чтобы асинхронный API получал запросы на моей лямбда-aws (время выполнения - python 3.6). Первоначально я пытался использовать grequests, но я не знаю, как скомпилировать это в совместимый с linux комплект для импорта в AWS lambda (я встречал «Gevent требуется для ошибки grequests»). Вместо этого сейчас я использую aysncio / aiohttp. На моем локальном компьютере он работает совершенно нормально, но когда я переношу его в AWS lambda (вручную развернуть, заархивировав пакеты и папку src в .zip, а затем загрузив), я столкнусь с
TypeError: A Future or coroutine is required
/var/runtime/awslambda/bootstrap.py:290: RuntimeWarning: coroutine 'main' was never awaited
Вот соответствующие части моего кода:
import os
import boto3
import json
import base64
from datetime import datetime
import logging
import asyncio
import aiohttp
async def fetch(session, headers, url):
async with session.get(url, headers=headers ) as response:
logging.info(response.status)
return await response.text()
async def main(urls, headers):
tasks = []
connector = aiohttp.TCPConnector(limit=13)
async with aiohttp.ClientSession(connector=connector) as session:
for url in urls:
task = asyncio.ensure_future(fetch(session, headers, url))
tasks.append(task)
responses = await asyncio.gather(*tasks)
return responses
# Invoked method
def lambda_handler(event, context):
my_urls = []
for record in event['Records']:
decoded = base64.b64decode(record['kinesis']['data'])
try:
url_record = json.loads(decoded)
url = url_record['url']
patient_urls.append(url)
except (json.JSONDecodeError, KeyError):
error = "Could not read url from record: {}".format(decoded)
logging.error(error)
continue
token = get_token() # method not included as not relevant to error
if token is not None:
headers = {"Authorization": "Bearer {}".format(token)}
loop = asyncio.get_event_loop()
results = loop.run_until_complete(main(my_urls, headers))
print("we did it:",len(results))
else:
timestamp = str(datetime.now())
error = timestamp + "Token error"
logging.error(error)
Я не понимаю, почему эта ошибка возникает, поскольку она прекрасно работает на моей локальной машине, и я практически скопировал код. Вот местный код для справки:
async def fetch(session, headers, url):
async with session.get(url, headers=headers ) as response:
return await response.text()
async def main(urls, headers):
tasks = []
connector = aiohttp.TCPConnector(limit=13)
async with aiohttp.ClientSession(connector=connector) as session:
for url in urls:
task = asyncio.ensure_future(fetch(session, headers, url))
tasks.append(task)
responses = await asyncio.gather(*tasks)
return responses
start = time.time()
token = get_token()
headers = {"Authorization": "Bearer {}".format(token)}
patient_urls = get_urls()
loop = asyncio.get_event_loop()
a = loop.run_until_complete(main(patient_urls, headers))
print("we did it!",len(a))
end = time.time()
print("it took {} seconds".format(end-start))