This commit is contained in:
2025-04-11 21:28:02 -03:00
parent 5b5e381191
commit 1b2ebcfb99
6 changed files with 107 additions and 62 deletions

View File

@@ -92,6 +92,7 @@ if __name__ == '__main__':
for file in tqdm(jsonl_files, desc='Processing files'): for file in tqdm(jsonl_files, desc='Processing files'):
with jsonlines.open(f'seeds/{file}') as lines: with jsonlines.open(f'seeds/{file}') as lines:
table_name = file.removesuffix('.jsonl') table_name = file.removesuffix('.jsonl')
reader = jsonlines.Reader(fp)
for line in tqdm(lines, desc=f'Processing lines in {file}'): for line in tqdm(lines, desc=f'Processing lines in {file}'):
put_item(line, table_name, dynamodb_client) put_item(line, table_name, dynamodb_client)

View File

@@ -12,6 +12,7 @@ from uuid import UUID
from aws_lambda_powertools import Logger 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 glom import glom
from .dateutils import now, timestamp from .dateutils import now, timestamp
from .funcs import omit from .funcs import omit
@@ -58,21 +59,20 @@ if TYPE_CHECKING:
@dataclass @dataclass
class ComposeKey(str): class ComposeKey(str):
"""Creates a composite key by joining string parts with a specified delimiter.
If a prefix is provided, it is added at the beginning of the key parts.
Example
-------
>>> ComposeKey(('abc', 'xyz'), prefix='examples', delimiter='#')
'examples#abc#xyz'
"""
keyparts: str | tuple[str, ...] keyparts: str | tuple[str, ...]
prefix: str | None = None prefix: str | None = None
delimiter: str = '#' delimiter: str = '#'
else: else:
class ComposeKey(str): class ComposeKey(str):
"""Creates a composite key by joining string parts with a specified delimiter.
If a prefix is provided, it is added at the beginning of the key parts.
Example
-------
ComposeKey(('abc', 'xyz'), prefix='examples', delimiter='#')
"""
def __new__( def __new__(
cls, cls,
keyparts: str | tuple[str, ...], keyparts: str | tuple[str, ...],
@@ -131,17 +131,31 @@ if TYPE_CHECKING:
class SortKey(str): class SortKey(str):
sk: str sk: str
table_name: str | None = None table_name: str | None = None
path_spec: str | None = None
else: else:
class SortKey(str): class SortKey(str):
def __new__(cls, sk: str, *, table_name: str | None = None) -> str: def __new__(
cls,
sk: str,
*,
table_name: str | None = None,
path_spec: str | None = None,
) -> str:
return super().__new__(cls, sk) return super().__new__(cls, sk)
def __init__(self, sk: str, *, table_name: str | None = None) -> None: def __init__(
self,
sk: str,
*,
table_name: str | None = None,
path_spec: str | None = None,
) -> None:
# __init__ is used to store the parameters for later reference. # __init__ is used to store the parameters for later reference.
# For immutable types like str, __init__ cannot change the instance's value. # For immutable types like str, __init__ cannot change the instance's value.
self.sk = sk self.sk = sk
self.table_name = table_name self.table_name = table_name
self.path_spec = path_spec
@dataclass @dataclass
@@ -149,9 +163,9 @@ class TransactKey:
""" """
Example Example
------- -------
>>> TransactKey('e9bb7dc6-c7b2-4d34-8931-d298353758ec') TransactKey('e9bb7dc6-c7b2-4d34-8931-d298353758ec')
... + SortKey('0') + SortKey('0')
... + SortKey('tenant') + SortKey('tenant')
""" """
pk: str pk: str
@@ -600,15 +614,15 @@ class DynamoDBCollection:
key: Key key: Key
Key of the item to be retrieved. Key of the item to be retrieved.
path_spec: str, optional path_spec: str, optional
A path specification for nested data extraction, default is None. A path specification for nested data extraction.
raise_on_error: bool, optional raise_on_error: bool, optional
If True, raises an exception when the item is not found, default is True. If True, raises an exception when the item is not found.
exception_cls: Type[Exception], optional exception_cls: Type[Exception], optional
Exception class to be used if the item is not found, default is MissingError. Exception class to be used if the item is not found.
default: Any, optional default: Any, optional
Default value returned if the item is not found, default is None. Default value returned if the item is not found.
delimiter: str, optional delimiter: str, optional
Delimiter used in key composition, default is '#'. Delimiter used in key composition.
Returns Returns
------- -------
@@ -647,7 +661,7 @@ class DynamoDBCollection:
key: Key key: Key
Key for the item to be inserted or updated. Key for the item to be inserted or updated.
ttl: int or datetime, optional ttl: int or datetime, optional
Time-to-live for the item, specified as a timestamp integer or datetime object, default is None. Time-to-live for the item, specified as a timestamp integer or datetime object.
**kwargs **kwargs
Additional data to be stored with the item. Additional data to be stored with the item.
@@ -691,11 +705,11 @@ class DynamoDBCollection:
key: Key key: Key
Key of the item to be deleted. Key of the item to be deleted.
cond_expr: str, optional cond_expr: str, optional
Conditional expression for deletion, default is None. Conditional expression for deletion.
expr_attr_names: dict, optional expr_attr_names: dict, optional
Mapping of attribute names for the expression, default is None. Mapping of attribute names for the expression.
expr_attr_values: dict, optional expr_attr_values: dict, optional
Mapping of attribute values for the expression, default is None. Mapping of attribute values for the expression.
Returns Returns
------- -------
@@ -720,7 +734,10 @@ class DynamoDBCollection:
------- -------
**Get items using chained sort keys** **Get items using chained sort keys**
key = TransactKey('b3511b5a-cb32-4833-a373-f8223f2088d4') + SortKey('sk-1') + SortKey('sk-2') key = (
TransactKey('b3511b5a-cb32-4833-a373-f8223f2088d4')
+ SortKey('sk-1') + SortKey('sk-2')
)
collect = DynamoDBCollection(...) collect = DynamoDBCollection(...)
items = collect.get_items(key) items = collect.get_items(key)
@@ -734,7 +751,6 @@ class DynamoDBCollection:
Determines whether the first nested item in the transaction result should be flattened, Determines whether the first nested item in the transaction result should be flattened,
i.e., extracted to serve as the primary item at the top level of the returned dict. i.e., extracted to serve as the primary item at the top level of the returned dict.
If True, the nested item is promoted to the top level. If True, the nested item is promoted to the top level.
The default is True.
Returns Returns
------- -------
@@ -764,9 +780,11 @@ class DynamoDBCollection:
else: else:
head, tail = {}, items head, tail = {}, items
return head | { def _getin(sk: SortKey, v: dict) -> dict:
k: omit((PK, SK), item) for k, item in zip(sortkeys, tail) if item v = omit((PK, SK), v)
} return glom(v, sk.path_spec) if sk.path_spec else v
return head | {k: _getin(k, item) for k, item in zip(sortkeys, tail) if item}
def query( def query(
self, self,
@@ -804,17 +822,17 @@ class DynamoDBCollection:
key: PartitionKey or KeyPair key: PartitionKey or KeyPair
Partition key or Key pair used for the query. Partition key or Key pair used for the query.
expr_attr_name: dict, optional expr_attr_name: dict, optional
Additional mapping for attribute names, default is {}. Additional mapping for attribute names.
expr_attr_values: dict, optional expr_attr_values: dict, optional
Additional mapping for attribute values, default is {}. Additional mapping for attribute values.
start_key: str, optional start_key: str, optional
Starting key for pagination, default is None. Starting key for pagination.
filter_expr: str, optional filter_expr: str, optional
Filter expression for the query, default is None. Filter expression for the query.
index_forward: bool, optional index_forward: bool, optional
Order of the results; True for ascending order, default is False. Order of the results; True for ascending order.
limit: int, optional limit: int, optional
Maximum number of items to return, default is LIMIT. Maximum number of items to return.
Returns Returns
------- -------

View File

@@ -4,8 +4,11 @@ theme:
name: "readthedocs" name: "readthedocs"
plugins: plugins:
- mkdocstrings - mkdocstrings:
handlers:
python:
options:
docstring_style: numpy
nav: nav:
- index.md - index.md
- API reference: reference.md - API reference: reference.md

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "layercake" name = "layercake"
version = "0.2.1" version = "0.2.5"
description = "Packages shared dependencies to optimize deployment and ensure consistency across functions." description = "Packages shared dependencies to optimize deployment and ensure consistency across functions."
readme = "README.md" readme = "README.md"
authors = [ authors = [
@@ -23,6 +23,7 @@ dependencies = [
"meilisearch>=0.34.0", "meilisearch>=0.34.0",
"arnparse>=0.0.2", "arnparse>=0.0.2",
"weasyprint>=65.0", "weasyprint>=65.0",
"uuid-utils>=0.10.0",
] ]
[dependency-groups] [dependency-groups]

View File

@@ -249,7 +249,7 @@ def test_collection_get_items(
doc = collect.get_items( doc = collect.get_items(
TransactKey('cJtK9SsnJhKPyxESe7g3DG') TransactKey('cJtK9SsnJhKPyxESe7g3DG')
+ SortKey('0') + SortKey('0')
+ SortKey('billing_policy') + SortKey('billing_policy', path_spec='payment_method')
+ SortKey('payment_policy'), + SortKey('payment_policy'),
) )
@@ -259,7 +259,7 @@ def test_collection_get_items(
'id': 'cJtK9SsnJhKPyxESe7g3DG', 'id': 'cJtK9SsnJhKPyxESe7g3DG',
'cnpj': '15608435000190', 'cnpj': '15608435000190',
'email': 'org+15608435000190@users.noreply.betaeducacao.com.br', 'email': 'org+15608435000190@users.noreply.betaeducacao.com.br',
'billing_policy': {'billing_day': Decimal('1'), 'payment_method': 'PIX'}, 'billing_policy': 'PIX',
'payment_policy': {'due_days': Decimal('90')}, 'payment_policy': {'due_days': Decimal('90')},
} }

24
layercake/uv.lock generated
View File

@@ -600,7 +600,7 @@ wheels = [
[[package]] [[package]]
name = "layercake" name = "layercake"
version = "0.2.0" version = "0.2.4"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "arnparse" }, { name = "arnparse" },
@@ -617,6 +617,7 @@ dependencies = [
{ name = "pydantic-extra-types" }, { name = "pydantic-extra-types" },
{ name = "pytz" }, { name = "pytz" },
{ name = "requests" }, { name = "requests" },
{ name = "uuid-utils" },
{ name = "weasyprint" }, { name = "weasyprint" },
] ]
@@ -646,6 +647,7 @@ requires-dist = [
{ name = "pydantic-extra-types", specifier = ">=2.10.3" }, { name = "pydantic-extra-types", specifier = ">=2.10.3" },
{ name = "pytz", specifier = ">=2025.1" }, { name = "pytz", specifier = ">=2025.1" },
{ name = "requests", specifier = ">=2.32.3" }, { name = "requests", specifier = ">=2.32.3" },
{ name = "uuid-utils", specifier = ">=0.10.0" },
{ name = "weasyprint", specifier = ">=65.0" }, { name = "weasyprint", specifier = ">=65.0" },
] ]
@@ -1277,6 +1279,26 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 },
] ]
[[package]]
name = "uuid-utils"
version = "0.10.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/66/0a/cbdb2eb4845dafeb632d02a18f47b02f87f2ce4f25266f5e3c017976ce89/uuid_utils-0.10.0.tar.gz", hash = "sha256:5db0e1890e8f008657ffe6ded4d9459af724ab114cfe82af1557c87545301539", size = 18828 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/44/54/9d22fa16b19e5d1676eba510f08a9c458d96e2a62ff2c8ebad64251afb18/uuid_utils-0.10.0-cp39-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d5a4508feefec62456cd6a41bcdde458d56827d908f226803b886d22a3d5e63", size = 573006 },
{ url = "https://files.pythonhosted.org/packages/08/8e/f895c6e52aa603e521fbc13b8626ba5dd99b6e2f5a55aa96ba5b232f4c53/uuid_utils-0.10.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:dbefc2b9113f9dfe56bdae58301a2b3c53792221410d422826f3d1e3e6555fe7", size = 292543 },
{ url = "https://files.pythonhosted.org/packages/b6/58/cc4834f377a5e97d6e184408ad96d13042308de56643b6e24afe1f6f34df/uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffc49c33edf87d1ec8112a9b43e4cf55326877716f929c165a2cc307d31c73d5", size = 323340 },
{ url = "https://files.pythonhosted.org/packages/37/e3/6aeddf148f6a7dd7759621b000e8c85382ec83f52ae79b60842d1dc3ab6b/uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0636b6208f69d5a4e629707ad2a89a04dfa8d1023e1999181f6830646ca048a1", size = 329653 },
{ url = "https://files.pythonhosted.org/packages/0c/00/dd6c2164ace70b7b1671d9129267df331481d7d1e5f9c5e6a564f07953f6/uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bc06452856b724df9dedfc161c3582199547da54aeb81915ec2ed54f92d19b0", size = 365471 },
{ url = "https://files.pythonhosted.org/packages/b4/e7/0ab8080fcae5462a7b5e555c1cef3d63457baffb97a59b9bc7b005a3ecb1/uuid_utils-0.10.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:263b2589111c61decdd74a762e8f850c9e4386fb78d2cf7cb4dfc537054cda1b", size = 325844 },
{ url = "https://files.pythonhosted.org/packages/73/39/52d94e9ef75b03f44b39ffc6ac3167e93e74ef4d010a93d25589d9f48540/uuid_utils-0.10.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a558db48b7096de6b4d2d2210d82bba8586a6d55f99106b03bb7d01dc5c5bcd6", size = 344389 },
{ url = "https://files.pythonhosted.org/packages/7c/29/4824566f62666238290d99c62a58e4ab2a8b9cf2eccf94cebd9b3359131e/uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:807465067f3c892514230326ac71a79b28a8dfe2c88ecd2d5675fc844f3c76b5", size = 510078 },
{ url = "https://files.pythonhosted.org/packages/5e/8f/bbcc7130d652462c685f0d3bd26bb214b754215b476340885a4cb50fb89a/uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:57423d4a2b9d7b916de6dbd75ba85465a28f9578a89a97f7d3e098d9aa4e5d4a", size = 515937 },
{ url = "https://files.pythonhosted.org/packages/23/f8/34e0c00f5f188604d336713e6a020fcf53b10998e8ab24735a39ab076740/uuid_utils-0.10.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:76d8d660f18ff6b767e319b1b5f927350cd92eafa4831d7ef5b57fdd1d91f974", size = 494111 },
{ url = "https://files.pythonhosted.org/packages/1a/52/b7f0066cc90a7a9c28d54061ed195cd617fde822e5d6ac3ccc88509c3c44/uuid_utils-0.10.0-cp39-abi3-win32.whl", hash = "sha256:6c11a71489338837db0b902b75e1ba7618d5d29f05fde4f68b3f909177dbc226", size = 173520 },
{ url = "https://files.pythonhosted.org/packages/8b/15/f04f58094674d333974243fb45d2c740cf4b79186fb707168e57943c84a3/uuid_utils-0.10.0-cp39-abi3-win_amd64.whl", hash = "sha256:11c55ae64f6c0a7a0c741deae8ca2a4eaa11e9c09dbb7bec2099635696034cf7", size = 182965 },
]
[[package]] [[package]]
name = "watchdog" name = "watchdog"
version = "6.0.0" version = "6.0.0"