terricain / aioboto3

Wrapper to use boto3 resources with the aiobotocore async backend
Apache License 2.0
732 stars 75 forks source link

s3 resource ObjectSummary.size -> argument of type 'coroutine' is not iterable #217

Closed puremcc closed 3 years ago

puremcc commented 3 years ago

Description

Trying to using s3 resource.ObjectSummary to retrieve the filesize of an S3 object. I can await/obtain a valid ObjectSummary object, but the properties are all still coroutine objects. When I try to await the filesize property to resolve it to a value, I get argument of type 'coroutine' is not iterable.

Refer to the statement in the code below re: filesize = await object_summary.size

What I Did

import asyncio
import os

import aioboto3
import boto3

async def main():
    sess = boto3.Session(profile_name=os.getenv('AWS_PROFILE'))

    access_key_id = sess._session.full_config['profiles']['myprofile']['aws_access_key_id']
    access_key = sess._session.full_config['profiles']['myprofile']['aws_secret_access_key']
    aioboto3.setup_default_session(aws_access_key_id=access_key_id, aws_secret_access_key=access_key)

    bucket_name = '******'
    object_key = '******'

    async with aioboto3.resource("s3") as s3:
        object_summary = await s3.ObjectSummary(bucket_name, object_key)
        filesize = await object_summary.size

        print(f'File size: {filesize / 1024**2}')

if __name__ == '__main__':
    asyncio.run(main())

Traceback

RuntimeWarning: coroutine 'AIOBoto3ResourceFactory._create_autoload_property.<locals>.property_loader' was never awaited
  self._variable_reference_to_variable.clear()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
  File "/usr/local/anaconda3/envs/*****/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/local/anaconda3/envs/*****/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/Users/*****/.vscode/extensions/ms-python.python-2020.10.332292344/pythonFiles/lib/python/debugpy/__main__.py", line 45, in <module>
    cli.main()
  File "/Users/*****/.vscode/extensions/ms-python.python-2020.10.332292344/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 430, in main
    run()
  File "/Users/*****/.vscode/extensions/ms-python.python-2020.10.332292344/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 267, in run_file
    runpy.run_path(options.target, run_name=compat.force_str("__main__"))
  File "/usr/local/anaconda3/envs/****/lib/python3.8/runpy.py", line 265, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "/usr/local/anaconda3/envs/****/lib/python3.8/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/local/anaconda3/envs/****/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/Users/*****/Library/Mobile Documents/com~apple~CloudDocs/****/****/****/scripts/batch-tasks/test_aioboto3.py", line 36, in <module>
    asyncio.run(main())
  File "/usr/local/anaconda3/envs/****/lib/python3.8/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/usr/local/anaconda3/envs/****/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/Users/*****/Library/Mobile Documents/com~apple~CloudDocs/****/****/****/scripts/batch-tasks/test_aioboto3.py", line 30, in main
    filesize = await object_summary.size
  File "/usr/local/anaconda3/envs/****/lib/python3.8/site-packages/aioboto3/resources/factory.py", line 116, in property_loader
    await self.load()
  File "/usr/local/anaconda3/envs/****/lib/python3.8/site-packages/boto3/s3/inject.py", line 88, in object_summary_load
    if 'ContentLength' in response:
TypeError: argument of type 'coroutine' is not iterable
sys:1: RuntimeWarning: coroutine 'AioBaseClient._make_api_call' was never awaited
terricain commented 3 years ago

Yep can replicate this. Will look into it

terricain commented 3 years ago

This should be fixed in 8.1.1. Didn't notice this one as ObjectSummary objects from await bucket.objects.all() work fine when getting metadata as it uses a different method..... for some reason :D

I have a feeling other methods will also need tweaking around here as each bit of custom code boto3 adds we'll need to asyncify

puremcc commented 3 years ago

Great, that worked! Thanks!