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

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 = '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__ 

75 

76 if profile_name is not None: 

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

78 

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 ) 

83 

84 if region_name is not None: 

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

86 

87 self.resource_factory = ResourceFactory( 

88 self._session.get_component('event_emitter') 

89 ) 

90 self._setup_loader() 

91 self._register_default_handlers() 

92 

93 def __repr__(self): 

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

95 self.__class__.__name__, 

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

97 ) 

98 

99 @property 

100 def profile_name(self): 

101 """ 

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

103 """ 

104 return self._session.profile or 'default' 

105 

106 @property 

107 def region_name(self): 

108 """ 

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

110 """ 

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

112 

113 @property 

114 def events(self): 

115 """ 

116 The event emitter for a session 

117 """ 

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

119 

120 @property 

121 def available_profiles(self): 

122 """ 

123 The profiles available to the session credentials 

124 """ 

125 return self._session.available_profiles 

126 

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 ) 

135 

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

140 

141 :rtype: list 

142 :return: List of service names 

143 """ 

144 return self._session.get_available_services() 

145 

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

150 

151 :rtype: list 

152 :return: List of service names 

153 """ 

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

155 

156 def get_available_partitions(self): 

157 """Lists the available partitions 

158 

159 :rtype: list 

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

161 """ 

162 return self._session.get_available_partitions() 

163 

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. 

168 

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. 

173 

174 :type service_name: string 

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

176 

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

181 

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

186 

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 ) 

194 

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

204 

205 def get_partition_for_region(self, region_name): 

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

207 

208 :type region_name: string 

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

210 us-east-1). 

211 

212 :rtype: string 

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

214 """ 

215 return self._session.get_partition_for_region(region_name) 

216 

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. 

232 

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

237 

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. 

241 

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. 

247 

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. 

251 

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: 

256 

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. 

263 

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. 

271 

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. 

278 

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. 

282 

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. 

286 

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. 

295 

296 :return: Service client instance 

297 

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 ) 

311 

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. 

327 

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

332 

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. 

336 

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. 

342 

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. 

346 

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: 

351 

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. 

358 

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. 

366 

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. 

373 

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. 

377 

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. 

381 

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. 

392 

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 ) 

415 

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 ) 

435 

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 

459 

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 ) 

470 

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 ) 

477 

478 return cls(client=client) 

479 

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 ) 

502 

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 ) 

518 

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 ) 

524 

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 )