Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/boto3/session.py: 33%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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 = f'Botocore/{self._session.user_agent_version}'
67 if self._session.user_agent_extra:
68 self._session.user_agent_extra += ' ' + botocore_info
69 else:
70 self._session.user_agent_extra = botocore_info
71 self._session.user_agent_name = 'Boto3'
72 self._session.user_agent_version = boto3.__version__
74 if profile_name is not None:
75 self._session.set_config_variable('profile', profile_name)
77 if aws_access_key_id or aws_secret_access_key or aws_session_token:
78 self._session.set_credentials(
79 aws_access_key_id, aws_secret_access_key, aws_session_token
80 )
82 if region_name is not None:
83 self._session.set_config_variable('region', region_name)
85 self.resource_factory = ResourceFactory(
86 self._session.get_component('event_emitter')
87 )
88 self._setup_loader()
89 self._register_default_handlers()
91 def __repr__(self):
92 return '{}(region_name={})'.format(
93 self.__class__.__name__,
94 repr(self._session.get_config_variable('region')),
95 )
97 @property
98 def profile_name(self):
99 """
100 The **read-only** profile name.
101 """
102 return self._session.profile or 'default'
104 @property
105 def region_name(self):
106 """
107 The **read-only** region name.
108 """
109 return self._session.get_config_variable('region')
111 @property
112 def events(self):
113 """
114 The event emitter for a session
115 """
116 return self._session.get_component('event_emitter')
118 @property
119 def available_profiles(self):
120 """
121 The profiles available to the session credentials
122 """
123 return self._session.available_profiles
125 def _setup_loader(self):
126 """
127 Setup loader paths so that we can load resources.
128 """
129 self._loader = self._session.get_component('data_loader')
130 self._loader.search_paths.append(
131 os.path.join(os.path.dirname(__file__), 'data')
132 )
134 def get_available_services(self):
135 """
136 Get a list of available services that can be loaded as low-level
137 clients via :py:meth:`Session.client`.
139 :rtype: list
140 :return: List of service names
141 """
142 return self._session.get_available_services()
144 def get_available_resources(self):
145 """
146 Get a list of available services that can be loaded as resource
147 clients via :py:meth:`Session.resource`.
149 :rtype: list
150 :return: List of service names
151 """
152 return self._loader.list_available_services(type_name='resources-1')
154 def get_available_partitions(self):
155 """Lists the available partitions
157 :rtype: list
158 :return: Returns a list of partition names (e.g., ["aws", "aws-cn"])
159 """
160 return self._session.get_available_partitions()
162 def get_available_regions(
163 self, service_name, partition_name='aws', allow_non_regional=False
164 ):
165 """Lists the region and endpoint names of a particular partition.
167 The list of regions returned by this method are regions that are
168 explicitly known by the client to exist and is not comprehensive. A
169 region not returned in this list may still be available for the
170 provided service.
172 :type service_name: string
173 :param service_name: Name of a service to list endpoint for (e.g., s3).
175 :type partition_name: string
176 :param partition_name: Name of the partition to limit endpoints to.
177 (e.g., aws for the public AWS endpoints, aws-cn for AWS China
178 endpoints, aws-us-gov for AWS GovCloud (US) Endpoints, etc.)
180 :type allow_non_regional: bool
181 :param allow_non_regional: Set to True to include endpoints that are
182 not regional endpoints (e.g., s3-external-1,
183 fips-us-gov-west-1, etc).
185 :return: Returns a list of endpoint names (e.g., ["us-east-1"]).
186 """
187 return self._session.get_available_regions(
188 service_name=service_name,
189 partition_name=partition_name,
190 allow_non_regional=allow_non_regional,
191 )
193 def get_credentials(self):
194 """
195 Return the :class:`botocore.credentials.Credentials` object
196 associated with this session. If the credentials have not
197 yet been loaded, this will attempt to load them. If they
198 have already been loaded, this will return the cached
199 credentials.
200 """
201 return self._session.get_credentials()
203 def get_partition_for_region(self, region_name):
204 """Lists the partition name of a particular region.
206 :type region_name: string
207 :param region_name: Name of the region to list partition for (e.g.,
208 us-east-1).
210 :rtype: string
211 :return: Returns the respective partition name (e.g., aws).
212 """
213 return self._session.get_partition_for_region(region_name)
215 def client(
216 self,
217 service_name,
218 region_name=None,
219 api_version=None,
220 use_ssl=True,
221 verify=None,
222 endpoint_url=None,
223 aws_access_key_id=None,
224 aws_secret_access_key=None,
225 aws_session_token=None,
226 config=None,
227 ):
228 """
229 Create a low-level service client by name.
231 :type service_name: string
232 :param service_name: The name of a service, e.g. 's3' or 'ec2'. You
233 can get a list of available services via
234 :py:meth:`get_available_services`.
236 :type region_name: string
237 :param region_name: The name of the region associated with the client.
238 A client is associated with a single region.
240 :type api_version: string
241 :param api_version: The API version to use. By default, botocore will
242 use the latest API version when creating a client. You only need
243 to specify this parameter if you want to use a previous API version
244 of the client.
246 :type use_ssl: boolean
247 :param use_ssl: Whether or not to use SSL. By default, SSL is used.
248 Note that not all services support non-ssl connections.
250 :type verify: boolean/string
251 :param verify: Whether or not to verify SSL certificates. By default
252 SSL certificates are verified. You can provide the following
253 values:
255 * False - do not validate SSL certificates. SSL will still be
256 used (unless use_ssl is False), but SSL certificates
257 will not be verified.
258 * path/to/cert/bundle.pem - A filename of the CA cert bundle to
259 uses. You can specify this argument if you want to use a
260 different CA cert bundle than the one used by botocore.
262 :type endpoint_url: string
263 :param endpoint_url: The complete URL to use for the constructed
264 client. Normally, botocore will automatically construct the
265 appropriate URL to use when communicating with a service. You
266 can specify a complete URL (including the "http/https" scheme)
267 to override this behavior. If this value is provided,
268 then ``use_ssl`` is ignored.
270 :type aws_access_key_id: string
271 :param aws_access_key_id: The access key to use when creating
272 the client. This is entirely optional, and if not provided,
273 the credentials configured for the session will automatically
274 be used. You only need to provide this argument if you want
275 to override the credentials used for this specific client.
277 :type aws_secret_access_key: string
278 :param aws_secret_access_key: The secret key to use when creating
279 the client. Same semantics as aws_access_key_id above.
281 :type aws_session_token: string
282 :param aws_session_token: The session token to use when creating
283 the client. Same semantics as aws_access_key_id above.
285 :type config: botocore.client.Config
286 :param config: Advanced client configuration options. If region_name
287 is specified in the client config, its value will take precedence
288 over environment variables and configuration values, but not over
289 a region_name value passed explicitly to the method. See
290 `botocore config documentation
291 <https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html>`_
292 for more details.
294 :return: Service client instance
296 """
297 return self._session.create_client(
298 service_name,
299 region_name=region_name,
300 api_version=api_version,
301 use_ssl=use_ssl,
302 verify=verify,
303 endpoint_url=endpoint_url,
304 aws_access_key_id=aws_access_key_id,
305 aws_secret_access_key=aws_secret_access_key,
306 aws_session_token=aws_session_token,
307 config=config,
308 )
310 def resource(
311 self,
312 service_name,
313 region_name=None,
314 api_version=None,
315 use_ssl=True,
316 verify=None,
317 endpoint_url=None,
318 aws_access_key_id=None,
319 aws_secret_access_key=None,
320 aws_session_token=None,
321 config=None,
322 ):
323 """
324 Create a resource service client by name.
326 :type service_name: string
327 :param service_name: The name of a service, e.g. 's3' or 'ec2'. You
328 can get a list of available services via
329 :py:meth:`get_available_resources`.
331 :type region_name: string
332 :param region_name: The name of the region associated with the client.
333 A client is associated with a single region.
335 :type api_version: string
336 :param api_version: The API version to use. By default, botocore will
337 use the latest API version when creating a client. You only need
338 to specify this parameter if you want to use a previous API version
339 of the client.
341 :type use_ssl: boolean
342 :param use_ssl: Whether or not to use SSL. By default, SSL is used.
343 Note that not all services support non-ssl connections.
345 :type verify: boolean/string
346 :param verify: Whether or not to verify SSL certificates. By default
347 SSL certificates are verified. You can provide the following
348 values:
350 * False - do not validate SSL certificates. SSL will still be
351 used (unless use_ssl is False), but SSL certificates
352 will not be verified.
353 * path/to/cert/bundle.pem - A filename of the CA cert bundle to
354 uses. You can specify this argument if you want to use a
355 different CA cert bundle than the one used by botocore.
357 :type endpoint_url: string
358 :param endpoint_url: The complete URL to use for the constructed
359 client. Normally, botocore will automatically construct the
360 appropriate URL to use when communicating with a service. You
361 can specify a complete URL (including the "http/https" scheme)
362 to override this behavior. If this value is provided,
363 then ``use_ssl`` is ignored.
365 :type aws_access_key_id: string
366 :param aws_access_key_id: The access key to use when creating
367 the client. This is entirely optional, and if not provided,
368 the credentials configured for the session will automatically
369 be used. You only need to provide this argument if you want
370 to override the credentials used for this specific client.
372 :type aws_secret_access_key: string
373 :param aws_secret_access_key: The secret key to use when creating
374 the client. Same semantics as aws_access_key_id above.
376 :type aws_session_token: string
377 :param aws_session_token: The session token to use when creating
378 the client. Same semantics as aws_access_key_id above.
380 :type config: botocore.client.Config
381 :param config: Advanced client configuration options. If region_name
382 is specified in the client config, its value will take precedence
383 over environment variables and configuration values, but not over
384 a region_name value passed explicitly to the method. If
385 user_agent_extra is specified in the client config, it overrides
386 the default user_agent_extra provided by the resource API. See
387 `botocore config documentation
388 <https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html>`_
389 for more details.
391 :return: Subclass of :py:class:`~boto3.resources.base.ServiceResource`
392 """
393 try:
394 resource_model = self._loader.load_service_model(
395 service_name, 'resources-1', api_version
396 )
397 except UnknownServiceError:
398 available = self.get_available_resources()
399 has_low_level_client = (
400 service_name in self.get_available_services()
401 )
402 raise ResourceNotExistsError(
403 service_name, available, has_low_level_client
404 )
405 except DataNotFoundError:
406 # This is because we've provided an invalid API version.
407 available_api_versions = self._loader.list_api_versions(
408 service_name, 'resources-1'
409 )
410 raise UnknownAPIVersionError(
411 service_name, api_version, ', '.join(available_api_versions)
412 )
414 if api_version is None:
415 # Even though botocore's load_service_model() can handle
416 # using the latest api_version if not provided, we need
417 # to track this api_version in boto3 in order to ensure
418 # we're pairing a resource model with a client model
419 # of the same API version. It's possible for the latest
420 # API version of a resource model in boto3 to not be
421 # the same API version as a service model in botocore.
422 # So we need to look up the api_version if one is not
423 # provided to ensure we load the same API version of the
424 # client.
425 #
426 # Note: This is relying on the fact that
427 # loader.load_service_model(..., api_version=None)
428 # and loader.determine_latest_version(..., 'resources-1')
429 # both load the same api version of the file.
430 api_version = self._loader.determine_latest_version(
431 service_name, 'resources-1'
432 )
434 # Creating a new resource instance requires the low-level client
435 # and service model, the resource version and resource JSON data.
436 # We pass these to the factory and get back a class, which is
437 # instantiated on top of the low-level client.
438 if config is not None:
439 if config.user_agent_extra is None:
440 config = copy.deepcopy(config)
441 config.user_agent_extra = 'Resource'
442 else:
443 config = Config(user_agent_extra='Resource')
444 client = self.client(
445 service_name,
446 region_name=region_name,
447 api_version=api_version,
448 use_ssl=use_ssl,
449 verify=verify,
450 endpoint_url=endpoint_url,
451 aws_access_key_id=aws_access_key_id,
452 aws_secret_access_key=aws_secret_access_key,
453 aws_session_token=aws_session_token,
454 config=config,
455 )
456 service_model = client.meta.service_model
458 # Create a ServiceContext object to serve as a reference to
459 # important read-only information about the general service.
460 service_context = boto3.utils.ServiceContext(
461 service_name=service_name,
462 service_model=service_model,
463 resource_json_definitions=resource_model['resources'],
464 service_waiter_model=boto3.utils.LazyLoadedWaiterModel(
465 self._session, service_name, api_version
466 ),
467 )
469 # Create the service resource class.
470 cls = self.resource_factory.load_from_definition(
471 resource_name=service_name,
472 single_resource_json_definition=resource_model['service'],
473 service_context=service_context,
474 )
476 return cls(client=client)
478 def _register_default_handlers(self):
479 # S3 customizations
480 self._session.register(
481 'creating-client-class.s3',
482 boto3.utils.lazy_call(
483 'boto3.s3.inject.inject_s3_transfer_methods'
484 ),
485 )
486 self._session.register(
487 'creating-resource-class.s3.Bucket',
488 boto3.utils.lazy_call('boto3.s3.inject.inject_bucket_methods'),
489 )
490 self._session.register(
491 'creating-resource-class.s3.Object',
492 boto3.utils.lazy_call('boto3.s3.inject.inject_object_methods'),
493 )
494 self._session.register(
495 'creating-resource-class.s3.ObjectSummary',
496 boto3.utils.lazy_call(
497 'boto3.s3.inject.inject_object_summary_methods'
498 ),
499 )
501 # DynamoDb customizations
502 self._session.register(
503 'creating-resource-class.dynamodb',
504 boto3.utils.lazy_call(
505 'boto3.dynamodb.transform.register_high_level_interface'
506 ),
507 unique_id='high-level-dynamodb',
508 )
509 self._session.register(
510 'creating-resource-class.dynamodb.Table',
511 boto3.utils.lazy_call(
512 'boto3.dynamodb.table.register_table_methods'
513 ),
514 unique_id='high-level-dynamodb-table',
515 )
517 # EC2 Customizations
518 self._session.register(
519 'creating-resource-class.ec2.ServiceResource',
520 boto3.utils.lazy_call('boto3.ec2.createtags.inject_create_tags'),
521 )
523 self._session.register(
524 'creating-resource-class.ec2.Instance',
525 boto3.utils.lazy_call(
526 'boto3.ec2.deletetags.inject_delete_tags',
527 event_emitter=self.events,
528 ),
529 )