Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9a8164e

Browse files
author
Lucas McDonald
committedMay 1, 2025·
ruff
1 parent c20581f commit 9a8164e

File tree

12 files changed

+233
-195
lines changed

12 files changed

+233
-195
lines changed
 

‎DynamoDbEncryption/runtimes/python/pyproject.toml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ exclude = [
6464
line-length=120
6565
indent-width=4
6666
target-version = "py311"
67+
68+
[tool.ruff.lint]
69+
# Choose linting tools
6770
select = [
6871
# pycodestyle: spacing, line length
6972
"E",
@@ -73,11 +76,14 @@ select = [
7376
"I",
7477
# pydocstyle: docstring style
7578
"D",
76-
# pyupgrade: auto-upgrade syntax if possible
77-
"UP",
79+
]
80+
# Ignore incompatible linting options
81+
ignore=[
82+
"D203", # `incorrect-blank-line-before-class`; incompatible with `no-blank-line-before-class` (D211)
83+
"D212", # `multi-line-summary-first-line`; incompatible with `multi-line-summary-second-line` (D213)
7884
]
7985

80-
[tool.ruff.per-file-ignores]
86+
[tool.ruff.lint.per-file-ignores]
8187
"src/aws_dbesdk_dynamodb/internal/*" = [
8288
# Ignore all "public"-related linting errors for internal modules
8389
"D100", "D101", "D102", "D103", "D104", "D105", "D106", "D107",

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0
3+
"""Initialization code for AWS DBESDK for DynamoDB."""
34

45
# Initialize generated Dafny, then initialize externs
56
# Disable sorting imports; this order initializes code in the required order
67
# (generated Dafny, then externs)
7-
# ruff: noqa: I001
8+
# ruff: noqa: I001, F401
89
from .internaldafny.generated import module_
910
from .internaldafny import extern
1011

@@ -28,6 +29,8 @@
2829
2930
For DBESDK DynamoDB, change the DynamoDB context to treat "Rounded" as acceptable.
3031
"""
32+
# Keep these imports down here for clarity
33+
# ruff: noqa: E402
3134
from decimal import Rounded
3235

3336
import boto3.dynamodb.types

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/encrypted/boto3_interface.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0
3+
"""Interface for encrypted boto3 interfaces."""
34
import abc
45
from abc import abstractmethod
56
from typing import Any
@@ -11,7 +12,8 @@ class EncryptedBotoInterface(abc.ABC):
1112
def _copy_sdk_response_to_dbesdk_response(
1213
self, sdk_response: dict[str, Any], dbesdk_response: dict[str, Any]
1314
) -> dict[str, Any]:
14-
"""Copy any missing fields from the SDK response to the DBESDK response.
15+
"""
16+
Copy any missing fields from the SDK response to the DBESDK response.
1517
1618
Args:
1719
sdk_response: The raw SDK response
@@ -32,7 +34,8 @@ def _boto_client_attr_name(self) -> str:
3234
"""Name of the attribute containing the underlying boto3 client."""
3335

3436
def __getattr__(self, name: str) -> Any:
35-
"""Delegate unknown attributes to the underlying client.
37+
"""
38+
Delegate unknown attributes to the underlying client.
3639
3740
Args:
3841
name: The name of the attribute to get

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/encrypted/client.py

Lines changed: 69 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737

3838

3939
class EncryptedClient(EncryptedBotoInterface):
40-
"""Wrapper for a boto3 DynamoDB client that transparently encrypts/decrypts items.
40+
"""
41+
Wrapper for a boto3 DynamoDB client that transparently encrypts/decrypts items.
4142
4243
This class implements the complete boto3 DynamoDB client API, allowing it to serve as a
4344
drop-in replacement that transparently handles encryption and decryption of items.
@@ -74,14 +75,17 @@ def __init__(
7475
encryption_config: DynamoDbTablesEncryptionConfig,
7576
expect_standard_dictionaries: bool | None = False,
7677
):
77-
"""Parameters
78-
client (botocore.client.BaseClient): Initialized boto3 DynamoDB client
79-
encryption_config (DynamoDbTablesEncryptionConfig): Initialized DynamoDbTablesEncryptionConfig
80-
expect_standard_dictionaries (Optional[bool]): Does the underlying boto3 client expect items to be standard Python
81-
dictionaries? This should only be set to True if you are using a client obtained
82-
from a service resource or table resource (ex: `table.meta.client`).
83-
If this is True, EncryptedClient will expect item-like shapes to be
84-
standard Python dictionaries (default: False).
78+
"""
79+
Create an EncryptedClient object.
80+
81+
Args:
82+
client (botocore.client.BaseClient): Initialized boto3 DynamoDB client
83+
encryption_config (DynamoDbTablesEncryptionConfig): Initialized DynamoDbTablesEncryptionConfig
84+
expect_standard_dictionaries (Optional[bool]): Does the underlying boto3 client expect items
85+
to be standard Python dictionaries? This should only be set to True if you are using a
86+
client obtained from a service resource or table resource (ex: `table.meta.client`).
87+
If this is True, EncryptedClient will expect item-like shapes to be
88+
standard Python dictionaries (default: False).
8589
8690
"""
8791
self._client = client
@@ -92,21 +96,17 @@ def __init__(
9296
self._client_to_resource_shape_converter = ClientShapeToResourceShapeConverter(delete_table_name=False)
9397

9498
def put_item(self, **kwargs) -> dict[str, Any]:
95-
"""Puts a single item in a table. Encrypts the item before writing to DynamoDB.
99+
"""
100+
Put a single item to a table. Encrypts the item before writing to DynamoDB.
96101
97102
The parameters and return value match the boto3 DynamoDB put_item API:
98103
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/put_item.html
99104
100105
Args:
101-
TableName (str): Name of the table to write to
102-
Item (dict): A map of attribute name/value pairs to write to the table
103-
104-
These are only a list of required args; see boto3 docs for complete request structure.
106+
**kwargs: Keyword arguments to pass to the operation. These match the boto3 put_item API parameters.
105107
106108
Returns:
107-
dict: The response from DynamoDB.
108-
109-
See boto3 docs for complete response structure.
109+
dict: The response from DynamoDB. This matches the boto3 put_item API response.
110110
111111
"""
112112
return self._client_operation_logic(
@@ -123,21 +123,17 @@ def put_item(self, **kwargs) -> dict[str, Any]:
123123
)
124124

125125
def get_item(self, **kwargs) -> dict[str, Any]:
126-
"""Gets a single item from a table. Decrypts the item after reading from DynamoDB.
126+
"""
127+
Get a single item from a table. Decrypts the item after reading from DynamoDB.
127128
128129
The parameters and return value match the boto3 DynamoDB get_item API:
129130
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/get_item.html
130131
131132
Args:
132-
TableName (str): Name of the table to read from
133-
Key (dict): The primary key of the item to retrieve
134-
135-
These are only a list of required args; see boto3 docs for complete request structure.
133+
**kwargs: Keyword arguments to pass to the operation. These match the boto3 get_item API parameters.
136134
137135
Returns:
138-
dict: The response from DynamoDB containing the requested item.
139-
140-
See boto3 docs for complete response structure.
136+
dict: The response from DynamoDB. This matches the boto3 get_item API response.
141137
142138
"""
143139
return self._client_operation_logic(
@@ -154,20 +150,17 @@ def get_item(self, **kwargs) -> dict[str, Any]:
154150
)
155151

156152
def query(self, **kwargs) -> dict[str, Any]:
157-
"""Queries items from a table or index. Decrypts any returned items.
153+
"""
154+
Query items from a table or index. Decrypts any returned items.
158155
159156
The parameters and return value match the boto3 DynamoDB query API:
160157
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/query.html
161158
162159
Args:
163-
TableName (str): Name of the table to query
164-
165-
These are only a list of required args; see boto3 docs for complete request structure.
160+
**kwargs: Keyword arguments to pass to the operation. These match the boto3 query API parameters.
166161
167162
Returns:
168-
dict: The response from DynamoDB containing the matching items.
169-
170-
See boto3 docs for complete response structure.
163+
dict: The response from DynamoDB. This matches the boto3 query API response.
171164
172165
"""
173166
return self._client_operation_logic(
@@ -184,20 +177,17 @@ def query(self, **kwargs) -> dict[str, Any]:
184177
)
185178

186179
def scan(self, **kwargs) -> dict[str, Any]:
187-
"""Scans an entire table or index. Decrypts any returned items.
180+
"""
181+
Scan an entire table or index. Decrypts any returned items.
188182
189183
The parameters and return value match the boto3 DynamoDB scan API:
190184
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/scan.html
191185
192186
Args:
193-
TableName (str): Name of the table to scan
194-
195-
These are only a list of required args; see boto3 docs for complete request structure.
187+
**kwargs: Keyword arguments to pass to the operation. These match the boto3 scan API parameters.
196188
197189
Returns:
198-
dict: The response from DynamoDB containing the scanned items.
199-
200-
See boto3 docs for complete response structure.
190+
dict: The response from DynamoDB. This matches the boto3 scan API response.
201191
202192
"""
203193
return self._client_operation_logic(
@@ -214,21 +204,19 @@ def scan(self, **kwargs) -> dict[str, Any]:
214204
)
215205

216206
def batch_write_item(self, **kwargs) -> dict[str, Any]:
217-
"""Puts or deletes multiple items in one or more tables.
207+
"""
208+
Put or delete multiple items in one or more tables.
209+
218210
For put operations, encrypts items before writing.
219211
220212
The parameters and return value match the boto3 DynamoDB batch_write_item API:
221213
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/batch_write_item.html
222214
223215
Args:
224-
RequestItems (dict): A map of table names to lists of write operations
225-
226-
These are only a list of required args; see boto3 docs for complete request structure.
216+
**kwargs: Keyword arguments to pass to the operation. These match the boto3 batch_write_item API parameters.
227217
228218
Returns:
229-
dict: The response from DynamoDB.
230-
231-
See boto3 docs for complete response structure.
219+
dict: The response from DynamoDB. This matches the boto3 batch_write_item API response.
232220
233221
"""
234222
return self._client_operation_logic(
@@ -245,20 +233,17 @@ def batch_write_item(self, **kwargs) -> dict[str, Any]:
245233
)
246234

247235
def batch_get_item(self, **kwargs) -> dict[str, Any]:
248-
"""Gets multiple items from one or more tables. Decrypts any returned items.
236+
"""
237+
Get multiple items from one or more tables. Decrypts any returned items.
249238
250239
The parameters and return value match the boto3 DynamoDB batch_get_item API:
251240
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/batch_get_item.html
252241
253242
Args:
254-
RequestItems (dict): A map of table names to lists of keys to retrieve
255-
256-
These are only a list of required args; see boto3 docs for complete request structure.
243+
**kwargs: Keyword arguments to pass to the operation. These match the boto3 batch_get_item API parameters.
257244
258245
Returns:
259-
dict: The response from DynamoDB containing the requested items.
260-
261-
See boto3 docs for complete response structure.
246+
dict: The response from DynamoDB. This matches the boto3 batch_get_item API response.
262247
263248
"""
264249
return self._client_operation_logic(
@@ -275,20 +260,18 @@ def batch_get_item(self, **kwargs) -> dict[str, Any]:
275260
)
276261

277262
def transact_get_items(self, **kwargs) -> dict[str, Any]:
278-
"""Gets multiple items in a single transaction. Decrypts any returned items.
263+
"""
264+
Get multiple items in a single transaction. Decrypts any returned items.
279265
280266
The parameters and return value match the boto3 DynamoDB transact_get_items API:
281267
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/transact_get_items.html
282268
283269
Args:
284-
TransactItems (list): List of operations to perform in the transaction
285-
286-
These are only a list of required args; see boto3 docs for complete request structure.
270+
**kwargs: Keyword arguments to pass to the operation. These match the boto3 transact_get_items API
271+
parameters.
287272
288273
Returns:
289-
dict: The response from DynamoDB containing the requested items.
290-
291-
See boto3 docs for complete response structure.
274+
dict: The response from DynamoDB. This matches the boto3 transact_get_items API response.
292275
293276
"""
294277
return self._client_operation_logic(
@@ -305,21 +288,20 @@ def transact_get_items(self, **kwargs) -> dict[str, Any]:
305288
)
306289

307290
def transact_write_items(self, **kwargs) -> dict[str, Any]:
308-
"""Performs multiple write operations in a single transaction.
291+
"""
292+
Perform multiple write operations in a single transaction.
293+
309294
For put operations, encrypts items before writing.
310295
311296
The parameters and return value match the boto3 DynamoDB transact_write_items API:
312297
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/transact_write_items.html
313298
314299
Args:
315-
TransactItems (list): List of operations to perform in the transaction
316-
317-
These are only a list of required args; see boto3 docs for complete request structure.
300+
**kwargs: Keyword arguments to pass to the operation. These match the boto3 transact_write_items API
301+
parameters.
318302
319303
Returns:
320-
dict: The response from DynamoDB.
321-
322-
See boto3 docs for complete response structure.
304+
dict: The response from DynamoDB. This matches the boto3 transact_write_items API response.
323305
324306
"""
325307
return self._client_operation_logic(
@@ -336,7 +318,8 @@ def transact_write_items(self, **kwargs) -> dict[str, Any]:
336318
)
337319

338320
def update_item(self, **kwargs):
339-
"""Not implemented. Raises NotImplementedError.
321+
"""
322+
Not implemented. Raises NotImplementedError.
340323
341324
Args:
342325
**kwargs: Any arguments passed to this method
@@ -348,8 +331,11 @@ def update_item(self, **kwargs):
348331
raise NotImplementedError('"update_item" is not yet implemented')
349332

350333
def get_paginator(self, operation_name: str) -> EncryptedPaginator | botocore.client.Paginator:
351-
"""Get a paginator from the underlying client. If the paginator requested is for
352-
"scan" or "query", the paginator returned will transparently decrypt the returned items.
334+
"""
335+
Get a paginator from the underlying client.
336+
337+
If the paginator requested is for "scan" or "query", the paginator returned will
338+
transparently decrypt the returned items.
353339
354340
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#paginators
355341
@@ -388,22 +374,27 @@ def _client_operation_logic(
388374
output_item_to_ddb_transform_method: callable,
389375
output_item_to_dict_transform_method: callable,
390376
) -> dict[str, Any]:
391-
"""Shared logic to interface between boto3 Client operation inputs and encryption transformers.
377+
"""
378+
Shared logic to interface between boto3 Client operation inputs and encryption transformers.
392379
393380
This captures the shared pattern to call encryption/decryption transformer code
394381
and boto3 Clients across all methods in this class.
395382
396383
Args:
397384
operation_input: The input to the operation
398-
input_item_to_ddb_transform_method: Method to transform input items from standard dictionaries to DynamoDB JSON
399-
input_item_to_dict_transform_method: Method to transform input items from DynamoDB JSON to standard dictionaries
385+
input_item_to_ddb_transform_method: Method to transform input items from standard dictionaries
386+
to DynamoDB JSON
387+
input_item_to_dict_transform_method: Method to transform input items from DynamoDB JSON
388+
to standard dictionaries
400389
input_transform_method: The method to transform the input for encryption
401390
input_transform_shape: The shape of the input transform
402391
output_transform_method: The method to transform the output for decryption
403392
output_transform_shape: The shape of the output transform
404393
client_method: The underlying client method to call
405-
output_item_to_ddb_transform_method: Method to transform output items from standard dictionaries to DynamoDB JSON
406-
output_item_to_dict_transform_method: Method to transform output items from DynamoDB JSON to standard dictionaries
394+
output_item_to_ddb_transform_method: Method to transform output items from standard dictionaries
395+
to DynamoDB JSON
396+
output_item_to_dict_transform_method: Method to transform output items from DynamoDB JSON
397+
to standard dictionaries
407398
408399
Returns:
409400
dict: The transformed response from DynamoDB
@@ -446,10 +437,11 @@ def _client_operation_logic(
446437

447438
@property
448439
def _boto_client_attr_name(self) -> str:
449-
"""Name of the attribute containing the underlying boto3 client.
440+
"""
441+
Name of the attribute containing the underlying boto3 client.
450442
451443
Returns:
452444
str: '_client'
453445
454446
"""
455-
return "_client"
447+
return "_client"

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/encrypted/item.py

Lines changed: 60 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ def __init__(
3030
self,
3131
item_encryptor_config: DynamoDbItemEncryptorConfig,
3232
):
33-
"""Create an ItemEncryptor.
33+
"""
34+
Create an ItemEncryptor.
3435
35-
Parameters
36-
----------
37-
item_encryptor_config (DynamoDbItemEncryptorConfig): Encryption configuration object.
36+
Args:
37+
item_encryptor_config (DynamoDbItemEncryptorConfig): Encryption configuration object.
3838
3939
"""
4040
self._internal_client = DynamoDbItemEncryptor(config=item_encryptor_config)
@@ -43,7 +43,8 @@ def encrypt_python_item(
4343
self,
4444
plaintext_dict_item: dict[str, Any],
4545
) -> EncryptItemOutput:
46-
"""Encrypt a Python dictionary.
46+
"""
47+
Encrypt a Python dictionary.
4748
4849
This method will transform the Python dictionary into DynamoDB JSON,
4950
encrypt the DynamoDB JSON,
@@ -59,19 +60,17 @@ def encrypt_python_item(
5960
(Alternatively, you can use this library's EncryptedTable or EncryptedResource interfaces
6061
to transparently encrypt items without an intermediary ItemEncryptor.)
6162
62-
Parameters
63-
----------
64-
plaintext_dict_item (dict[str, Any]): A standard Python dictionary.
63+
Args:
64+
plaintext_dict_item (dict[str, Any]): A standard Python dictionary.
6565
66-
Returns
67-
-------
68-
EncryptItemOutput: Structure containing the following fields:
69-
- `encrypted_item` (dict[str, Any]): The encrypted Python dictionary.
70-
**Note:** The item was encrypted as DynamoDB JSON, then transformed to a Python dictionary.
71-
- `parsed_header` (Optional[ParsedHeader]): The encrypted DynamoDB item's header (parsed `aws_dbe_head` value).
66+
Returns:
67+
EncryptItemOutput: Structure containing the following fields:
68+
- `encrypted_item` (dict[str, Any]): The encrypted Python dictionary.
69+
**Note:** The item was encrypted as DynamoDB JSON, then transformed to a Python dictionary.
70+
- `parsed_header` (Optional[ParsedHeader]): The encrypted DynamoDB item's header (parsed
71+
`aws_dbe_head` value).
7272
7373
Example:
74-
7574
>>> plaintext_item = {
7675
... 'some': 'data',
7776
... 'more': 5
@@ -90,7 +89,8 @@ def encrypt_dynamodb_item(
9089
self,
9190
plaintext_dynamodb_item: dict[str, dict[str, Any]],
9291
) -> EncryptItemOutput:
93-
"""Encrypt DynamoDB-formatted JSON.
92+
"""
93+
Encrypt DynamoDB-formatted JSON.
9494
9595
boto3 DynamoDB clients expect items formatted as DynamoDB JSON:
9696
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html
@@ -99,19 +99,16 @@ def encrypt_dynamodb_item(
9999
(Alternatively, you can use this library's EncryptedClient interface
100100
to transparently encrypt items without an intermediary ItemEncryptor.)
101101
102-
Parameters
103-
----------
104-
plaintext_dynamodb_item (dict[str, dict[str, Any]]): The item to encrypt formatted as DynamoDB JSON.
102+
Args:
103+
plaintext_dynamodb_item (dict[str, dict[str, Any]]): The item to encrypt formatted as DynamoDB JSON.
105104
106-
Returns
107-
-------
108-
EncryptItemOutput: Structure containing the following fields:
109-
- `encrypted_item` (dict[str, Any]): A dictionary containing the encrypted DynamoDB item
110-
formatted as DynamoDB JSON.
111-
- `parsed_header` (Optional[ParsedHeader]): The encrypted DynamoDB item's header (`aws_dbe_head` value).
105+
Returns:
106+
EncryptItemOutput: Structure containing the following fields:
107+
- `encrypted_item` (dict[str, Any]): A dictionary containing the encrypted DynamoDB item
108+
formatted as DynamoDB JSON.
109+
- `parsed_header` (Optional[ParsedHeader]): The encrypted DynamoDB item's header (`aws_dbe_head` value).
112110
113111
Example:
114-
115112
>>> plaintext_item = {
116113
... 'some': {'S': 'data'},
117114
... 'more': {'N': '5'}
@@ -127,24 +124,23 @@ def encrypt_item(
127124
self,
128125
encrypt_item_input: EncryptItemInput,
129126
) -> EncryptItemOutput:
130-
"""Encrypt a DynamoDB item.
127+
"""
128+
Encrypt a DynamoDB item.
131129
132130
The input item should contain a dictionary formatted as DynamoDB JSON:
133131
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html
134132
135-
Parameters
136-
----------
137-
encrypt_item_input (EncryptItemInput): Structure containing the following field:
138-
- `plaintext_item` (dict[str, Any]): The item to encrypt formatted as DynamoDB JSON.
133+
Args:
134+
encrypt_item_input (EncryptItemInput): Structure containing the following field:
135+
- `plaintext_item` (dict[str, Any]): The item to encrypt formatted as DynamoDB JSON.
139136
140-
Returns
141-
-------
142-
EncryptItemOutput: Structure containing the following fields:
143-
- `encrypted_item` (dict[str, Any]): The encrypted DynamoDB item formatted as DynamoDB JSON.
144-
- `parsed_header` (Optional[ParsedHeader]): The encrypted DynamoDB item's header (`aws_dbe_head` value).
137+
Returns:
138+
EncryptItemOutput: Structure containing the following fields:
139+
- `encrypted_item` (dict[str, Any]): The encrypted DynamoDB item formatted as DynamoDB JSON.
140+
- `parsed_header` (Optional[ParsedHeader]): The encrypted DynamoDB item's header
141+
(`aws_dbe_head` value).
145142
146143
Example:
147-
148144
>>> plaintext_item = {
149145
... 'some': {'S': 'data'},
150146
... 'more': {'N': '5'}
@@ -164,7 +160,8 @@ def decrypt_python_item(
164160
self,
165161
encrypted_dict_item: dict[str, Any],
166162
) -> DecryptItemOutput:
167-
"""Decrypt a Python dictionary.
163+
"""
164+
Decrypt a Python dictionary.
168165
169166
This method will transform the Python dictionary into DynamoDB JSON,
170167
decrypt the DynamoDB JSON,
@@ -180,19 +177,17 @@ def decrypt_python_item(
180177
(Alternatively, you can use this library's EncryptedTable or EncryptedResource interfaces
181178
to transparently decrypt items without an intermediary ItemEncryptor.)
182179
183-
Parameters
184-
----------
185-
encrypted_dict_item (dict[str, Any]): A standard Python dictionary with encrypted values.
180+
Args:
181+
encrypted_dict_item (dict[str, Any]): A standard Python dictionary with encrypted values.
186182
187-
Returns
188-
-------
189-
DecryptItemOutput: Structure containing the following fields:
190-
- `plaintext_item` (dict[str, Any]): The decrypted Python dictionary.
191-
**Note:** The item was decrypted as DynamoDB JSON, then transformed to a Python dictionary.
192-
- `parsed_header` (Optional[ParsedHeader]): The encrypted DynamoDB item's header (parsed `aws_dbe_head` value).
183+
Returns:
184+
DecryptItemOutput: Structure containing the following fields:
185+
- `plaintext_item` (dict[str, Any]): The decrypted Python dictionary.
186+
**Note:** The item was decrypted as DynamoDB JSON, then transformed to a Python dictionary.
187+
- `parsed_header` (Optional[ParsedHeader]): The encrypted DynamoDB item's header
188+
(parsed `aws_dbe_head` value).
193189
194190
Example:
195-
196191
>>> encrypted_item = {
197192
... 'some': b'ENCRYPTED_DATA',
198193
... 'more': b'ENCRYPTED_DATA',
@@ -211,7 +206,8 @@ def decrypt_dynamodb_item(
211206
self,
212207
encrypted_dynamodb_item: dict[str, dict[str, Any]],
213208
) -> DecryptItemOutput:
214-
"""Decrypt DynamoDB-formatted JSON.
209+
"""
210+
Decrypt DynamoDB-formatted JSON.
215211
216212
boto3 DynamoDB clients return items formatted as DynamoDB JSON:
217213
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html
@@ -220,18 +216,15 @@ def decrypt_dynamodb_item(
220216
(Alternatively, you can use this library's EncryptedClient interface
221217
to transparently decrypt items without an intermediary ItemEncryptor.)
222218
223-
Parameters
224-
----------
225-
encrypted_ddb_item (dict[str, dict[str, Any]]): The item to decrypt formatted as DynamoDB JSON.
219+
Args:
220+
encrypted_dynamodb_item (dict[str, dict[str, Any]]): The item to decrypt formatted as DynamoDB JSON.
226221
227-
Returns
228-
-------
229-
DecryptItemOutput: Structure containing the following fields:
230-
- `plaintext_item` (dict[str, Any]): The plaintext DynamoDB item formatted as DynamoDB JSON.
231-
- `parsed_header` (Optional[ParsedHeader]): The decrypted DynamoDB item's header (`aws_dbe_head` value).
222+
Returns:
223+
DecryptItemOutput: Structure containing the following fields:
224+
- `plaintext_item` (dict[str, Any]): The plaintext DynamoDB item formatted as DynamoDB JSON.
225+
- `parsed_header` (Optional[ParsedHeader]): The decrypted DynamoDB item's header (`aws_dbe_head` value).
232226
233227
Example:
234-
235228
>>> encrypted_item = {
236229
... 'some': {'B': b'ENCRYPTED_DATA'},
237230
... 'more': {'B': b'ENCRYPTED_DATA'}
@@ -247,24 +240,22 @@ def decrypt_item(
247240
self,
248241
decrypt_item_input: DecryptItemInput,
249242
) -> DecryptItemOutput:
250-
"""Decrypt a DynamoDB item.
243+
"""
244+
Decrypt a DynamoDB item.
251245
252246
The input item should contain a dictionary formatted as DynamoDB JSON:
253247
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html
254248
255-
Parameters
256-
----------
257-
decrypt_item_input (DecryptItemInput): Structure containing the following field:
258-
- `encrypted_item` (dict[str, Any]): The item to decrypt formatted as DynamoDB JSON.
249+
Args:
250+
decrypt_item_input (DecryptItemInput): Structure containing the following field:
251+
- `encrypted_item` (dict[str, Any]): The item to decrypt formatted as DynamoDB JSON.
259252
260-
Returns
261-
-------
262-
DecryptItemOutput: Structure containing the following fields:
263-
- `plaintext_item` (dict[str, Any]): The decrypted DynamoDB item formatted as DynamoDB JSON.
264-
- `parsed_header` (Optional[ParsedHeader]): The decrypted DynamoDB item's header (`aws_dbe_head` value).
253+
Returns:
254+
DecryptItemOutput: Structure containing the following fields:
255+
- `plaintext_item` (dict[str, Any]): The decrypted DynamoDB item formatted as DynamoDB JSON.
256+
- `parsed_header` (Optional[ParsedHeader]): The decrypted DynamoDB item's header (`aws_dbe_head` value).
265257
266258
Example:
267-
268259
>>> encrypted_item = {
269260
... 'some': {'B': b'ENCRYPTED_DATA'},
270261
... 'more': {'B': b'ENCRYPTED_DATA'}

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/encrypted/paginator.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,18 @@ def __init__(
3535
encryption_config: DynamoDbTablesEncryptionConfig,
3636
expect_standard_dictionaries: bool | None = False,
3737
):
38-
"""Create an EncryptedPaginator.
38+
"""
39+
Create an EncryptedPaginator.
3940
4041
Args:
4142
paginator (Paginator): A boto3 Paginator object for DynamoDB operations.
4243
This can be either a "query" or "scan" Paginator.
4344
encryption_config (DynamoDbTablesEncryptionConfig): Encryption configuration object.
45+
expect_standard_dictionaries (Optional[bool]): Does the underlying boto3 client expect items
46+
to be standard Python dictionaries? This should only be set to True if you are using a
47+
client obtained from a service resource or table resource (ex: `table.meta.client`).
48+
If this is True, EncryptedClient will expect item-like shapes to be
49+
standard Python dictionaries (default: False).
4450
4551
"""
4652
self._paginator = paginator
@@ -49,16 +55,15 @@ def __init__(
4955
self._expect_standard_dictionaries = expect_standard_dictionaries
5056
self._resource_to_client_shape_converter = ResourceShapeToClientShapeConverter()
5157
self._client_to_resource_shape_converter = ClientShapeToResourceShapeConverter(delete_table_name=False)
52-
print(f"{self._paginator=}")
53-
print(f"{self._paginator._model.name=}")
5458

5559
def paginate(self, **kwargs) -> Generator[dict, None, None]:
56-
"""Yields a generator that paginates through responses from DynamoDB, decrypting items.
60+
"""
61+
Yield a generator that paginates through responses from DynamoDB, decrypting items.
5762
5863
Note:
5964
Calling `botocore.paginate.Paginator`'s `paginate` method for Query or Scan
6065
returns a `PageIterator` object, but this implementation returns a Python generator.
61-
However, you can use this generator to iterate exactly as described in the official
66+
However, you can use this generator to iterate exactly as described in the
6267
boto3 documentation:
6368
https://botocore.amazonaws.com/v1/documentation/api/latest/topics/paginators.html
6469
Any other operations on this class will defer to the underlying boto3 Paginator's implementation.
@@ -166,7 +171,8 @@ def _paginate_request(
166171

167172
@property
168173
def _boto_client_attr_name(self) -> str:
169-
"""Name of the attribute containing the underlying boto3 client.
174+
"""
175+
Name of the attribute containing the underlying boto3 client.
170176
171177
Returns:
172178
str: '_paginator'

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/encrypted/resource.py

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""High-level helper classes to provide encrypting wrappers for boto3 DynamoDB resources."""
14
from collections.abc import Callable, Generator
25
from copy import deepcopy
36
from typing import Any
@@ -24,15 +27,13 @@
2427

2528

2629
class EncryptedTablesCollectionManager(EncryptedBotoInterface):
27-
"""Tables collection manager that provides EncryptedTable objects.
30+
"""
31+
Tables collection manager that provides EncryptedTable objects.
2832
33+
The API matches boto3's tables collection manager interface:
2934
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/service-resource/tables.html
3035
31-
:param collection: Pre-configured boto3 DynamoDB table collection manager
32-
:type collection: boto3.resources.collection.CollectionManager
33-
:param CryptographicMaterialsProvider materials_provider: Cryptographic materials provider to use
34-
:param AttributeActions attribute_actions: Table-level configuration of how to encrypt/sign attributes
35-
:param TableInfoCache table_info_cache: Local cache from which to obtain TableInfo data
36+
All operations on this class will yield EncryptedTable objects.
3637
"""
3738

3839
def __init__(
@@ -41,11 +42,20 @@ def __init__(
4142
collection: CollectionManager,
4243
encryption_config: DynamoDbTablesEncryptionConfig,
4344
):
45+
"""
46+
Create an EncryptedTablesCollectionManager object.
47+
48+
Args:
49+
collection (CollectionManager): Pre-configured boto3 DynamoDB table collection manager
50+
encryption_config (DynamoDbTablesEncryptionConfig): Initialized DynamoDbTablesEncryptionConfig
51+
52+
"""
4453
self._collection = collection
4554
self._encryption_config = encryption_config
4655

4756
def all(self) -> Generator[EncryptedTable, None, None]:
48-
"""Create an iterable of all EncryptedTable resources in the collection.
57+
"""
58+
Create an iterable of all EncryptedTable resources in the collection.
4959
5060
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/service-resource/tables.html#DynamoDB.ServiceResource.all
5161
@@ -56,7 +66,8 @@ def all(self) -> Generator[EncryptedTable, None, None]:
5666
yield from self._transform_table(self._collection.all)
5767

5868
def filter(self, **kwargs) -> Generator[EncryptedTable, None, None]:
59-
"""Create an iterable of all EncryptedTable resources in the collection filtered by kwargs passed to method.
69+
"""
70+
Create an iterable of all EncryptedTable resources in the collection filtered by kwargs passed to method.
6071
6172
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/service-resource/tables.html#filter
6273
@@ -67,7 +78,8 @@ def filter(self, **kwargs) -> Generator[EncryptedTable, None, None]:
6778
yield from self._transform_table(self._collection.filter, **kwargs)
6879

6980
def limit(self, **kwargs) -> Generator[EncryptedTable, None, None]:
70-
"""Create an iterable of all EncryptedTable resources in the collection filtered by kwargs passed to method.
81+
"""
82+
Create an iterable of all EncryptedTable resources in the collection filtered by kwargs passed to method.
7183
7284
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/service-resource/tables.html#limit
7385
@@ -78,7 +90,8 @@ def limit(self, **kwargs) -> Generator[EncryptedTable, None, None]:
7890
yield from self._transform_table(self._collection.limit, **kwargs)
7991

8092
def page_size(self, **kwargs) -> Generator[EncryptedTable, None, None]:
81-
"""Create an iterable of all EncryptedTable resources in the collection.
93+
"""
94+
Create an iterable of all EncryptedTable resources in the collection.
8295
8396
This limits the number of items returned by each service call by the specified amount.
8497
@@ -100,7 +113,8 @@ def _transform_table(
100113

101114
@property
102115
def _boto_client_attr_name(self) -> str:
103-
"""Name of the attribute containing the underlying boto3 client.
116+
"""
117+
Name of the attribute containing the underlying boto3 client.
104118
105119
Returns:
106120
str: '_collection'
@@ -110,7 +124,8 @@ def _boto_client_attr_name(self) -> str:
110124

111125

112126
class EncryptedResource(EncryptedBotoInterface):
113-
"""Wrapper for a boto3 DynamoDB resource.
127+
"""
128+
Wrapper for a boto3 DynamoDB resource.
114129
115130
This class implements the complete boto3 DynamoDB resource API, allowing it to serve as a
116131
drop-in replacement that transparently handles encryption and decryption of items.
@@ -135,7 +150,8 @@ def __init__(
135150
resource: ServiceResource,
136151
encryption_config: DynamoDbTablesEncryptionConfig,
137152
):
138-
"""Create an EncryptedResource object.
153+
"""
154+
Create an EncryptedResource object.
139155
140156
Args:
141157
resource (ServiceResource): Initialized boto3 DynamoDB resource
@@ -152,7 +168,8 @@ def __init__(
152168
)
153169

154170
def Table(self, name):
155-
"""Create an EncryptedTable resource.
171+
"""
172+
Create an EncryptedTable resource.
156173
157174
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/service-resource/Table.html
158175
@@ -166,7 +183,8 @@ def Table(self, name):
166183
return EncryptedTable(table=self._resource.Table(name), encryption_config=self._encryption_config)
167184

168185
def batch_get_item(self, **kwargs):
169-
"""Get multiple items from one or more tables. Decrypts any returned items.
186+
"""
187+
Get multiple items from one or more tables. Decrypts any returned items.
170188
171189
The parameters and return value match the boto3 DynamoDB batch_get_item API:
172190
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/service-resource/batch_get_item.html
@@ -192,7 +210,8 @@ def batch_get_item(self, **kwargs):
192210
)
193211

194212
def batch_write_item(self, **kwargs):
195-
"""Put or delete multiple items in one or more tables.
213+
"""
214+
Put or delete multiple items in one or more tables.
196215
197216
For put operations, encrypts items before writing.
198217
@@ -273,7 +292,8 @@ def _resource_operation_logic(
273292

274293
@property
275294
def _boto_client_attr_name(self) -> str:
276-
"""Name of the attribute containing the underlying boto3 client.
295+
"""
296+
Name of the attribute containing the underlying boto3 client.
277297
278298
Returns:
279299
str: '_resource'

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/encrypted/table.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030

3131

3232
class EncryptedTable(EncryptedBotoInterface):
33-
"""Wrapper for a boto3 DynamoDB table that transparently encrypts/decrypts items.
33+
"""
34+
Wrapper for a boto3 DynamoDB table that transparently encrypts/decrypts items.
3435
3536
This class implements the complete boto3 DynamoDB table API, allowing it to serve as a
3637
drop-in replacement that transparently handles encryption and decryption of items.
@@ -58,12 +59,12 @@ def __init__(
5859
table: ServiceResource,
5960
encryption_config: DynamoDbTablesEncryptionConfig,
6061
):
61-
"""Create an EncryptedTable object.
62+
"""
63+
Create an EncryptedTable object.
6264
6365
Args:
6466
table (ServiceResource): Initialized boto3 DynamoDB table
65-
encryption_config (DynamoDbTablesEncryptionConfig): Initialized
66-
~aws_dbesdk_dynamodb.smithygenerated.aws_cryptography_dbencryptionsdk_dynamodb.models.DynamoDbTablesEncryptionConfig~
67+
encryption_config (DynamoDbTablesEncryptionConfig): Initialized DynamoDbTablesEncryptionConfig
6768
6869
"""
6970
self._table = table
@@ -75,7 +76,8 @@ def __init__(
7576
)
7677

7778
def put_item(self, **kwargs) -> dict[str, Any]:
78-
"""Put a single item to the table. Encrypts the item before writing to DynamoDB.
79+
"""
80+
Put a single item to the table. Encrypts the item before writing to DynamoDB.
7981
8082
The parameters and return value match the boto3 DynamoDB table put_item API:
8183
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/put_item.html
@@ -101,7 +103,8 @@ def put_item(self, **kwargs) -> dict[str, Any]:
101103
)
102104

103105
def get_item(self, **kwargs) -> dict[str, Any]:
104-
"""Get a single item from the table. Decrypts the item after reading from DynamoDB.
106+
"""
107+
Get a single item from the table. Decrypts the item after reading from DynamoDB.
105108
106109
The parameters and return value match the boto3 DynamoDB table get_item API:
107110
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/get_item.html
@@ -127,7 +130,8 @@ def get_item(self, **kwargs) -> dict[str, Any]:
127130
)
128131

129132
def query(self, **kwargs) -> dict[str, Any]:
130-
"""Query items from the table or index. Decrypts any returned items.
133+
"""
134+
Query items from the table or index. Decrypts any returned items.
131135
132136
The parameters and return value match the boto3 DynamoDB table query API:
133137
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/query.html
@@ -153,7 +157,8 @@ def query(self, **kwargs) -> dict[str, Any]:
153157
)
154158

155159
def scan(self, **kwargs) -> dict[str, Any]:
156-
"""Scan the entire table or index. Decrypts any returned items.
160+
"""
161+
Scan the entire table or index. Decrypts any returned items.
157162
158163
The parameters and return value match the boto3 DynamoDB table scan API:
159164
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/scan.html
@@ -179,7 +184,8 @@ def scan(self, **kwargs) -> dict[str, Any]:
179184
)
180185

181186
def update_item(self, **kwargs):
182-
"""Not implemented. Raises NotImplementedError.
187+
"""
188+
Not implemented. Raises NotImplementedError.
183189
184190
Args:
185191
**kwargs: Any arguments passed to this method
@@ -191,7 +197,8 @@ def update_item(self, **kwargs):
191197
raise NotImplementedError('"update_item" is not yet implemented')
192198

193199
def batch_writer(self, overwrite_by_pkeys: list[str] | None = None) -> BatchWriter:
194-
"""Create a batch writer object that will transparently encrypt requests to DynamoDB.
200+
"""
201+
Create a batch writer object that will transparently encrypt requests to DynamoDB.
195202
196203
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/table/batch_writer.html
197204
@@ -226,7 +233,8 @@ def _table_operation_logic(
226233
output_client_to_resource_shape_transform_method: Any,
227234
table_method: Callable,
228235
) -> dict[str, Any]:
229-
"""Interface between user-supplied input, encryption/decryption transformers, and boto3 Tables.
236+
"""
237+
Interface between user-supplied input, encryption/decryption transformers, and boto3 Tables.
230238
231239
Args:
232240
operation_input: User-supplied input to the operation
@@ -287,7 +295,8 @@ def _table_operation_logic(
287295

288296
@property
289297
def _boto_client_attr_name(self) -> str:
290-
"""Name of the attribute containing the underlying boto3 client.
298+
"""
299+
Name of the attribute containing the underlying boto3 client.
291300
292301
Returns:
293302
str: '_table'

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/internal/boto3_conversions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33

44
class BotoInterfaceShapeConverter(ABC):
5-
"""Class modelling transformations between boto3 DynamoDB client and resource shapes.
5+
"""
6+
Class modelling transformations between boto3 DynamoDB client and resource shapes.
67
78
DBESDK for DynamoDB provides encrypted interfaces for boto3 DynamoDB resources (ex. Table, Resource).
89
boto3 resource methods accept different input shapes than boto3 clients, and return different output shapes.

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/internal/condition_expression_builder.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def reset(self):
3434
def build_expression(
3535
self, condition, attribute_name_placeholders, attribute_value_placeholders, is_key_condition=False
3636
):
37-
"""Builds the condition expression and the dictionary of placeholders.
37+
"""
38+
Builds the condition expression and the dictionary of placeholders.
3839
3940
:type condition: ConditionBase
4041
:param condition: A condition to be built into a condition expression

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/internal/resource_to_client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ def __init__(self, table_name=None):
1616
self.expression_builder = InternalDBESDKDynamoDBConditionExpressionBuilder()
1717

1818
def condition_handler(self, expression_key, request):
19-
"""Converts an object from boto3.dynamodb.conditions to a string
19+
"""
20+
Converts an object from boto3.dynamodb.conditions to a string
2021
and updates ExpressionAttributeNames and ExpressionAttributeValues with any new names/values.
2122
The ExpressionAttributeValues are returned in resource format (Python dictionaries).
2223
"""

‎DynamoDbEncryption/runtimes/python/src/aws_dbesdk_dynamodb/transform.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0
3-
"""Helper tools for translating between native and DynamoDB items.
3+
"""
4+
Helper tools for translating between native and DynamoDB items.
45
56
For information on how types are serializes, see:
67
https://boto3.amazonaws.com/v1/documentation/api/latest/_modules/boto3/dynamodb/types.html
@@ -13,7 +14,8 @@
1314

1415

1516
def dict_to_ddb(item: dict[str, Any]) -> dict[str, Any]:
16-
"""Convert a native Python dictionary to a DynamoDB-JSON item.
17+
"""
18+
Convert a native Python dictionary to a DynamoDB-JSON item.
1719
1820
Args:
1921
item (Dict[str, Any]): Native Python dictionary.
@@ -27,7 +29,8 @@ def dict_to_ddb(item: dict[str, Any]) -> dict[str, Any]:
2729

2830

2931
def list_of_dict_to_list_of_ddb(items: list[dict[str, Any]]) -> list[dict[str, Any]]:
30-
"""Convert a list of Python dictionaries into a list of DynamoDB-JSON formatted items.
32+
"""
33+
Convert a list of Python dictionaries into a list of DynamoDB-JSON formatted items.
3134
3235
Args:
3336
items (List[Dict[str, Any]]): List of native Python dictionaries.
@@ -40,7 +43,8 @@ def list_of_dict_to_list_of_ddb(items: list[dict[str, Any]]) -> list[dict[str, A
4043

4144

4245
def ddb_to_dict(item: dict[str, Any]) -> dict[str, Any]:
43-
"""Convert a DynamoDB-JSON item to a native Python dictionary.
46+
"""
47+
Convert a DynamoDB-JSON item to a native Python dictionary.
4448
4549
Args:
4650
item (Dict[str, Any]): DynamoDB-formatted item.
@@ -54,7 +58,8 @@ def ddb_to_dict(item: dict[str, Any]) -> dict[str, Any]:
5458

5559

5660
def list_of_ddb_to_list_of_dict(items: list[dict[str, Any]]) -> list[dict[str, Any]]:
57-
"""Convert a list of DynamoDB-JSON formatted items to a list of Python dictionaries.
61+
"""
62+
Convert a list of DynamoDB-JSON formatted items to a list of Python dictionaries.
5863
5964
Args:
6065
items (List[Dict[str, Any]]): List of DynamoDB-formatted items.

0 commit comments

Comments
 (0)
Please sign in to comment.