add ttl
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from ipaddress import IPv4Address
|
from ipaddress import IPv4Address
|
||||||
from typing import Any, Type
|
from typing import Any, Type
|
||||||
@@ -6,6 +7,10 @@ from aws_lambda_powertools import Logger
|
|||||||
from boto3.dynamodb.types import TypeDeserializer, TypeSerializer
|
from boto3.dynamodb.types import TypeDeserializer, TypeSerializer
|
||||||
from botocore.exceptions import ClientError
|
from botocore.exceptions import ClientError
|
||||||
|
|
||||||
|
from .dateutils import now, timestamp
|
||||||
|
|
||||||
|
TZ = os.getenv('TZ', 'UTC')
|
||||||
|
|
||||||
logger = Logger(__name__)
|
logger = Logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@@ -432,6 +437,20 @@ class DynamoDBPersistenceLayer:
|
|||||||
|
|
||||||
|
|
||||||
class DynamoDBCollection:
|
class DynamoDBCollection:
|
||||||
|
"""
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
Get an item using a composed sort key
|
||||||
|
|
||||||
|
collect = DynamoDBCollection(...)
|
||||||
|
collect.get_item(
|
||||||
|
key=KeyPair(
|
||||||
|
pk='5OxmMjL-ujoR5IMGegQz',
|
||||||
|
sk=Key('sergio@somosbeta.com.br', prefix='emails'),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
|
||||||
class MissingError(ValueError):
|
class MissingError(ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -439,6 +458,7 @@ class DynamoDBCollection:
|
|||||||
self,
|
self,
|
||||||
persistence_layer: DynamoDBPersistenceLayer,
|
persistence_layer: DynamoDBPersistenceLayer,
|
||||||
exception_cls: Type[ValueError] = MissingError,
|
exception_cls: Type[ValueError] = MissingError,
|
||||||
|
tz: str = TZ,
|
||||||
) -> None:
|
) -> None:
|
||||||
if not issubclass(exception_cls, ValueError):
|
if not issubclass(exception_cls, ValueError):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
@@ -447,6 +467,7 @@ class DynamoDBCollection:
|
|||||||
|
|
||||||
self.persistence_layer = persistence_layer
|
self.persistence_layer = persistence_layer
|
||||||
self.exception_cls = exception_cls
|
self.exception_cls = exception_cls
|
||||||
|
self.tz = tz
|
||||||
|
|
||||||
def get_item(
|
def get_item(
|
||||||
self,
|
self,
|
||||||
@@ -468,3 +489,28 @@ class DynamoDBCollection:
|
|||||||
return glom(data, path_spec, default=default)
|
return glom(data, path_spec, default=default)
|
||||||
|
|
||||||
return data or default
|
return data or default
|
||||||
|
|
||||||
|
def put_item(
|
||||||
|
self, key: KeyPair, ttl: int | datetime | None = None, **kwargs: Any
|
||||||
|
) -> bool:
|
||||||
|
now_ = now(self.tz)
|
||||||
|
|
||||||
|
if isinstance(ttl, int):
|
||||||
|
kwargs.update(
|
||||||
|
{
|
||||||
|
'ttl': ttl,
|
||||||
|
'ttl_date': datetime.fromtimestamp(ttl, now_.tzinfo),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if isinstance(ttl, datetime):
|
||||||
|
kwargs.update(
|
||||||
|
{
|
||||||
|
'ttl': timestamp(ttl),
|
||||||
|
'ttl_date': ttl,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.persistence_layer.put_item(
|
||||||
|
item=key | {'create_date': now_} | kwargs
|
||||||
|
)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from ipaddress import IPv4Address
|
|||||||
import pytest
|
import pytest
|
||||||
from botocore.exceptions import ClientError
|
from botocore.exceptions import ClientError
|
||||||
|
|
||||||
|
from layercake.dateutils import ttl
|
||||||
from layercake.dynamodb import (
|
from layercake.dynamodb import (
|
||||||
DynamoDBCollection,
|
DynamoDBCollection,
|
||||||
DynamoDBPersistenceLayer,
|
DynamoDBPersistenceLayer,
|
||||||
@@ -58,29 +59,30 @@ def test_transact_write_items(
|
|||||||
dynamodb_persistence_layer.transact_write_items(transact)
|
dynamodb_persistence_layer.transact_write_items(transact)
|
||||||
|
|
||||||
|
|
||||||
def test_collection(
|
def test_collection_get_item(
|
||||||
dynamodb_seeds,
|
dynamodb_seeds,
|
||||||
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
||||||
):
|
):
|
||||||
collect = DynamoDBCollection(dynamodb_persistence_layer)
|
collect = DynamoDBCollection(dynamodb_persistence_layer)
|
||||||
tenant_item = collect.get_item(
|
data_notfound = collect.get_item(
|
||||||
key=KeyPair(
|
key=KeyPair(
|
||||||
pk='5OxmMjL-ujoR5IMGegQz',
|
pk='5OxmMjL-ujoR5IMGegQz',
|
||||||
sk=Key('tenant'),
|
sk='tenant',
|
||||||
),
|
),
|
||||||
raise_if_missing=False,
|
raise_if_missing=False,
|
||||||
default={},
|
default={},
|
||||||
)
|
)
|
||||||
assert tenant_item == {}
|
assert data_notfound == {}
|
||||||
|
|
||||||
email_item = collect.get_item(
|
# This item was added from seeds
|
||||||
|
data = collect.get_item(
|
||||||
key=KeyPair(
|
key=KeyPair(
|
||||||
pk='5OxmMjL-ujoR5IMGegQz',
|
pk='5OxmMjL-ujoR5IMGegQz',
|
||||||
sk=Key('sergio@somosbeta.com.br', prefix='emails'),
|
sk=Key('sergio@somosbeta.com.br', prefix='emails'),
|
||||||
),
|
),
|
||||||
default={},
|
default={},
|
||||||
)
|
)
|
||||||
assert email_item == {
|
assert data == {
|
||||||
'email_verified': True,
|
'email_verified': True,
|
||||||
'mx_record_exists': True,
|
'mx_record_exists': True,
|
||||||
'sk': 'emails#sergio@somosbeta.com.br',
|
'sk': 'emails#sergio@somosbeta.com.br',
|
||||||
@@ -92,3 +94,30 @@ def test_collection(
|
|||||||
|
|
||||||
with pytest.raises(DynamoDBCollection.MissingError):
|
with pytest.raises(DynamoDBCollection.MissingError):
|
||||||
collect.get_item(key=KeyPair('5OxmMjL-ujoR5IMGegQz', 'notfound'))
|
collect.get_item(key=KeyPair('5OxmMjL-ujoR5IMGegQz', 'notfound'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_collection_put_item(
|
||||||
|
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
||||||
|
):
|
||||||
|
collect = DynamoDBCollection(dynamodb_persistence_layer)
|
||||||
|
|
||||||
|
assert collect.put_item(
|
||||||
|
key=KeyPair(
|
||||||
|
'5OxmMjL-ujoR5IMGegQz',
|
||||||
|
Key('6d1044d5-18c5-437c-9219-fc2ace7e5ebc', prefix='orgs'),
|
||||||
|
),
|
||||||
|
name='Beta Educação',
|
||||||
|
ttl=ttl(days=3),
|
||||||
|
)
|
||||||
|
|
||||||
|
data = collect.get_item(
|
||||||
|
key=KeyPair(
|
||||||
|
pk='5OxmMjL-ujoR5IMGegQz',
|
||||||
|
sk=Key('6d1044d5-18c5-437c-9219-fc2ace7e5ebc', prefix='orgs'),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert data['sk'] == 'orgs#6d1044d5-18c5-437c-9219-fc2ace7e5ebc'
|
||||||
|
assert 'name' in data
|
||||||
|
assert 'ttl' in data
|
||||||
|
assert 'ttl_date' in data
|
||||||
|
|||||||
Reference in New Issue
Block a user