All public symbols are visible in the top-level module, no need to import submodules.

All examples in this doc depend on:

>>> from LowVoltage import *
>>> table = "LowVoltage.Tests.Doc.1"
>>> table2 = "LowVoltage.Tests.Doc.2"
>>> connection = Connection("us-west-2", EnvironmentCredentials())


class Connection(region, credentials, endpoint=None, retry_policy=None, requests_session=None)

The main entry point of the package.

  • region – the identifier of the AWS region you want to connect to. Like "us-west-2" or "eu-west-1".
  • credentials – a credentials providers. See credentials.
  • endpoint – the HTTP endpoint you want to connect to. Typically useful to connect to DynamoDB Local with endpoint="http://localhost:8000/". If left None, it will be computed from the region.
  • retry_policy – a retry policy. See retry_policies. If left None, the DEFAULT retry policy will be used.
  • requests_session – a Session object from the python-requests library. Typically not used. Leave it to None and one will be created for you.

Send requests and return responses.


Authentication credentials are passed to the connection as a credentials provider. On each request, the connection retrieves a key/secret pair from the credentials provider, uses it to sign the request, and then discards it. This allows credentials rotation in the same long-lived connection: the credential provider just has to return the new credentials.

class Credentials

The interface to be implemented by all credential providers. Note that you must not inherit from this class, just implement the same interface.


Return the key/secret/token to be used to sign the next request. If the credentials are permanent, return None as token.

Type:tuple of (string, string, None or string)
class StaticCredentials(key, secret, token=None)

The simplest credential provider: a constant key/secret pair (and optionally a session token if you know what you’re doing).

class EnvironmentCredentials

Credential provider reading the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and optionally AWS_SECURITY_TOKEN environment variables.

class Ec2RoleCredentials(requests_session=None)

Credentials provider using EC2 instance metadata to retrieve temporary, automatically rotated, credentials from the IAM role of the instance. Usable only on an EC2 instance with an IAM role assigned.

Parameters:requests_session – a Session object from the python-requests library. Typically not used. Leave it to None and one will be created for you.

Retry policies

Some errors are retryable: NetworkError or ProvisionedThroughputExceededException for example. When they happen, it makes sense to wait for a short while and then retry the request. Retry policies decide if it’s worth retrying and how long to wait.

class RetryPolicy

The interface to be implemented by all retry policies. Note that you must not inherit from this class, just implement the same interface.

retry(action, exceptions)

Return the delay before retrying the action. None if the action shouldn’t be retried.

  • action – the action that failed.
  • exceptions – the (retryable) exceptions that occured so far. The most recent exception is exceptions[-1].

None or number (in seconds)

class ExponentialBackoffRetryPolicy(first_wait, multiplier, max_retries)

Retry failed requests with a waiting time growing exponentialy.

  • first_wait – the duration to wait before the first retry.
  • multiplier – the factor by which to augment the waiting duration between successive retries. Greater than 1.
  • max_retries – the maximum number of times to retry a failed action (0 meaning “don’t retry”, 1 meaning “retry once”, etc.).
DEFAULT = ExponentialBackoffRetryPolicy(1, 1.5, 4)

The default retry policy: a reasonable exponential backoff.

FAIL_FAST = ExponentialBackoffRetryPolicy(1, 1, 0)

A retry policy that never retries anything.

Attribute types

In DynamoDB, the key attributes are typed. Here are a few constants for those types, to be used in CreateTable or compared to what DescribeTable returns.


The ‘string’ attribute type


The ‘number’ attribute type


The ‘binary’ attribute type

Python types

Attributes in DynamoDB can have some types. LowVoltage translates some Python types to be stored in DynamoDB:

  • number 10 is stored as "N" (number)
>>> connection(PutItem(table, {"h": 0, "number": 10}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'h': 0, u'number': 10}
  • unicode u"foobar" is stored as "S" (string, properly utf8-encoded)
>>> connection(PutItem(table, {"h": 0, "unicode": u"foobar"}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'h': 0, u'unicode': u'foobar'}
  • bytes b"barbaz" is stored as "B" (binary, properly base64-encoded)
>>> connection(PutItem(table, {"h": 0, "bytes": b"barbaz"}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'h': 0, u'bytes': 'barbaz'}

Note that strings are bytes in Python 2 and unicode in Python 3. You may want to avoid them.

  • booleans True and False are stored as "BOOL"
>>> connection(PutItem(table, {"h": 0, "boolean": True}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'h': 0, u'boolean': True}
  • None is stored as "NULL"
>>> connection(PutItem(table, {"h": 0, "none": None}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'h': 0, u'none': None}
  • an homogeneous set of numbers {24, 57} is stored as "NS" (number set)
>>> connection(PutItem(table, {"h": 0, "set_of_number": {24, 57}}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'h': 0, u'set_of_number': set([24, 57])}
  • an homogeneous set of unicodes {u"foo", u"bar"} is stored as "SS" (string set)
>>> connection(PutItem(table, {"h": 0, "set_of_unicode": {u"foo", u"bar"}}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'h': 0, u'set_of_unicode': set([u'foo', u'bar'])}
  • an homogeneous set of bytes {b"bar", b"baz"} is stored as "BS" (binary set)
>>> connection(PutItem(table, {"h": 0, "set_of_bytes": {b"bar", b"baz"}}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'set_of_bytes': set(['baz', 'bar']), u'h': 0}
  • a list ["a", {"b": "c"}, 42] is stored as "L" (list)
>>> connection(PutItem(table, {"h": 0, "list": ["a", {"b": "c"}, 42]}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'h': 0, u'list': ['a', {u'b': 'c'}, 42]}

Note that lists are stored as "L" even if they are homogeneous, so you have to use sets if you plan to use UpdateItem.add() and UpdateItem.delete().

  • a dict {"a": "b", "c": 42} is stored as "M" (map)
>>> connection(PutItem(table, {"h": 0, "dict": {"a": "b", "c": 42}}))
<LowVoltage.actions.put_item.PutItemResponse ...>
>>> connection(GetItem(table, {"h": 0})).item
{u'h': 0, u'dict': {u'a': 'b', u'c': 42}}
  • everything else will raise a TypeError:
>>> connection(PutItem(table, {"h": 0, "something_else": {"a", 42}}))
Traceback (most recent call last):
TypeError: ...