Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/boto3/session.py: 63%
92 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
1# Copyright 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"). You
4# may not use this file except in compliance with the License. A copy of
5# the License is located at
6#
7# https://aws.amazon.com/apache2.0/
8#
9# or in the "license" file accompanying this file. This file is
10# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11# ANY KIND, either express or implied. See the License for the specific
12# language governing permissions and limitations under the License.
14import copy
15import os
17import botocore.session
18from botocore.client import Config
19from botocore.exceptions import DataNotFoundError, UnknownServiceError
21import boto3
22import boto3.utils
23from boto3.exceptions import ResourceNotExistsError, UnknownAPIVersionError
25from .resources.factory import ResourceFactory
28class Session:
29 """
30 A session stores configuration state and allows you to create service
31 clients and resources.
33 :type aws_access_key_id: string
34 :param aws_access_key_id: AWS access key ID
35 :type aws_secret_access_key: string
36 :param aws_secret_access_key: AWS secret access key
37 :type aws_session_token: string
38 :param aws_session_token: AWS temporary session token
39 :type region_name: string
40 :param region_name: Default region when creating new connections
41 :type botocore_session: botocore.session.Session
42 :param botocore_session: Use this Botocore session instead of creating
43 a new default one.
44 :type profile_name: string
45 :param profile_name: The name of a profile to use. If not given, then
46 the default profile is used.
47 """
49 def __init__(
50 self,
51 aws_access_key_id=None,
52 aws_secret_access_key=None,
53 aws_session_token=None,
54 region_name=None,
55 botocore_session=None,
56 profile_name=None,
57 ):
58 if botocore_session is not None:
59 self._session = botocore_session
60 else:
61 # Create a new default session
62 self._session = botocore.session.get_session()
64 # Setup custom user-agent string if it isn't already customized
65 if self._session.user_agent_name == 'Botocore':
66 botocore_info = 'Botocore/{}'.format(
67 self._session.user_agent_version
68 )
69 if self._session.user_agent_extra:
70 self._session.user_agent_extra += ' ' + botocore_info
71 else:
72 self._session.user_agent_extra = botocore_info
73 self._session.user_agent_name = 'Boto3'
74 self._session.user_agent_version = boto3.__version__
76 if profile_name is not None:
77 self._session.set_config_variable('profile', profile_name)
79 if aws_access_key_id or aws_secret_access_key or aws_session_token:
80 self._session.set_credentials(
81 aws_access_key_id, aws_secret_access_key, aws_session_token
82 )
84 if region_name is not None:
85 self._session.set_config_variable('region', region_name)
87 self.resource_factory = ResourceFactory(
88 self._session.get_component('event_emitter')
89 )
90 self._setup_loader()
91 self._register_default_handlers()
93 def __repr__(self):
94 return '{}(region_name={})'.format(
95 self.__class__.__name__,
96 repr(self._session.get_config_variable('region')),
97 )
99 @property
100 def profile_name(self):
101 """
102 The **read-only** profile name.
103 """
104 return self._session.profile or 'default'
106 @property
107 def region_name(self):
108 """
109 The **read-only** region name.
110 """
111 return self._session.get_config_variable('region')
113 @property
114 def events(self):
115 """
116 The event emitter for a session
117 """
118 return self._session.get_component('event_emitter')
120 @property
121 def available_profiles(self):
122 """
123 The profiles available to the session credentials
124 """
125 return self._session.available_profiles
127 def _setup_loader(self):
128 """
129 Setup loader paths so that we can load resources.
130 """
131 self._loader = self._session.get_component('data_loader')
132 self._loader.search_paths.append(
133 os.path.join(os.path.dirname(__file__), 'data')
134 )
136 def get_available_services(self):
137 """
138 Get a list of available services that can be loaded as low-level
139 clients via :py:meth:`Session.client`.
141 :rtype: list
142 :return: List of service names
143 """
144 return self._session.get_available_services()
146 def get_available_resources(self):
147 """
148 Get a list of available services that can be loaded as resource
149 clients via :py:meth:`Session.resource`.
151 :rtype: list
152 :return: List of service names
153 """
154 return self._loader.list_available_services(type_name='resources-1')
156 def get_available_partitions(self):
157 """Lists the available partitions
159 :rtype: list
160 :return: Returns a list of partition names (e.g., ["aws", "aws-cn"])
161 """
162 return self._session.get_available_partitions()
164 def get_available_regions(
165 self, service_name, partition_name='aws', allow_non_regional=False
166 ):
167 """Lists the region and endpoint names of a particular partition.
169 The list of regions returned by this method are regions that are
170 explicitly known by the client to exist and is not comprehensive. A
171 region not returned in this list may still be available for the
172 provided service.
174 :type service_name: string
175 :param service_name: Name of a service to list endpoint for (e.g., s3).
177 :type partition_name: string
178 :param partition_name: Name of the partition to limit endpoints to.
179 (e.g., aws for the public AWS endpoints, aws-cn for AWS China
180 endpoints, aws-us-gov for AWS GovCloud (US) Endpoints, etc.)
182 :type allow_non_regional: bool
183 :param allow_non_regional: Set to True to include endpoints that are
184 not regional endpoints (e.g., s3-external-1,
185 fips-us-gov-west-1, etc).
187 :return: Returns a list of endpoint names (e.g., ["us-east-1"]).
188 """
189 return self._session.get_available_regions(
190 service_name=service_name,
191 partition_name=partition_name,
192 allow_non_regional=allow_non_regional,
193 )
195 def get_credentials(self):
196 """
197 Return the :class:`botocore.credentials.Credentials` object
198 associated with this session. If the credentials have not
199 yet been loaded, this will attempt to load them. If they
200 have already been loaded, this will return the cached
201 credentials.
202 """
203 return self._session.get_credentials()
205 def get_partition_for_region(self, region_name):
206 """Lists the partition name of a particular region.
208 :type region_name: string
209 :param region_name: Name of the region to list partition for (e.g.,
210 us-east-1).
212 :rtype: string
213 :return: Returns the respective partition name (e.g., aws).
214 """
215 return self._session.get_partition_for_region(region_name)
217 def client(
218 self,
219 service_name,
220 region_name=None,
221 api_version=None,
222 use_ssl=True,
223 verify=None,
224 endpoint_url=None,
225 aws_access_key_id=None,
226 aws_secret_access_key=None,
227 aws_session_token=None,
228 config=None,
229 ):
230 """
231 Create a low-level service client by name.
233 :type service_name: string
234 :param service_name: The name of a service, e.g. 's3' or 'ec2'. You
235 can get a list of available services via
236 :py:meth:`get_available_services`.
238 :type region_name: string
239 :param region_name: The name of the region associated with the client.
240 A client is associated with a single region.
242 :type api_version: string
243 :param api_version: The API version to use. By default, botocore will
244 use the latest API version when creating a client. You only need
245 to specify this parameter if you want to use a previous API version
246 of the client.
248 :type use_ssl: boolean
249 :param use_ssl: Whether or not to use SSL. By default, SSL is used.
250 Note that not all services support non-ssl connections.
252 :type verify: boolean/string
253 :param verify: Whether or not to verify SSL certificates. By default
254 SSL certificates are verified. You can provide the following
255 values:
257 * False - do not validate SSL certificates. SSL will still be
258 used (unless use_ssl is False), but SSL certificates
259 will not be verified.
260 * path/to/cert/bundle.pem - A filename of the CA cert bundle to
261 uses. You can specify this argument if you want to use a
262 different CA cert bundle than the one used by botocore.
264 :type endpoint_url: string
265 :param endpoint_url: The complete URL to use for the constructed
266 client. Normally, botocore will automatically construct the
267 appropriate URL to use when communicating with a service. You
268 can specify a complete URL (including the "http/https" scheme)
269 to override this behavior. If this value is provided,
270 then ``use_ssl`` is ignored.
272 :type aws_access_key_id: string
273 :param aws_access_key_id: The access key to use when creating
274 the client. This is entirely optional, and if not provided,
275 the credentials configured for the session will automatically
276 be used. You only need to provide this argument if you want
277 to override the credentials used for this specific client.
279 :type aws_secret_access_key: string
280 :param aws_secret_access_key: The secret key to use when creating
281 the client. Same semantics as aws_access_key_id above.
283 :type aws_session_token: string
284 :param aws_session_token: The session token to use when creating
285 the client. Same semantics as aws_access_key_id above.
287 :type config: botocore.client.Config
288 :param config: Advanced client configuration options. If region_name
289 is specified in the client config, its value will take precedence
290 over environment variables and configuration values, but not over
291 a region_name value passed explicitly to the method. See
292 `botocore config documentation
293 <https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html>`_
294 for more details.
296 :return: Service client instance
298 """
299 return self._session.create_client(
300 service_name,
301 region_name=region_name,
302 api_version=api_version,
303 use_ssl=use_ssl,
304 verify=verify,
305 endpoint_url=endpoint_url,
306 aws_access_key_id=aws_access_key_id,
307 aws_secret_access_key=aws_secret_access_key,
308 aws_session_token=aws_session_token,
309 config=config,
310 )
312 def resource(
313 self,
314 service_name,
315 region_name=None,
316 api_version=None,
317 use_ssl=True,
318 verify=None,
319 endpoint_url=None,
320 aws_access_key_id=None,
321 aws_secret_access_key=None,
322 aws_session_token=None,
323 config=None,
324 ):
325 """
326 Create a resource service client by name.
328 :type service_name: string
329 :param service_name: The name of a service, e.g. 's3' or 'ec2'. You
330 can get a list of available services via
331 :py:meth:`get_available_resources`.
333 :type region_name: string
334 :param region_name: The name of the region associated with the client.
335 A client is associated with a single region.
337 :type api_version: string
338 :param api_version: The API version to use. By default, botocore will
339 use the latest API version when creating a client. You only need
340 to specify this parameter if you want to use a previous API version
341 of the client.
343 :type use_ssl: boolean
344 :param use_ssl: Whether or not to use SSL. By default, SSL is used.
345 Note that not all services support non-ssl connections.
347 :type verify: boolean/string
348 :param verify: Whether or not to verify SSL certificates. By default
349 SSL certificates are verified. You can provide the following
350 values:
352 * False - do not validate SSL certificates. SSL will still be
353 used (unless use_ssl is False), but SSL certificates
354 will not be verified.
355 * path/to/cert/bundle.pem - A filename of the CA cert bundle to
356 uses. You can specify this argument if you want to use a
357 different CA cert bundle than the one used by botocore.
359 :type endpoint_url: string
360 :param endpoint_url: The complete URL to use for the constructed
361 client. Normally, botocore will automatically construct the
362 appropriate URL to use when communicating with a service. You
363 can specify a complete URL (including the "http/https" scheme)
364 to override this behavior. If this value is provided,
365 then ``use_ssl`` is ignored.
367 :type aws_access_key_id: string
368 :param aws_access_key_id: The access key to use when creating
369 the client. This is entirely optional, and if not provided,
370 the credentials configured for the session will automatically
371 be used. You only need to provide this argument if you want
372 to override the credentials used for this specific client.
374 :type aws_secret_access_key: string
375 :param aws_secret_access_key: The secret key to use when creating
376 the client. Same semantics as aws_access_key_id above.
378 :type aws_session_token: string
379 :param aws_session_token: The session token to use when creating
380 the client. Same semantics as aws_access_key_id above.
382 :type config: botocore.client.Config
383 :param config: Advanced client configuration options. If region_name
384 is specified in the client config, its value will take precedence
385 over environment variables and configuration values, but not over
386 a region_name value passed explicitly to the method. If
387 user_agent_extra is specified in the client config, it overrides
388 the default user_agent_extra provided by the resource API. See
389 `botocore config documentation
390 <https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html>`_
391 for more details.
393 :return: Subclass of :py:class:`~boto3.resources.base.ServiceResource`
394 """
395 try:
396 resource_model = self._loader.load_service_model(
397 service_name, 'resources-1', api_version
398 )
399 except UnknownServiceError:
400 available = self.get_available_resources()
401 has_low_level_client = (
402 service_name in self.get_available_services()
403 )
404 raise ResourceNotExistsError(
405 service_name, available, has_low_level_client
406 )
407 except DataNotFoundError:
408 # This is because we've provided an invalid API version.
409 available_api_versions = self._loader.list_api_versions(
410 service_name, 'resources-1'
411 )
412 raise UnknownAPIVersionError(
413 service_name, api_version, ', '.join(available_api_versions)
414 )
416 if api_version is None:
417 # Even though botocore's load_service_model() can handle
418 # using the latest api_version if not provided, we need
419 # to track this api_version in boto3 in order to ensure
420 # we're pairing a resource model with a client model
421 # of the same API version. It's possible for the latest
422 # API version of a resource model in boto3 to not be
423 # the same API version as a service model in botocore.
424 # So we need to look up the api_version if one is not
425 # provided to ensure we load the same API version of the
426 # client.
427 #
428 # Note: This is relying on the fact that
429 # loader.load_service_model(..., api_version=None)
430 # and loader.determine_latest_version(..., 'resources-1')
431 # both load the same api version of the file.
432 api_version = self._loader.determine_latest_version(
433 service_name, 'resources-1'
434 )
436 # Creating a new resource instance requires the low-level client
437 # and service model, the resource version and resource JSON data.
438 # We pass these to the factory and get back a class, which is
439 # instantiated on top of the low-level client.
440 if config is not None:
441 if config.user_agent_extra is None:
442 config = copy.deepcopy(config)
443 config.user_agent_extra = 'Resource'
444 else:
445 config = Config(user_agent_extra='Resource')
446 client = self.client(
447 service_name,
448 region_name=region_name,
449 api_version=api_version,
450 use_ssl=use_ssl,
451 verify=verify,
452 endpoint_url=endpoint_url,
453 aws_access_key_id=aws_access_key_id,
454 aws_secret_access_key=aws_secret_access_key,
455 aws_session_token=aws_session_token,
456 config=config,
457 )
458 service_model = client.meta.service_model
460 # Create a ServiceContext object to serve as a reference to
461 # important read-only information about the general service.
462 service_context = boto3.utils.ServiceContext(
463 service_name=service_name,
464 service_model=service_model,
465 resource_json_definitions=resource_model['resources'],
466 service_waiter_model=boto3.utils.LazyLoadedWaiterModel(
467 self._session, service_name, api_version
468 ),
469 )
471 # Create the service resource class.
472 cls = self.resource_factory.load_from_definition(
473 resource_name=service_name,
474 single_resource_json_definition=resource_model['service'],
475 service_context=service_context,
476 )
478 return cls(client=client)
480 def _register_default_handlers(self):
481 # S3 customizations
482 self._session.register(
483 'creating-client-class.s3',
484 boto3.utils.lazy_call(
485 'boto3.s3.inject.inject_s3_transfer_methods'
486 ),
487 )
488 self._session.register(
489 'creating-resource-class.s3.Bucket',
490 boto3.utils.lazy_call('boto3.s3.inject.inject_bucket_methods'),
491 )
492 self._session.register(
493 'creating-resource-class.s3.Object',
494 boto3.utils.lazy_call('boto3.s3.inject.inject_object_methods'),
495 )
496 self._session.register(
497 'creating-resource-class.s3.ObjectSummary',
498 boto3.utils.lazy_call(
499 'boto3.s3.inject.inject_object_summary_methods'
500 ),
501 )
503 # DynamoDb customizations
504 self._session.register(
505 'creating-resource-class.dynamodb',
506 boto3.utils.lazy_call(
507 'boto3.dynamodb.transform.register_high_level_interface'
508 ),
509 unique_id='high-level-dynamodb',
510 )
511 self._session.register(
512 'creating-resource-class.dynamodb.Table',
513 boto3.utils.lazy_call(
514 'boto3.dynamodb.table.register_table_methods'
515 ),
516 unique_id='high-level-dynamodb-table',
517 )
519 # EC2 Customizations
520 self._session.register(
521 'creating-resource-class.ec2.ServiceResource',
522 boto3.utils.lazy_call('boto3.ec2.createtags.inject_create_tags'),
523 )
525 self._session.register(
526 'creating-resource-class.ec2.Instance',
527 boto3.utils.lazy_call(
528 'boto3.ec2.deletetags.inject_delete_tags',
529 event_emitter=self.events,
530 ),
531 )