-
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 31 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.
19 changes: 19 additions & 0 deletions
19
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,19 @@ | ||
""" | ||
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: | ||
pass | ||
leandrodamascena marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@abstractmethod | ||
def from_dict(self, data: Dict) -> Any: | ||
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) |
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 |
30 changes: 30 additions & 0 deletions
30
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,30 @@ | ||
from typing import Dict, Type | ||
|
||
from pydantic import BaseModel | ||
|
||
from aws_lambda_powertools.utilities.idempotency.serialization.base import BaseIdempotencySerializer | ||
|
||
Model = BaseModel | ||
|
||
|
||
class PydanticSerializer(BaseIdempotencySerializer): | ||
def __init__(self, model: Type[Model]): | ||
""" | ||
Parameters | ||
---------- | ||
model: Model | ||
A Pydantic model of the type to transform | ||
""" | ||
self.__model: Type[Model] = model | ||
|
||
def to_dict(self, data: Model) -> 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) -> Model: | ||
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) |
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
54 changes: 54 additions & 0 deletions
54
examples/idempotency/src/working_with_idempotent_function_dataclass_output_serializer.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,54 @@ | ||
from dataclasses import dataclass | ||
|
||
from aws_lambda_powertools.utilities.idempotency import ( | ||
DynamoDBPersistenceLayer, | ||
IdempotencyConfig, | ||
idempotent_function, | ||
) | ||
from aws_lambda_powertools.utilities.idempotency.serialization.custom_dict import CustomDictSerializer | ||
from aws_lambda_powertools.utilities.typing import LambdaContext | ||
|
||
dynamodb = DynamoDBPersistenceLayer(table_name="IdempotencyTable") | ||
config = IdempotencyConfig(event_key_jmespath="order_id") # see Choosing a payload subset section | ||
|
||
|
||
@dataclass | ||
class OrderItem: | ||
sku: str | ||
description: str | ||
|
||
|
||
@dataclass | ||
class Order: | ||
item: OrderItem | ||
order_id: int | ||
|
||
|
||
@dataclass | ||
class OrderOutput: | ||
order_id: int | ||
|
||
|
||
order_output_serializer: CustomDictSerializer = CustomDictSerializer( | ||
leandrodamascena marked this conversation as resolved.
Show resolved
Hide resolved
|
||
to_dict=lambda x: x.asdict(), | ||
from_dict=lambda x: OrderOutput(**x), | ||
rubenfonseca marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
|
||
|
||
@idempotent_function( | ||
data_keyword_argument="order", | ||
config=config, | ||
persistence_store=dynamodb, | ||
output_serializer=order_output_serializer, | ||
) | ||
def process_order(order: Order) -> OrderOutput: | ||
return OrderOutput(order_id=order.order_id) | ||
|
||
|
||
def lambda_handler(event: dict, context: LambdaContext): | ||
config.register_lambda_context(context) # see Lambda timeouts section | ||
order_item = OrderItem(sku="fake", description="sample") | ||
order = Order(item=order_item, order_id=1) | ||
|
||
# `order` parameter must be called as a keyword argument to work | ||
process_order(order=order) |
44 changes: 44 additions & 0 deletions
44
examples/idempotency/src/working_with_idempotent_function_pydantic_output_serializer.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,44 @@ | ||
from aws_lambda_powertools.utilities.idempotency import ( | ||
DynamoDBPersistenceLayer, | ||
IdempotencyConfig, | ||
idempotent_function, | ||
) | ||
from aws_lambda_powertools.utilities.idempotency.serialization.pydantic import PydanticSerializer | ||
from aws_lambda_powertools.utilities.parser import BaseModel | ||
from aws_lambda_powertools.utilities.typing import LambdaContext | ||
|
||
dynamodb = DynamoDBPersistenceLayer(table_name="IdempotencyTable") | ||
config = IdempotencyConfig(event_key_jmespath="order_id") # see Choosing a payload subset section | ||
|
||
|
||
class OrderItem(BaseModel): | ||
sku: str | ||
description: str | ||
|
||
|
||
class Order(BaseModel): | ||
item: OrderItem | ||
order_id: int | ||
|
||
|
||
class OrderOutput(BaseModel): | ||
order_id: int | ||
|
||
|
||
@idempotent_function( | ||
data_keyword_argument="order", | ||
config=config, | ||
persistence_store=dynamodb, | ||
output_serializer=PydanticSerializer(model=OrderOutput), | ||
) | ||
def process_order(order: Order) -> OrderOutput: | ||
leandrodamascena marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return OrderOutput(order_id=order.order_id) | ||
|
||
|
||
def lambda_handler(event: dict, context: LambdaContext): | ||
config.register_lambda_context(context) # see Lambda timeouts section | ||
order_item = OrderItem(sku="fake", description="sample") | ||
order = Order(item=order_item, order_id=1) | ||
|
||
# `order` parameter must be called as a keyword argument to work | ||
process_order(order=order) |
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.