Request Mixins

Request Mixins are classes that define the functionality of each Request subclass. All subclasses inherit from the BaseRequest, which define the constructor and basic helpers to build the request.

BaseRequest

class cerami.request.mixins.base_request.BaseRequest(client, tablename='', request_attributes=None, reconstructor=None)

The Base Class for all requests

It provides the default constructor and methods for building requests.

client

A boto3.client('dynamodb')

request_attributes

a dict of SearchAttribute objects whose keys represent options that can be passed to client upon execution For example, it may include a FilterExpression key whose value is a SearchAttribute that resolves to a string of filters. This is typically None but can be used to manually build requests:

Parent.scan.filter(Parent.name == 'Mom').project(Parent.name)
# The search_attributes can be manually specified
ScanRequest(client=client, tablename='parents', search_attributes={
    'FilterExpression': SearchAttribute('name = Mom'),
    'ProjectionExpression': SearchAttribute('name'),
})
reconstructor

a Reconstructor object

__init__(client, tablename='', request_attributes=None, reconstructor=None)

constructor for base request

Parameters
  • client – A boto3.client('dynamodb')

  • tablename – the name of the table to perform the request on

  • request_attributes

    a dict of SearchAttribute objects whose keys represent options that can be passed to client upon execution For example, it may include a FilterExpression key whose value is a SearchAttribute that resolves to a string of filters. This is typically None but can be used to manually build requests:

    Parent.scan.filter(Parent.name == 'Mom').project(Parent.name)
    # The search_attributes can be manually specified
    ScanRequest(client=client, tablename='parents', search_attributes={
        'FilterExpression': SearchAttribute('name = Mom'),
        'ProjectionExpression': SearchAttribute('name'),
    })
    

  • reconstructor – a Reconstructor object

add_attribute(attr_class, name, value)

add a search attribute to a to the request_attributes dict

All search attributes must be unique keys. When the key already exists, it will update that value by calling add(). Depending on the attr_class, this can overwrite, append, change the value of the existing search attribute.

Parameters
  • attr_class – a SearchAttribute class

  • name – the name of the attribute

  • value – the value that will be added to the SearchAttribute

For example:

Person.scan.limit(10)
# or ...
Person.scan.add_attribute(SearchAttribute, 'Limit', 10)
build()

build the dict used by dynamodb

Returns

a dict whose keys matching the keys of the request_attributes and whose values are string versions of each attribute

For example:

User.scan.filter(User.email == 'test@test.com').build()
{
    "TableName": "Users",
    "FilterExpression": "#__email = :_email_dpxqm",
    "ExpressionAttributeNames": {
        "#__email": "email"
    },
    "ExpressionAttributeValues": {
        ":_email_dpxqm": {
            "S": "test@test.com"
        }
    }
}

Filterable

class cerami.request.mixins.Filterable

A mixin to add the filter method

filter(*expressions)

return a new Request setup with filter attributes

Adds the FilterExpression, ExpressionAttributeNames, and ExpressionAttributeValue to the request_attributes dict

Parameters

*expressions – a list of BaseExpressions

Returns

the caller of the method. This allows for chaining

For example:

Person.scan.filter(Person.name == 'Zac').filter(Person.age < 50).build()
{
    "TableName": "people",
    "FilterExpression": "#__name = :_name_pwmbx and #__age < :_age_twtue",
    "ExpressionAttributeNames": {
        "#__name": "name",
        "#__age": "age"
    },
    "ExpressionAttributeValues": {
        ":_name_pwmbx": {
            "S": "Zac"
        },
        ":_age_twtue": {
            "N": "50"
        }
    }
}

Keyable

class cerami.request.mixins.Keyable

A mixin to add the key method

key(*expressions)

return a new Request setup with the Key attribute

Adds the Key to the request_attributes dict

Parameters

*expressions – a list of BaseExpressions

Returns

the caller of the method. This allows for chaning

For example:

Person.get.key(Person.email == 'test@test.com').build()
{
    "TableName": "people",
    "Key": {
        "email": {
            "S": "test@test.com"
        }
    }
}

Limitable

class cerami.request.mixins.Limitable

A mixin to add the limit method

limit(limit_number)

return a new Request setup with the limit attribute

Adds the Limit to the request_attributes dict

Parameters

limit_number – a number representing the maximum items to be returned

Returns

the caller of the method. This allows for chaining

For example:

Person.scan.limit(10).build()
{
    "TableName": "people",
    "Limit": 10
}

Pageable

class cerami.request.mixins.Pageable

A mixin to add the start_key method

Pageable requests can be paginated by passing in an ExclusiveStartKey attribute.

start_key(key)

return a new Request setup with the ExclusiveStartKey attribute

Parameters

key – A dict representing the exclusive start key. This key is _excluded_ from the response. Typically, this key is auto-generated from a previous response of a request.

For example:

request = Person.scan \
    .limit(1) \
    .start_key({"email": {"S": "test@test.com"}})

request.build()
{
    "TableName": "people",
    "Limit": 1,
    "ExclusiveStartKey": {
        "email": {
            "S": "test@test.com",
        },
    },
}

# you can use the responses exclusive_start_key to continually paginate
response = request.execute()
next_response = request.start_key(response.last_evaludated_key).execute()

Projectable

class cerami.request.mixins.Projectable

A mixin to add the project method

project(*datatypes_or_expressions)

return a new Request setup with project attributes

Adds the ProjectionExpression, ExpressionAttributeNames to the request_attributes dict

Parameters

*datatypes – a list of datatypes. List.index() and Map.key() can be passed to project specific nested attributes

Returns

the caller of the method. This allows for chaining

For example:

Person.scan.project(Person.name, Person.email)
{
    "TableName": "people",
    "ProjectionExpression": "#__name  :_name_lwxqt, #__email  :_email_dvsyj",
    "ExpressionAttributeNames": {
        "#__name": "name",
        "#__email": "email"
    }
}

Returnable

class cerami.request.mixins.Returnable

A mixin to add the returns method

returns(value)

return the Request setup with ReturnValues attribute

Adds the ReturnValues to the request attributes dict

Parameters

value – NONE | ALL_OLD | UPDATED_OLD | ALL_NEW | UPDATED_NEW

Returns

the caller of the method. This allows for chaining

For example:

from cerami.request.return_values import UPDATED_NEW
Person.update \
    .key(Person.email == 'test@test.com') \
    .set(Person.name, 'new name') \
    .returns(UPDATED_NEW) \
    .build()
{
    "TableName": "people",
    "ReturnValues": "UPDATED_NEW",
    "Key": {
        "email": {
            "S": "test@test.com"
        }
    },
    "UpdateExpression": "SET #__name = :_name_zhvzz",
    "ExpressionAttributeNames": {
        "#__name": "name"
    },
    "ExpressionAttributeValues": {
        ":_name_zhvzz": {
            "S": "new name"
        }
    }
}