Skip to main content

Dynamizer

A supportive set of defaults for dynamodb. Dynamizer doesn't aim to abstract away the nuances of dynamodb, but rather to provide effective defaults for the repetitive tasks of (de)serializing models to and from dynamodb.

It provides:

  • Automatic deserialization from dynamo's format. This is helpful when processing a change stream from dynamo.
  • Overwrite detection. If a model is changed between reading it and writing it back to dynamodb an error will be raised, preventing the unintentional overwriting of existing data.
  • Supportive base delete, save, and load function to make a programmers life easier.

Usage

Dynamizer models are built on top of immutable data classes.

import dataclasses
import dynamizer


@dataclasses.dataclass(frozen=True)
class DemoClass(dynamizer.DynamiteModel):
    """A demo class."""

    foobar: str
    fizbuzz: typing.Optional[str] = None

    @property
    def hash_key(self) -> str:
        """
        Get the hash key.

        Dynamizer can't tell you what the right hash/range key scheme is
        write for your use case and access patterns so you must define
        how to translate the model's data into a hash and range key.
        """
        return f"hash-key/{self.foobar}"

    @property
    def range_key(self) -> str:
        """Get the range key."""
        return "/range-key"

    def _gs1(self) -> str:
        """
        Get the gs1 value.

        Dynamizer will also support you in instantiating any global secondary
        indices. It expects these to be defined matching the pattern
        `^_?gs\d+$`. Dynamizer searches the class for any functions matching
        this pattern and automatically manages their lifecycle within dynamodb,
        creating them dynamically as the model is saved, and deleting them
        if they are null in some part of the models life. Note that The index
        itself still needs to be created within dynamodb.
        """
        return f"{self.foobar}/hash-key"

    @classmethod
    def load(cls, my_identifier: typing.Any) -> "DemoClass":
        """
        Load a model from dynamodb.

        Dynamizer does not provide a default load function, since it doesn't
        know all of your specific access patterns and how incoming arguments
        are to be translated into a hash key, range key pair, but it does
        provide helpful secondary methods to make writing a load function
        easier.
        """
        hash_key = _hash_key(my_identifier)
        range_key = _hash_key(my_identifier)
        client = boto3.client("dynamodb")
        result = cls._base_load(client, "my-table-name", hash_key, range_key)
        if result is None:
            raise NotFoundError(f"Could not find {my_identifier}")
        return result

    @classmethod
    def list_group(cls, my_group: typing.Any) -> typing.List["DemoClass"]:
        """
        List a model under the specified group.

        Dynamizer provides methods for easily converting a dynamodb response
        into a python model making it easier to write functions defining a
        variety of access patterns.
        """
        ...
        response = client.query("Something fancy")
        return [cls.inflate(item) for item in response.get("Items", [])]


    def save(self) -> "DemoClass":
        """
        Save a model.

        Dynamizer keeps a count of changes to a model and checks when saving
        to ensure that no changes have come in since the model was initially
        read. This prevents data from being overwritten both during initial
        creation and during updates.
        """
        ...
        return self._base_save(client, "table_to_save_to")

    def delete(self):
        """
        Delete a model.

        Like during saves, Dynamizer keeps a count of changes and will prevent
        a delete from taking place if an update has taken place since the last
        read.
        """
        ...
        self._base_delete(client, "table_to_delete_from")

Mocking

Dynamizer provides a mechanism for mocking out dynamodb calls for testing. The initial state of dynamodb can be set via yaml files.

import dynamizer.mock

data = yaml.safe_load("/path/to/data.yaml")

with dynamizer.mock.from_yaml(data):
    # Within this context dynamodb will have the state defined in data.yaml

The expected format of the yaml file is:

- table_name: my-table-name
  region: us-east-1 # Optional
  secondary_indexes: # Optional
    - name: gs1-gs2
      hash_key: gs1
      range_key: gs2
  objects:
    MyDynamizerSubCls:
      - foo: {S: bar}
        fiz: {S: buzz}
    AnotherDynamizerSubCls:
      - mock: {S: data}

Metadata

Release files for dynamizer 0.2.14

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dynamizer 0.2.14
File Size Uploaded Provenance Actions
dynamizer-0.2.14.tar.gz 8.0 kB Without provenance Details for dynamizer-0.2.14.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for dynamizer 0.2.14
File Interpreter ABI Platform Actions
dynamizer-0.2.14-py3-none-any.whl Python 3 none any Details for dynamizer-0.2.14-py3-none-any.whl

Total release size: 17.8 kB

Release files / dynamizer-0.2.14.tar.gz

Download URL dynamizer-0.2.14.tar.gz
Size 8.0 kB
Tags Source
SHA-256 checksum
How to use checksums
5e96267dbfac6e16950d33dec29dc9e80042ea4dcaeccb93adafc393bf337e94
BLAKE2b-256 checksum
How to use checksums
6d1429d154ca8db4d9dcdf347a1720a8d7b8b1fdf80d1803c8f16de9be9c9516
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.1.2 CPython/3.13.3 Linux/6.14.4-300.fc42.x86_64

Release files / dynamizer-0.2.14-py3-none-any.whl

Download URL dynamizer-0.2.14-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
38d787359c44d3e78e0fa49d86bd82e95db7159db806e3a9ce266ce0bdd113fd
BLAKE2b-256 checksum
How to use checksums
49b212b27f3abd4238de6dfe3b506493bc76e8b58a28ab0c41af11b53e70cda0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.1.2 CPython/3.13.3 Linux/6.14.4-300.fc42.x86_64

Security for dynamizer 0.2.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page