Skip to content

Commit 4f28c9f

Browse files
committed
Remove operation settings and wrap with verboseclienterror
1 parent fabf329 commit 4f28c9f

File tree

6 files changed

+121
-137
lines changed

6 files changed

+121
-137
lines changed

pynamodb/connection/base.py

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
import botocore.client
1111
import botocore.exceptions
12-
from botocore.awsrequest import AWSPreparedRequest, create_request_object
1312
from botocore.client import ClientError
1413
from botocore.exceptions import BotoCoreError
1514
from botocore.session import get_session
@@ -42,7 +41,7 @@
4241
from pynamodb.expressions.operand import Path
4342
from pynamodb.expressions.projection import create_projection_expression
4443
from pynamodb.expressions.update import Action, Update
45-
from pynamodb.settings import get_settings_value, OperationSettings
44+
from pynamodb.settings import get_settings_value
4645
from pynamodb.signals import pre_dynamodb_send, post_dynamodb_send
4746
from pynamodb.types import HASH, RANGE
4847

@@ -281,28 +280,7 @@ def __init__(self,
281280
def __repr__(self) -> str:
282281
return "Connection<{}>".format(self.client.meta.endpoint_url)
283282

284-
def _sign_request(self, request):
285-
auth = self.client._request_signer.get_auth_instance(
286-
self.client._request_signer.signing_name,
287-
self.client._request_signer.region_name,
288-
self.client._request_signer.signature_version)
289-
auth.add_auth(request)
290-
291-
def _create_prepared_request(
292-
self,
293-
params: Dict,
294-
settings: OperationSettings,
295-
) -> AWSPreparedRequest:
296-
request = create_request_object(params)
297-
self._sign_request(request)
298-
prepared_request = self.client._endpoint.prepare_request(request)
299-
if self._extra_headers is not None:
300-
prepared_request.headers.update(self._extra_headers)
301-
if settings.extra_headers is not None:
302-
prepared_request.headers.update(settings.extra_headers)
303-
return prepared_request
304-
305-
def dispatch(self, operation_name: str, operation_kwargs: Dict, settings: OperationSettings = OperationSettings.default) -> Dict:
283+
def dispatch(self, operation_name: str, operation_kwargs: Dict) -> Dict:
306284
"""
307285
Dispatches `operation_name` with arguments `operation_kwargs`
308286
@@ -317,7 +295,7 @@ def dispatch(self, operation_name: str, operation_kwargs: Dict, settings: Operat
317295
req_uuid = uuid.uuid4()
318296

319297
self.send_pre_boto_callback(operation_name, req_uuid, table_name)
320-
data = self._make_api_call(operation_name, operation_kwargs, settings)
298+
data = self._make_api_call(operation_name, operation_kwargs)
321299
self.send_post_boto_callback(operation_name, req_uuid, table_name)
322300

323301
if data and CONSUMED_CAPACITY in data:
@@ -330,17 +308,47 @@ def dispatch(self, operation_name: str, operation_kwargs: Dict, settings: Operat
330308
def send_post_boto_callback(self, operation_name, req_uuid, table_name):
331309
try:
332310
post_dynamodb_send.send(self, operation_name=operation_name, table_name=table_name, req_uuid=req_uuid)
333-
except Exception as e:
311+
except Exception:
334312
log.exception("post_boto callback threw an exception.")
335313

336314
def send_pre_boto_callback(self, operation_name, req_uuid, table_name):
337315
try:
338316
pre_dynamodb_send.send(self, operation_name=operation_name, table_name=table_name, req_uuid=req_uuid)
339-
except Exception as e:
317+
except Exception:
340318
log.exception("pre_boto callback threw an exception.")
341319

342-
def _make_api_call(self, operation_name: str, operation_kwargs: Dict, settings: OperationSettings = OperationSettings.default) -> Dict:
343-
return self.client._make_api_call(operation_name, operation_kwargs)
320+
def _before_sign(self, request, **_) -> None:
321+
if self._extra_headers is not None:
322+
for k, v in self._extra_headers.items():
323+
request.headers.add_header(k, v)
324+
325+
def _make_api_call(self, operation_name: str, operation_kwargs: Dict) -> Dict:
326+
try:
327+
return self.client._make_api_call(operation_name, operation_kwargs)
328+
except ClientError as e:
329+
resp_metadata = e.response.get('ResponseMetadata', {}).get('HTTPHeaders', {})
330+
331+
botocore_props = {'Error': e.response.get('Error', {})}
332+
verbose_props = {
333+
'request_id': resp_metadata.get('x-amzn-requestid', ''),
334+
'table_name': self._get_table_name_for_error_context(operation_kwargs),
335+
}
336+
raise VerboseClientError(botocore_props, operation_name, verbose_props) from e
337+
338+
# todo: should we handle generic BotoCoreError here too?
339+
# todo: should we handle generic HTTPClientError here too? e.g. for timeout
340+
341+
def _get_table_name_for_error_context(self, operation_kwargs) -> str:
342+
# First handle the two multi-table cases: batch and transaction operations
343+
if REQUEST_ITEMS in operation_kwargs:
344+
return ','.join(operation_kwargs[REQUEST_ITEMS])
345+
elif TRANSACT_ITEMS in operation_kwargs:
346+
return ",".join(
347+
op[TABLE_NAME] for op in (
348+
item for item in operation_kwargs[TRANSACT_ITEMS]
349+
)
350+
)
351+
return operation_kwargs.get(TABLE_NAME)
344352

345353
@property
346354
def session(self) -> botocore.session.Session:
@@ -373,6 +381,8 @@ def client(self):
373381
}
374382
)
375383
self._client = self.session.create_client(SERVICE_NAME, self.region, endpoint_url=self.host, config=config)
384+
385+
self._client.meta.events.register_first('before-sign.*.*', self._before_sign)
376386
return self._client
377387

378388
def get_meta_table(self, table_name: str, refresh: bool = False):
@@ -780,7 +790,6 @@ def delete_item(
780790
return_values: Optional[str] = None,
781791
return_consumed_capacity: Optional[str] = None,
782792
return_item_collection_metrics: Optional[str] = None,
783-
settings: OperationSettings = OperationSettings.default,
784793
) -> Dict:
785794
"""
786795
Performs the DeleteItem operation and returns the result
@@ -795,7 +804,7 @@ def delete_item(
795804
return_item_collection_metrics=return_item_collection_metrics
796805
)
797806
try:
798-
return self.dispatch(DELETE_ITEM, operation_kwargs, settings)
807+
return self.dispatch(DELETE_ITEM, operation_kwargs)
799808
except BOTOCORE_EXCEPTIONS as e:
800809
raise DeleteError("Failed to delete item: {}".format(e), e)
801810

@@ -809,7 +818,6 @@ def update_item(
809818
return_consumed_capacity: Optional[str] = None,
810819
return_item_collection_metrics: Optional[str] = None,
811820
return_values: Optional[str] = None,
812-
settings: OperationSettings = OperationSettings.default,
813821
) -> Dict:
814822
"""
815823
Performs the UpdateItem operation
@@ -828,7 +836,7 @@ def update_item(
828836
return_item_collection_metrics=return_item_collection_metrics,
829837
)
830838
try:
831-
return self.dispatch(UPDATE_ITEM, operation_kwargs, settings)
839+
return self.dispatch(UPDATE_ITEM, operation_kwargs)
832840
except BOTOCORE_EXCEPTIONS as e:
833841
raise UpdateError("Failed to update item: {}".format(e), e)
834842

@@ -842,7 +850,6 @@ def put_item(
842850
return_values: Optional[str] = None,
843851
return_consumed_capacity: Optional[str] = None,
844852
return_item_collection_metrics: Optional[str] = None,
845-
settings: OperationSettings = OperationSettings.default,
846853
) -> Dict:
847854
"""
848855
Performs the PutItem operation and returns the result
@@ -859,7 +866,7 @@ def put_item(
859866
return_item_collection_metrics=return_item_collection_metrics
860867
)
861868
try:
862-
return self.dispatch(PUT_ITEM, operation_kwargs, settings)
869+
return self.dispatch(PUT_ITEM, operation_kwargs)
863870
except BOTOCORE_EXCEPTIONS as e:
864871
raise PutError("Failed to put item: {}".format(e), e)
865872

@@ -888,7 +895,6 @@ def transact_write_items(
888895
client_request_token: Optional[str] = None,
889896
return_consumed_capacity: Optional[str] = None,
890897
return_item_collection_metrics: Optional[str] = None,
891-
settings: OperationSettings = OperationSettings.default,
892898
) -> Dict:
893899
"""
894900
Performs the TransactWrite operation and returns the result
@@ -915,15 +921,14 @@ def transact_write_items(
915921
operation_kwargs[TRANSACT_ITEMS] = transact_items
916922

917923
try:
918-
return self.dispatch(TRANSACT_WRITE_ITEMS, operation_kwargs, settings)
924+
return self.dispatch(TRANSACT_WRITE_ITEMS, operation_kwargs)
919925
except BOTOCORE_EXCEPTIONS as e:
920926
raise TransactWriteError("Failed to write transaction items", e)
921927

922928
def transact_get_items(
923929
self,
924930
get_items: Sequence[Dict],
925931
return_consumed_capacity: Optional[str] = None,
926-
settings: OperationSettings = OperationSettings.default,
927932
) -> Dict:
928933
"""
929934
Performs the TransactGet operation and returns the result
@@ -934,7 +939,7 @@ def transact_get_items(
934939
]
935940

936941
try:
937-
return self.dispatch(TRANSACT_GET_ITEMS, operation_kwargs, settings)
942+
return self.dispatch(TRANSACT_GET_ITEMS, operation_kwargs)
938943
except BOTOCORE_EXCEPTIONS as e:
939944
raise TransactGetError("Failed to get transaction items", e)
940945

@@ -945,7 +950,6 @@ def batch_write_item(
945950
delete_items: Optional[Any] = None,
946951
return_consumed_capacity: Optional[str] = None,
947952
return_item_collection_metrics: Optional[str] = None,
948-
settings: OperationSettings = OperationSettings.default,
949953
) -> Dict:
950954
"""
951955
Performs the batch_write_item operation
@@ -975,7 +979,7 @@ def batch_write_item(
975979
})
976980
operation_kwargs[REQUEST_ITEMS][table_name] = delete_items_list + put_items_list
977981
try:
978-
return self.dispatch(BATCH_WRITE_ITEM, operation_kwargs, settings)
982+
return self.dispatch(BATCH_WRITE_ITEM, operation_kwargs)
979983
except BOTOCORE_EXCEPTIONS as e:
980984
raise PutError("Failed to batch write items: {}".format(e), e)
981985

@@ -986,7 +990,6 @@ def batch_get_item(
986990
consistent_read: Optional[bool] = None,
987991
return_consumed_capacity: Optional[str] = None,
988992
attributes_to_get: Optional[Any] = None,
989-
settings: OperationSettings = OperationSettings.default,
990993
) -> Dict:
991994
"""
992995
Performs the batch get item operation
@@ -1017,7 +1020,7 @@ def batch_get_item(
10171020
)
10181021
operation_kwargs[REQUEST_ITEMS][table_name].update(keys_map)
10191022
try:
1020-
return self.dispatch(BATCH_GET_ITEM, operation_kwargs, settings)
1023+
return self.dispatch(BATCH_GET_ITEM, operation_kwargs)
10211024
except BOTOCORE_EXCEPTIONS as e:
10221025
raise GetError("Failed to batch get items: {}".format(e), e)
10231026

@@ -1028,7 +1031,6 @@ def get_item(
10281031
range_key: Optional[str] = None,
10291032
consistent_read: bool = False,
10301033
attributes_to_get: Optional[Any] = None,
1031-
settings: OperationSettings = OperationSettings.default,
10321034
) -> Dict:
10331035
"""
10341036
Performs the GetItem operation and returns the result
@@ -1041,7 +1043,7 @@ def get_item(
10411043
attributes_to_get=attributes_to_get
10421044
)
10431045
try:
1044-
return self.dispatch(GET_ITEM, operation_kwargs, settings)
1046+
return self.dispatch(GET_ITEM, operation_kwargs)
10451047
except BOTOCORE_EXCEPTIONS as e:
10461048
raise GetError("Failed to get item: {}".format(e), e)
10471049

@@ -1057,7 +1059,6 @@ def scan(
10571059
total_segments: Optional[int] = None,
10581060
consistent_read: Optional[bool] = None,
10591061
index_name: Optional[str] = None,
1060-
settings: OperationSettings = OperationSettings.default,
10611062
) -> Dict:
10621063
"""
10631064
Performs the scan operation
@@ -1094,7 +1095,7 @@ def scan(
10941095
operation_kwargs[EXPRESSION_ATTRIBUTE_VALUES] = expression_attribute_values
10951096

10961097
try:
1097-
return self.dispatch(SCAN, operation_kwargs, settings)
1098+
return self.dispatch(SCAN, operation_kwargs)
10981099
except BOTOCORE_EXCEPTIONS as e:
10991100
raise ScanError("Failed to scan table: {}".format(e), e)
11001101

@@ -1112,7 +1113,6 @@ def query(
11121113
return_consumed_capacity: Optional[str] = None,
11131114
scan_index_forward: Optional[bool] = None,
11141115
select: Optional[str] = None,
1115-
settings: OperationSettings = OperationSettings.default,
11161116
) -> Dict:
11171117
"""
11181118
Performs the Query operation and returns the result
@@ -1169,7 +1169,7 @@ def query(
11691169
operation_kwargs[EXPRESSION_ATTRIBUTE_VALUES] = expression_attribute_values
11701170

11711171
try:
1172-
return self.dispatch(QUERY, operation_kwargs, settings)
1172+
return self.dispatch(QUERY, operation_kwargs)
11731173
except BOTOCORE_EXCEPTIONS as e:
11741174
raise QueryError("Failed to query items: {}".format(e), e)
11751175

0 commit comments

Comments
 (0)