1# Copyright (c) 2012-2013 Mitch Garnaat http://garnaat.org/
2# Copyright 2012-2014 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.
14
15import logging
16import os
17import re
18
19__version__ = '1.38.41'
20
21
22class NullHandler(logging.Handler):
23 def emit(self, record):
24 pass
25
26
27# Configure default logger to do nothing
28log = logging.getLogger('botocore')
29log.addHandler(NullHandler())
30
31_INITIALIZERS = []
32
33_first_cap_regex = re.compile('(.)([A-Z][a-z]+)')
34_end_cap_regex = re.compile('([a-z0-9])([A-Z])')
35# The regex below handles the special case where some acronym
36# name is pluralized, e.g GatewayARNs, ListWebACLs, SomeCNAMEs.
37_special_case_transform = re.compile('[A-Z]{2,}s$')
38# Prepopulate the cache with special cases that don't match
39# our regular transformation.
40_xform_cache = {
41 ('CreateCachediSCSIVolume', '_'): 'create_cached_iscsi_volume',
42 ('CreateCachediSCSIVolume', '-'): 'create-cached-iscsi-volume',
43 ('DescribeCachediSCSIVolumes', '_'): 'describe_cached_iscsi_volumes',
44 ('DescribeCachediSCSIVolumes', '-'): 'describe-cached-iscsi-volumes',
45 ('DescribeStorediSCSIVolumes', '_'): 'describe_stored_iscsi_volumes',
46 ('DescribeStorediSCSIVolumes', '-'): 'describe-stored-iscsi-volumes',
47 ('CreateStorediSCSIVolume', '_'): 'create_stored_iscsi_volume',
48 ('CreateStorediSCSIVolume', '-'): 'create-stored-iscsi-volume',
49 ('ListHITsForQualificationType', '_'): 'list_hits_for_qualification_type',
50 ('ListHITsForQualificationType', '-'): 'list-hits-for-qualification-type',
51 ('ExecutePartiQLStatement', '_'): 'execute_partiql_statement',
52 ('ExecutePartiQLStatement', '-'): 'execute-partiql-statement',
53 ('ExecutePartiQLTransaction', '_'): 'execute_partiql_transaction',
54 ('ExecutePartiQLTransaction', '-'): 'execute-partiql-transaction',
55 ('ExecutePartiQLBatch', '_'): 'execute_partiql_batch',
56 ('ExecutePartiQLBatch', '-'): 'execute-partiql-batch',
57 (
58 'AssociateWhatsAppBusinessAccount',
59 '_',
60 ): 'associate_whatsapp_business_account',
61 (
62 'AssociateWhatsAppBusinessAccount',
63 '-',
64 ): 'associate-whatsapp-business-account',
65 ('DeleteWhatsAppMessageMedia', '_'): 'delete_whatsapp_message_media',
66 ('DeleteWhatsAppMessageMedia', '-'): 'delete-whatsapp-message-media',
67 (
68 'DisassociateWhatsAppBusinessAccount',
69 '_',
70 ): 'disassociate_whatsapp_business_account',
71 (
72 'DisassociateWhatsAppBusinessAccount',
73 '-',
74 ): 'disassociate-whatsapp-business-account',
75 (
76 'GetLinkedWhatsAppBusinessAccount',
77 '_',
78 ): 'get_linked_whatsapp_business_account',
79 (
80 'GetLinkedWhatsAppBusinessAccount',
81 '-',
82 ): 'get-linked-whatsapp-business-account',
83 (
84 'GetLinkedWhatsAppBusinessAccountPhoneNumber',
85 '_',
86 ): 'get_linked_whatsapp_business_account_phone_number',
87 (
88 'GetLinkedWhatsAppBusinessAccountPhoneNumber',
89 '-',
90 ): 'get-linked-whatsapp-business-account-phone-number',
91 ('GetWhatsAppMessageMedia', '_'): 'get_whatsapp_message_media',
92 ('GetWhatsAppMessageMedia', '-'): 'get-whatsapp-message-media',
93 (
94 'ListLinkedWhatsAppBusinessAccounts',
95 '_',
96 ): 'list_linked_whatsapp_business_accounts',
97 (
98 'ListLinkedWhatsAppBusinessAccounts',
99 '-',
100 ): 'list-linked-whatsapp-business-accounts',
101 ('PostWhatsAppMessageMedia', '_'): 'post_whatsapp_message_media',
102 ('PostWhatsAppMessageMedia', '-'): 'post-whatsapp-message-media',
103 (
104 'PutWhatsAppBusinessAccountEventDestinations',
105 '_',
106 ): 'put_whatsapp_business_account_event_destinations',
107 (
108 'PutWhatsAppBusinessAccountEventDestinations',
109 '-',
110 ): 'put-whatsapp-business-account-event-destinations',
111 ('SendWhatsAppMessage', '_'): 'send_whatsapp_message',
112 ('SendWhatsAppMessage', '-'): 'send-whatsapp-message',
113}
114ScalarTypes = ('string', 'integer', 'boolean', 'timestamp', 'float', 'double')
115
116BOTOCORE_ROOT = os.path.dirname(os.path.abspath(__file__))
117
118
119# Used to specify anonymous (unsigned) request signature
120class UNSIGNED:
121 def __copy__(self):
122 return self
123
124 def __deepcopy__(self, memodict):
125 return self
126
127
128UNSIGNED = UNSIGNED()
129
130
131def xform_name(name, sep='_', _xform_cache=_xform_cache):
132 """Convert camel case to a "pythonic" name.
133
134 If the name contains the ``sep`` character, then it is
135 returned unchanged.
136
137 """
138 if sep in name:
139 # If the sep is in the name, assume that it's already
140 # transformed and return the string unchanged.
141 return name
142 key = (name, sep)
143 if key not in _xform_cache:
144 if _special_case_transform.search(name) is not None:
145 is_special = _special_case_transform.search(name)
146 matched = is_special.group()
147 # Replace something like ARNs, ACLs with _arns, _acls.
148 name = f"{name[: -len(matched)]}{sep}{matched.lower()}"
149 s1 = _first_cap_regex.sub(r'\1' + sep + r'\2', name)
150 transformed = _end_cap_regex.sub(r'\1' + sep + r'\2', s1).lower()
151 _xform_cache[key] = transformed
152 return _xform_cache[key]
153
154
155def register_initializer(callback):
156 """Register an initializer function for session creation.
157
158 This initializer function will be invoked whenever a new
159 `botocore.session.Session` is instantiated.
160
161 :type callback: callable
162 :param callback: A callable that accepts a single argument
163 of type `botocore.session.Session`.
164
165 """
166 _INITIALIZERS.append(callback)
167
168
169def unregister_initializer(callback):
170 """Unregister an initializer function.
171
172 :type callback: callable
173 :param callback: A callable that was previously registered
174 with `botocore.register_initializer`.
175
176 :raises ValueError: If a callback is provided that is not currently
177 registered as an initializer.
178
179 """
180 _INITIALIZERS.remove(callback)
181
182
183def invoke_initializers(session):
184 """Invoke all initializers for a session.
185
186 :type session: botocore.session.Session
187 :param session: The session to initialize.
188
189 """
190 for initializer in _INITIALIZERS:
191 initializer(session)