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

92 statements  

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. 

13 

14import copy 

15import os 

16 

17import botocore.session 

18from botocore.client import Config 

19from botocore.exceptions import DataNotFoundError, UnknownServiceError 

20 

21import boto3 

22import boto3.utils 

23from boto3.exceptions import ResourceNotExistsError, UnknownAPIVersionError 

24 

25from .resources.factory import ResourceFactory 

26 

27 

28class Session: 

29 """ 

30 A session stores configuration state and allows you to create service 

31 clients and resources. 

32 

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 """ 

48 

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() 

63 

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__ 

73 

74 if profile_name is not None: 

75 self._session.set_config_variable('profile', profile_name) 

76 

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 ) 

81 

82 if region_name is not None: 

83 self._session.set_config_variable('region', region_name) 

84 

85 self.resource_factory = ResourceFactory( 

86 self._session.get_component('event_emitter') 

87 ) 

88 self._setup_loader() 

89 self._register_default_handlers() 

90 

91 def __repr__(self): 

92 return '{}(region_name={})'.format( 

93 self.__class__.__name__, 

94 repr(self._session.get_config_variable('region')), 

95 ) 

96 

97 @property 

98 def profile_name(self): 

99 """ 

100 The **read-only** profile name. 

101 """ 

102 return self._session.profile or 'default' 

103 

104 @property 

105 def region_name(self): 

106 """ 

107 The **read-only** region name. 

108 """ 

109 return self._session.get_config_variable('region') 

110 

111 @property 

112 def events(self): 

113 """ 

114 The event emitter for a session 

115 """ 

116 return self._session.get_component('event_emitter') 

117 

118 @property 

119 def available_profiles(self): 

120 """ 

121 The profiles available to the session credentials 

122 """ 

123 return self._session.available_profiles 

124 

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 ) 

133 

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`. 

138 

139 :rtype: list 

140 :return: List of service names 

141 """ 

142 return self._session.get_available_services() 

143 

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`. 

148 

149 :rtype: list 

150 :return: List of service names 

151 """ 

152 return self._loader.list_available_services(type_name='resources-1') 

153 

154 def get_available_partitions(self): 

155 """Lists the available partitions 

156 

157 :rtype: list 

158 :return: Returns a list of partition names (e.g., ["aws", "aws-cn"]) 

159 """ 

160 return self._session.get_available_partitions() 

161 

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. 

166 

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. 

171 

172 :type service_name: string 

173 :param service_name: Name of a service to list endpoint for (e.g., s3). 

174 

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.) 

179 

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). 

184 

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 ) 

192 

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() 

202 

203 def get_partition_for_region(self, region_name): 

204 """Lists the partition name of a particular region. 

205 

206 :type region_name: string 

207 :param region_name: Name of the region to list partition for (e.g., 

208 us-east-1). 

209 

210 :rtype: string 

211 :return: Returns the respective partition name (e.g., aws). 

212 """ 

213 return self._session.get_partition_for_region(region_name) 

214 

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. 

230 

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`. 

235 

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. 

239 

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. 

245 

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. 

249 

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: 

254 

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. 

261 

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. 

269 

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. 

276 

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. 

280 

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. 

284 

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. 

293 

294 :return: Service client instance 

295 

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 ) 

309 

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. 

325 

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`. 

330 

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. 

334 

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. 

340 

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. 

344 

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: 

349 

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. 

356 

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. 

364 

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. 

371 

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. 

375 

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. 

379 

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. 

390 

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 ) 

413 

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 ) 

433 

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 

457 

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 ) 

468 

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 ) 

475 

476 return cls(client=client) 

477 

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 ) 

500 

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 ) 

516 

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 ) 

522 

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 )