-
Notifications
You must be signed in to change notification settings - Fork 432
feat(idempotency): add support to custom serialization/deserialization on idempotency decorator #2951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
leandrodamascena
merged 54 commits into
aws-powertools:develop
from
aradyaron:feat/idempotency-output-serializer
Sep 5, 2023
Merged
feat(idempotency): add support to custom serialization/deserialization on idempotency decorator #2951
Changes from 52 commits
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
6d85c94
add serializer/deserilizer
aradyaron e142c4b
improve docs
aradyaron 151080b
seperate serializers of input and output
aradyaron 9774248
feat(idempotency): custom serialization - add a helper serailizer cla…
aradyaron 641905c
fix tests
aradyaron e7a3712
Merge branch 'aws-powertools:develop' into feat/idempotency-output-se…
aradyaron f1daf07
idemoponcy changes
aradyaron 17b721c
Merge branch 'feat/idempotency-output-serializer' of github.com:arady…
aradyaron cd6f269
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena 6c4d5d4
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena 423fe7c
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena aebc3ed
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena cf307e5
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron c3797d7
Merge branch 'aws-powertools:develop' into feat/idempotency-output-se…
aradyaron 008aecf
* Add NoOpSerializer instead of checking for None
aradyaron 45a64b5
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron f2e818e
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron 1b39f31
make pr
aradyaron 654396a
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron bf25130
update function description
aradyaron 1075631
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron 7394007
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron d8361af
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron baf49bc
Cr fixes
aradyaron 58c803c
Merge branch 'feat/idempotency-output-serializer' of github.com:arady…
aradyaron f8e591a
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron fc38f63
add support to dynamic model deducation
aradyaron 9f08bf0
add negative tests
aradyaron fdde7b9
add implelementation for dataclass
aradyaron fe4ff3d
add dataclass serializer
aradyaron 4fc2875
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron 1a6aa42
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena 89394d6
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena 18a19a7
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena 8b7d526
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena 988dcfa
Merge pull request #2 from aradyaron/feat/idempotency-output-serializ…
aradyaron 18ae349
cr change requests
aradyaron f6dc695
rename example file
aradyaron cc5a1bd
fix lines
aradyaron 17de6a0
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena ba2ebc6
add more docs and examples
aradyaron 6052783
remove redundant type annotation
aradyaron ebacef8
Merge branch 'feat/idempotency-output-serializer' of github.com:arady…
aradyaron 39b27a0
fix: reading improvements
rubenfonseca e71dd19
fix: mypy errors
rubenfonseca a08ba6d
add newline
aradyaron 020adce
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron af2ecb4
revert file format change
aradyaron c0469b6
add newline
aradyaron 82caabe
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena cef68c7
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron 7aaed7c
Merge branch 'develop' into feat/idempotency-output-serializer
aradyaron f750b3b
Merge branch 'develop' into feat/idempotency-output-serializer
leandrodamascena bfbc636
Adjusts in the documentation
leandrodamascena File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
47 changes: 47 additions & 0 deletions
47
aws_lambda_powertools/utilities/idempotency/serialization/base.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
""" | ||
Serialization for supporting idempotency | ||
""" | ||
from abc import ABC, abstractmethod | ||
from typing import Any, Dict | ||
|
||
|
||
class BaseIdempotencySerializer(ABC): | ||
""" | ||
Abstract Base Class for Idempotency serialization layer, supporting dict operations. | ||
""" | ||
|
||
@abstractmethod | ||
def to_dict(self, data: Any) -> Dict: | ||
raise NotImplementedError("Implementation of to_dict is required") | ||
|
||
@abstractmethod | ||
def from_dict(self, data: Dict) -> Any: | ||
raise NotImplementedError("Implementation of from_dict is required") | ||
|
||
|
||
class BaseIdempotencyModelSerializer(BaseIdempotencySerializer): | ||
""" | ||
Abstract Base Class for Idempotency serialization layer, for using a model as data object representation. | ||
""" | ||
|
||
@classmethod | ||
@abstractmethod | ||
def instantiate(cls, model_type: Any) -> BaseIdempotencySerializer: | ||
""" | ||
Creates an instance of a serializer based on a provided model type. | ||
In case the model_type is unknown, None will be sent as `model_type`. | ||
It's on the implementer to verify that: | ||
- None is handled correctly | ||
- A model type not matching the expected types is handled | ||
|
||
Parameters | ||
---------- | ||
model_type: Any | ||
The model type to instantiate the class for | ||
|
||
Returns | ||
------- | ||
BaseIdempotencySerializer | ||
Instance of the serializer class | ||
""" | ||
pass | ||
leandrodamascena marked this conversation as resolved.
Show resolved
Hide resolved
|
23 changes: 23 additions & 0 deletions
23
aws_lambda_powertools/utilities/idempotency/serialization/custom_dict.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from typing import Any, Callable, Dict | ||
|
||
from aws_lambda_powertools.utilities.idempotency.serialization.base import BaseIdempotencySerializer | ||
|
||
|
||
class CustomDictSerializer(BaseIdempotencySerializer): | ||
def __init__(self, to_dict: Callable[[Any], Dict], from_dict: Callable[[Dict], Any]): | ||
""" | ||
Parameters | ||
---------- | ||
to_dict: Callable[[Any], Dict] | ||
A function capable of transforming the saved data object representation into a dictionary | ||
from_dict: Callable[[Dict], Any] | ||
A function capable of transforming the saved dictionary into the original data object representation | ||
""" | ||
self.__to_dict: Callable[[Any], Dict] = to_dict | ||
self.__from_dict: Callable[[Dict], Any] = from_dict | ||
|
||
def to_dict(self, data: Any) -> Dict: | ||
return self.__to_dict(data) | ||
|
||
def from_dict(self, data: Dict) -> Any: | ||
return self.__from_dict(data) |
43 changes: 43 additions & 0 deletions
43
aws_lambda_powertools/utilities/idempotency/serialization/dataclass.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
from dataclasses import asdict, is_dataclass | ||
from typing import Any, Dict, Type | ||
|
||
from aws_lambda_powertools.utilities.idempotency.exceptions import ( | ||
IdempotencyModelTypeError, | ||
IdempotencyNoSerializationModelError, | ||
) | ||
from aws_lambda_powertools.utilities.idempotency.serialization.base import ( | ||
BaseIdempotencyModelSerializer, | ||
BaseIdempotencySerializer, | ||
) | ||
|
||
DataClass = Any | ||
|
||
|
||
class DataclassSerializer(BaseIdempotencyModelSerializer): | ||
""" | ||
A serializer class for transforming data between dataclass objects and dictionaries. | ||
""" | ||
|
||
def __init__(self, model: Type[DataClass]): | ||
""" | ||
Parameters | ||
---------- | ||
model: Type[DataClass] | ||
A dataclass type to be used for serialization and deserialization | ||
""" | ||
self.__model: Type[DataClass] = model | ||
|
||
def to_dict(self, data: DataClass) -> Dict: | ||
return asdict(data) | ||
|
||
def from_dict(self, data: Dict) -> DataClass: | ||
return self.__model(**data) | ||
|
||
@classmethod | ||
def instantiate(cls, model_type: Any) -> BaseIdempotencySerializer: | ||
if model_type is None: | ||
raise IdempotencyNoSerializationModelError("No serialization model was supplied") | ||
|
||
if not is_dataclass(model_type): | ||
raise IdempotencyModelTypeError("Model type is not inherited of dataclass type") | ||
return cls(model=model_type) |
18 changes: 18 additions & 0 deletions
18
aws_lambda_powertools/utilities/idempotency/serialization/no_op.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from typing import Dict | ||
|
||
from aws_lambda_powertools.utilities.idempotency.serialization.base import BaseIdempotencySerializer | ||
|
||
|
||
class NoOpSerializer(BaseIdempotencySerializer): | ||
def __init__(self): | ||
""" | ||
Parameters | ||
---------- | ||
Default serializer, does not transform data | ||
""" | ||
|
||
def to_dict(self, data: Dict) -> Dict: | ||
return data | ||
|
||
def from_dict(self, data: Dict) -> Dict: | ||
return data |
47 changes: 47 additions & 0 deletions
47
aws_lambda_powertools/utilities/idempotency/serialization/pydantic.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from typing import Any, Dict, Type | ||
|
||
from pydantic import BaseModel | ||
|
||
from aws_lambda_powertools.utilities.idempotency.exceptions import ( | ||
IdempotencyModelTypeError, | ||
IdempotencyNoSerializationModelError, | ||
) | ||
from aws_lambda_powertools.utilities.idempotency.serialization.base import ( | ||
BaseIdempotencyModelSerializer, | ||
BaseIdempotencySerializer, | ||
) | ||
|
||
|
||
class PydanticSerializer(BaseIdempotencyModelSerializer): | ||
"""Pydantic serializer for idempotency models""" | ||
|
||
def __init__(self, model: Type[BaseModel]): | ||
""" | ||
Parameters | ||
---------- | ||
model: Model | ||
Pydantic model to be used for serialization | ||
""" | ||
self.__model: Type[BaseModel] = model | ||
|
||
def to_dict(self, data: BaseModel) -> Dict: | ||
if callable(getattr(data, "model_dump", None)): | ||
# Support for pydantic V2 | ||
return data.model_dump() # type: ignore[unused-ignore,attr-defined] | ||
return data.dict() | ||
|
||
def from_dict(self, data: Dict) -> BaseModel: | ||
if callable(getattr(self.__model, "model_validate", None)): | ||
# Support for pydantic V2 | ||
return self.__model.model_validate(data) # type: ignore[unused-ignore,attr-defined] | ||
return self.__model.parse_obj(data) | ||
|
||
@classmethod | ||
def instantiate(cls, model_type: Any) -> BaseIdempotencySerializer: | ||
if model_type is None: | ||
raise IdempotencyNoSerializationModelError("No serialization model was supplied") | ||
|
||
if not issubclass(model_type, BaseModel): | ||
raise IdempotencyModelTypeError("Model type is not inherited from pydantic BaseModel") | ||
|
||
return cls(model=model_type) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.