Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/botocore/translate.py: 24%

21 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:51 +0000

1# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/ 

2# Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"). You 

5# may not use this file except in compliance with the License. A copy of 

6# the License is located at 

7# 

8# http://aws.amazon.com/apache2.0/ 

9# 

10# or in the "license" file accompanying this file. This file is 

11# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 

12# ANY KIND, either express or implied. See the License for the specific 

13# language governing permissions and limitations under the License. 

14import copy 

15 

16from botocore.utils import merge_dicts 

17 

18 

19def build_retry_config( 

20 endpoint_prefix, retry_model, definitions, client_retry_config=None 

21): 

22 service_config = retry_model.get(endpoint_prefix, {}) 

23 resolve_references(service_config, definitions) 

24 # We want to merge the global defaults with the service specific 

25 # defaults, with the service specific defaults taking precedence. 

26 # So we use the global defaults as the base. 

27 # 

28 # A deepcopy is done on the retry defaults because it ensures the 

29 # retry model has no chance of getting mutated when the service specific 

30 # configuration or client retry config is merged in. 

31 final_retry_config = { 

32 '__default__': copy.deepcopy(retry_model.get('__default__', {})) 

33 } 

34 resolve_references(final_retry_config, definitions) 

35 # The merge the service specific config on top. 

36 merge_dicts(final_retry_config, service_config) 

37 if client_retry_config is not None: 

38 _merge_client_retry_config(final_retry_config, client_retry_config) 

39 return final_retry_config 

40 

41 

42def _merge_client_retry_config(retry_config, client_retry_config): 

43 max_retry_attempts_override = client_retry_config.get('max_attempts') 

44 if max_retry_attempts_override is not None: 

45 # In the retry config, the max_attempts refers to the maximum number 

46 # of requests in general will be made. However, for the client's 

47 # retry config it refers to how many retry attempts will be made at 

48 # most. So to translate this number from the client config, one is 

49 # added to convert it to the maximum number request that will be made 

50 # by including the initial request. 

51 # 

52 # It is also important to note that if we ever support per operation 

53 # configuration in the retry model via the client, we will need to 

54 # revisit this logic to make sure max_attempts gets applied 

55 # per operation. 

56 retry_config['__default__']['max_attempts'] = ( 

57 max_retry_attempts_override + 1 

58 ) 

59 

60 

61def resolve_references(config, definitions): 

62 """Recursively replace $ref keys. 

63 

64 To cut down on duplication, common definitions can be declared 

65 (and passed in via the ``definitions`` attribute) and then 

66 references as {"$ref": "name"}, when this happens the reference 

67 dict is placed with the value from the ``definition`` dict. 

68 

69 This is recursively done. 

70 

71 """ 

72 for key, value in config.items(): 

73 if isinstance(value, dict): 

74 if len(value) == 1 and list(value.keys())[0] == '$ref': 

75 # Then we need to resolve this reference. 

76 config[key] = definitions[list(value.values())[0]] 

77 else: 

78 resolve_references(value, definitions)