Boto3: будущее или сопрограмма требуется - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь загрузить 2 файла с S3, используя boto3, и подождать, пока 2 файла не загрузятся, продолжит обрабатывать 2 файла

Что я сделал

async def download_files():
    await client.download_file(const.bucket_name, 'file/name.txt', '/tmp/name.txt')
    print('file 1 downloaded')
    await client.download_file(const.bucket_name, 'file/class.txt', '/tmp/class.txt')
    print('file 2 downloaded')
    return True

def main():
    ...
    loop = asyncio.get_event_loop()
    loop.run_until_complete(download_files())
    loop.close()
    ...
main()

Iполучил ошибку

A Future or coroutine is required

Впервые я использую asyncio, пожалуйста, сообщите мне.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

посмотрите на aioboto3 . Также для более низкого уровня посмотрите в aiobotocore . Оба доступны через пипс

0 голосов
/ 27 января 2019

boto3 не поддерживает асинхронность ... его функции скорее блокируют, чем ожидают.Таким образом, абсолютный минимум, который нужно сделать здесь, это просто удалить await из вызовов на download_file, и это должно работать.

client.download_file(const.bucket_name, 'file/name.txt', '/tmp/name.txt')
print('file 1 downloaded')
client.download_file(const.bucket_name, 'file/class.txt', '/tmp/class.txt')
print('file 2 downloaded')
return True

Однако, это может иметь плохие свойства параллелизма, еслилюбые другие параллельные задачи в цикле событий потока: они будут заблокированы и не будут продолжаться во время загрузок [это сделало бы использование asyncio немного ненужным ... выполнение параллельных задач является своего рода точкой асинхронности ...]

Чтобы иметь лучшие свойства параллелизма, вы должны иметь возможность вызывать функции через run_in_executor, который по умолчанию будет запускать переданную функцию в другом потоке.

async def download_files(loop):
  await loop.run_in_executor(None, client.download_file, const.bucket_name, 'file/name.txt', '/tmp/name.txt')
  print('file 1 downloaded')
  await loop.run_in_executor(None, client.download_file, const.bucket_name, 'file/class.txt', '/tmp/class.txt')
  print('file 2 downloaded')
  return True

В качестве альтернативы, вместо того, чтобы использовать boto3 и потоки, вы можете использовать aiohttp и аутентификацию AWS "на рулоне" (полное раскрытие информации: публикация на AWS "самостоятельно")Аутентификация была написана мной)

...