Search code examples
pythonpython-3.xamazon-web-servicesaws-sdkboto3

Type annotation for boto3 resources like DynamoDB.Table


The boto3 library provides several factory methods that returns resources. For example:

dynamo = (
    boto3
    .resource('dynamodb')
    .Table(os.environ['DYNAMODB_TABLE'])
)

I want to annotate those resources so I can get better type checking and completion, but the only type alike I could find was from boto3.dynamodb.table import TableResource.

When I add that annotation:

dynamo: TableResource = (
    boto3
    .resource('dynamodb')
    .Table(os.environ['DYNAMODB_TABLE'])
)

The only method offered by auto-completion is batch_writer(self, overwrite_by_pkeys), even though the docs lists several others.

Is this the wrong class to use as annotation? Inspecting that variable type in the terminal I could see that it was <class 'boto3.resources.factory.dynamodb.Table'>, but it doesn't seem to be possible to get that type statically.


Solution

  • The types and API methods don't exist statically. boto3 uses data driven architecture, an extremely dynamic design that uses data in JSON format (here is an example) to determine what API calls are possible. They do this to make it easy to update the library to include new API changes. I'm not sure but I think they might use the same strategy for SDKs in other languages, so changes to multiple SDKs can be made with little duplicated work.

    Here's a quote from their blog:

    Libraries must adapt to changes in users’ needs and also to changes in the platforms on which they run. As AWS’s growth accelerated over the years, the speed at which our APIs are updated has also gotten faster. This required us to devise a scalable method to quickly deliver support for multiple API updates every week, and this is why AWS API support in Boto3 is almost completely data-driven. Boto3 has ‘client’ classes that are driven by JSON-formatted API models that describe AWS APIs, so most new service features only require a simple model update. This allows us to deliver support for API changes very quickly, in consistent and reliable manner.

    You can also get a glimpse of this happening by stepping into a method call such as resource.Table in a debugger.