def test_connect_disconnect_with_default_singletons(self): connection = self._create_connection(use_static_singletons=True) connection.connect().result(TIMEOUT) connection.disconnect().result(TIMEOUT) # free singletons ClientBootstrap.release_static_default() EventLoopGroup.release_static_default() DefaultHostResolver.release_static_default()
def _initialize_default_loop(self): event_loop_group = EventLoopGroup(1) host_resolver = DefaultHostResolver(event_loop_group) return ClientBootstrap( event_loop_group, host_resolver, )
def test_closes_on_zero_refcount(self): self.skipTest("Skipping until we have permanent echo server") elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) handler = SimpleHandler() future = EventStreamRpcClientConnection.connect( handler=handler, host_name="127.0.0.1", port=8033, bootstrap=bootstrap) # connection should succeed self.assertIsNone(future.exception(TIMEOUT)) # grab pointers to stuff that will tell us about how shutdown went, record = handler.record shutdown_future = handler.connection.shutdown_future # connection should shut itself down when all references are released. # the shutdown_future should complete, but the handler's shutdown # callback should not fire in this test because the handler has been deleted. del handler self.assertIsNone(shutdown_future.exception(TIMEOUT)) self.assertIsNone( record.shutdown_call, "on_connection_shutdown shouldn't fire if handler is garbage collected before connection finishes shutdown") self.assertIsNone(record.failure)
def test_mtls_from_path(self): config = Config.get() elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) # test "from path" builder by writing secrets to tempfiles tmp_dirpath = tempfile.mkdtemp() try: cert_filepath = os.path.join(tmp_dirpath, 'cert') with open(cert_filepath, 'wb') as cert_file: cert_file.write(config.cert) key_filepath = os.path.join(tmp_dirpath, 'key') with open(key_filepath, 'wb') as key_file: key_file.write(config.key) connection = awsiot_mqtt_connection_builder.mtls_from_path( cert_filepath=cert_filepath, pri_key_filepath=key_filepath, endpoint=config.endpoint, client_id=create_client_id(), client_bootstrap=bootstrap) finally: shutil.rmtree(tmp_dirpath) self._test_connection(connection)
def test_connect_success(self): elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) handler = ConnectionHandler(self._fail_test_from_callback) future = ClientConnection.connect(handler=handler, host_name="127.0.0.1", port=8033, bootstrap=bootstrap) self.assertIsNone(future.exception(TIMEOUT)) self.assertIsNotNone(handler.record.setup_call) self.assertTrue( isinstance(handler.record.setup_call['connection'], ClientConnection)) self.assertIsNone(handler.record.setup_call['error']) self.assertTrue(handler.connection.is_open()) self.assertIsNone(handler.record.shutdown_call) # close shutdown_future = handler.connection.close() self.assertIsNone(shutdown_future.exception(TIMEOUT)) self.assertIsNotNone(handler.record.shutdown_call) self.assertIsNone(handler.record.shutdown_call['reason']) self._assertNoFailuresFromCallbacks()
def new_default_chain(cls, client_bootstrap=None): """ Create the default provider chain used by most AWS SDKs. Generally: 1. Environment 2. Profile 3. (conditional, off by default) ECS 4. (conditional, on by default) EC2 Instance Metadata Args: client_bootstrap (Optional[ClientBootstrap]): Client bootstrap to use when initiating socket connection. If not set, uses the default static ClientBootstrap instead. Returns: AwsCredentialsProvider: """ assert isinstance(client_bootstrap, ClientBootstrap) or client_bootstrap is None if client_bootstrap is None: client_bootstrap = ClientBootstrap.get_or_create_static_default() binding = _awscrt.credentials_provider_new_chain_default( client_bootstrap) return cls(binding)
def _connect_fully(self): # connect, send CONNECT message, receive CONNECT_ACK elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) handler = ConnectionHandler(self._fail_test_from_callback) connect_future = ClientConnection.connect(handler=handler, host_name="127.0.0.1", port=8033, bootstrap=bootstrap) self.assertIsNone(connect_future.exception(TIMEOUT)) # send CONNECT msg msg_future = handler.connection.send_protocol_message( message_type=MessageType.CONNECT, headers=[ Header.from_string(':version', '0.1.0'), Header.from_string('client-name', 'accepted.testy_mc_testerson') ]) self.assertIsNone(msg_future.exception(TIMEOUT)) # wait to receive CONNECT_ACK msg = handler.record.message_calls.get(timeout=TIMEOUT) self.assertIs(MessageType.CONNECT_ACK, msg['message_type']) self.assertTrue(MessageFlag.CONNECTION_ACCEPTED & msg['flags']) return handler
def test_echo(self): self.skipTest("Skipping until we have permanent echo server") elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) handler = SimpleHandler() connect_future = EventStreamRpcClientConnection.connect( handler=handler, host_name="127.0.0.1", port=8033, bootstrap=bootstrap) self.assertIsNone(connect_future.exception(TIMEOUT)) # send CONNECT msg msg_future = handler.connection.send_protocol_message( message_type=EventStreamRpcMessageType.CONNECT, headers=[EventStreamHeader.from_string(':version', '0.1.0'), EventStreamHeader.from_string('client-name', 'accepted.testy_mc_testerson')]) self.assertIsNone(msg_future.exception(TIMEOUT)) # wait to receive CONNECT_ACK msg = handler.record.message_calls.get(timeout=TIMEOUT) self.assertIs(EventStreamRpcMessageType.CONNECT_ACK, msg['message_type']) self.assertTrue(EventStreamRpcMessageFlag.CONNECTION_ACCEPTED & msg['flags']) # send PING msg, server will echo back its headers and payload in the PING_RESPONSE. # test every single header type echo_headers = [ EventStreamHeader.from_bool('echo-true', True), EventStreamHeader.from_bool('echo-false', False), EventStreamHeader.from_byte('echo-byte', 127), EventStreamHeader.from_int16('echo-int16', 32000), EventStreamHeader.from_int32('echo-int32', 2000000000), EventStreamHeader.from_int64('echo-int64', 999999999999), EventStreamHeader.from_byte_buf('echo-byte-buf', b'\x00\xff\x0f\xf0'), EventStreamHeader.from_string('echo-string', 'noodles'), EventStreamHeader.from_timestamp('echo-timestamp', time.time()), EventStreamHeader.from_uuid('echo-uuid', UUID('01234567-89ab-cdef-0123-456789abcdef')), ] echo_payload = b'\x00\xDE\xAD\xBE\xEF' msg_future = handler.connection.send_protocol_message( message_type=EventStreamRpcMessageType.PING, headers=echo_headers, payload=echo_payload) self.assertIsNone(msg_future.exception(TIMEOUT)) # wait to receive PING_RESPONSE, which should echo what we sent msg = handler.record.message_calls.get(timeout=TIMEOUT) self.assertIs(EventStreamRpcMessageType.PING_RESPONSE, msg['message_type']) for sent_header in echo_headers: recv_header = next(x for x in msg['headers'] if x.name.lower() == sent_header.name.lower()) self.assertEqual(sent_header.type, recv_header.type) self.assertEqual(sent_header.value, recv_header.value) self.assertEqual(echo_payload, msg['payload']) self.assertIsNone(handler.record.failure)
def test_create_destroy(self): event_loop_group = EventLoopGroup() host_resolver = DefaultHostResolver(event_loop_group) bootstrap = ClientBootstrap(event_loop_group, host_resolver) # ensure shutdown_event fires bootstrap_shutdown_event = bootstrap.shutdown_event del bootstrap self.assertTrue(bootstrap_shutdown_event.wait(TIMEOUT))
def __init__(self, bootstrap=None, tls_ctx=None): assert isinstance(bootstrap, ClientBootstrap) or bootstrap is None assert tls_ctx is None or isinstance(tls_ctx, ClientTlsContext) super().__init__() self.tls_ctx = tls_ctx if not bootstrap: bootstrap = ClientBootstrap.get_or_create_static_default() self._binding = _awscrt.mqtt_client_new(bootstrap, tls_ctx)
def connect( cls, *, handler: ClientConnectionHandler, host_name: str, port: int, bootstrap: ClientBootstrap = None, socket_options: Optional[SocketOptions] = None, tls_connection_options: Optional[TlsConnectionOptions] = None ) -> 'concurrent.futures.Future': """Asynchronously establish a new ClientConnection. Args: handler: Handler for connection events. host_name: Connect to host. port: Connect to port. bootstrap: Client bootstrap to use when initiating socket connection. If None is provided, the default singleton is used. socket_options: Optional socket options. If None is provided, then default options are used. tls_connection_options: Optional TLS connection options. If None is provided, then the connection will be attempted over plain-text. Returns: concurrent.futures.Future: A Future which completes when the connection succeeds or fails. If successful, the Future will contain None. Otherwise it will contain an exception. If the connection is successful, it will be made available via the handler's on_connection_setup callback. Note that this network connection stays alive until it is closed, even if no local references to the connection object remain. The user should store a reference to any connections, and call :meth:`close()` when they are done with them to avoid leaking resources. """ if not socket_options: socket_options = SocketOptions() # Connection is not made available to user until setup callback fires connection = cls(host_name, port, handler) if not bootstrap: bootstrap = ClientBootstrap.get_or_create_static_default() # connection._binding is set within the following call */ _awscrt.event_stream_rpc_client_connection_connect( host_name, port, bootstrap, socket_options, tls_connection_options, connection) return connection._connect_future
def test_on_message_old_fn_signature(self): # ensure that message-received callbacks with the old function signature still work config = Config.get() elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) tls_opts = TlsContextOptions.create_client_with_mtls( config.cert, config.key) tls = ClientTlsContext(tls_opts) client = Client(bootstrap, tls) connection = Connection(client=client, client_id=create_client_id(), host_name=config.endpoint, port=8883) any_received = Future() sub_received = Future() # Note: Testing degenerate callback signature that failed to take # forward-compatibility **kwargs. def on_any_message(topic, payload): any_received.set_result({'topic': topic, 'payload': payload}) def on_sub_message(topic, payload): sub_received.set_result({'topic': topic, 'payload': payload}) # on_message for connection has to be set before connect, or possible race will happen connection.on_message(on_any_message) connection.connect().result(TIMEOUT) # subscribe without callback subscribed, packet_id = connection.subscribe(self.TEST_TOPIC, QoS.AT_LEAST_ONCE, on_sub_message) subscribed.result(TIMEOUT) # publish published, packet_id = connection.publish(self.TEST_TOPIC, self.TEST_MSG, QoS.AT_LEAST_ONCE) puback = published.result(TIMEOUT) # receive message rcv = any_received.result(TIMEOUT) self.assertEqual(self.TEST_TOPIC, rcv['topic']) self.assertEqual(self.TEST_MSG, rcv['payload']) rcv = sub_received.result(TIMEOUT) self.assertEqual(self.TEST_TOPIC, rcv['topic']) self.assertEqual(self.TEST_MSG, rcv['payload']) # disconnect connection.disconnect().result(TIMEOUT)
def test_mtls_from_bytes(self): config = Config.get() elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) connection = awsiot_mqtt_connection_builder.mtls_from_bytes( cert_bytes=config.cert, pri_key_bytes=config.key, endpoint=config.endpoint, client_id=create_client_id(), client_bootstrap=bootstrap) self._test_connection(connection)
def __init__( self, *, bootstrap, region, tls_mode=None, credential_provider=None, tls_connection_options=None, part_size=None, throughput_target_gbps=None): assert isinstance(bootstrap, ClientBootstrap) or bootstrap is None assert isinstance(region, str) assert isinstance(credential_provider, AwsCredentialsProvider) or credential_provider is None assert isinstance(tls_connection_options, TlsConnectionOptions) or tls_connection_options is None assert isinstance(part_size, int) or part_size is None assert isinstance( throughput_target_gbps, int) or isinstance( throughput_target_gbps, float) or throughput_target_gbps is None super().__init__() shutdown_event = threading.Event() def on_shutdown(): shutdown_event.set() self._region = region self.shutdown_event = shutdown_event if not bootstrap: bootstrap = ClientBootstrap.get_or_create_static_default() s3_client_core = _S3ClientCore(bootstrap, credential_provider, tls_connection_options) # C layer uses 0 to indicate defaults if tls_mode is None: tls_mode = 0 if part_size is None: part_size = 0 if throughput_target_gbps is None: throughput_target_gbps = 0 self._binding = _awscrt.s3_client_new( bootstrap, credential_provider, tls_connection_options, on_shutdown, region, tls_mode, part_size, throughput_target_gbps, s3_client_core)
def test_websockets_default(self): config = Config.get() elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) cred_provider = AwsCredentialsProvider.new_default_chain(bootstrap) connection = awsiot_mqtt_connection_builder.websockets_with_default_aws_signing( region=config.region, credentials_provider=cred_provider, endpoint=config.endpoint, client_id=create_client_id(), client_bootstrap=bootstrap) self._test_connection(connection)
def _establish_http_connection(self, test_type, uri, proxy_options): event_loop_group = EventLoopGroup() host_resolver = DefaultHostResolver(event_loop_group) bootstrap = ClientBootstrap(event_loop_group, host_resolver) connection_future = HttpClientConnection.new( host_name=uri, port=ProxyTestConfiguration.get_port_from_test_type(test_type), bootstrap=bootstrap, tls_connection_options=ProxyTestConfiguration. get_tls_connection_options_for_test(test_type, uri), proxy_options=proxy_options) return connection_future.result(TIMEOUT)
def test_websockets_proxy(self): config = Config.get() elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) cred_provider = AwsCredentialsProvider.new_default_chain(bootstrap) connection = mqtt_connection_builder.websockets_with_default_aws_signing( credentials_provider=cred_provider, websocket_proxy_options=HttpProxyOptions(PROXY_HOST, PROXY_PORT), endpoint=config.endpoint, region=config.region, client_id=create_client_id(), client_bootstrap=bootstrap) self._test_connection(connection)
def _connect_and_return_weakref(self): elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) handler = ConnectionHandler(self._fail_test_from_callback) future = ClientConnection.connect(handler=handler, host_name="127.0.0.1", port=8033, bootstrap=bootstrap) # connection should succeed self.assertIsNone(future.exception(TIMEOUT)) return weakref.ref(handler.connection)
def connect(*, ipc_socket: str = None, authtoken: str = None, lifecycle_handler: Optional[LifecycleHandler] = None, timeout=10.0) -> GreengrassCoreIPCClient: """ Creates an IPC client and connects to the GreengrassCoreIPC service. Args: ipc_socket: Path to the Unix domain socket of Greengrass Nucleus, defaults to environment variable AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT authtoken: Authentication token, defaults to environment variable SVCUID lifecycle_handler: Handler for events over the course of this network connection. See :class:`LifecycleHandler` for more info. Handler methods will only be invoked if the connect attempt succeeds. timeout: The number of seconds to wait for establishing the connection. Returns: Client for the GreengrassCoreIPC service. """ if not ipc_socket: ipc_socket = os.environ[ "AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT"] if not authtoken: authtoken = os.environ["SVCUID"] if not lifecycle_handler: lifecycle_handler = LifecycleHandler() elg = EventLoopGroup(num_threads=1) resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) socket_options = SocketOptions() socket_options.domain = SocketDomain.Local amender = MessageAmendment.create_static_authtoken_amender(authtoken) connection = Connection( host_name=ipc_socket, port=0, # dummy port number, not needed for Unix domain sockets bootstrap=bootstrap, socket_options=socket_options, connect_message_amender=amender, ) connect_future = connection.connect(lifecycle_handler) connect_future.result(timeout) return GreengrassCoreIPCClient(connection)
def test_connect_failure(self): elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) handler = SimpleHandler() future = EventStreamRpcClientConnection.connect( handler=handler, host_name="fake", port=99, bootstrap=bootstrap) failure = future.exception(TIMEOUT) self.assertTrue(isinstance(failure, Exception)) self.assertIsNone(handler.record.setup_call) self.assertIsNone(handler.record.shutdown_call) self.assertIsNone(handler.record.failure)
def test_websockets_sts(self): """Websocket connection with X-Amz-Security-Token query param""" config = Config.get() elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) cred_provider = AwsCredentialsProvider.new_static( access_key_id=config.cognito_creds['AccessKeyId'], secret_access_key=config.cognito_creds['SecretKey'], session_token=config.cognito_creds['SessionToken']) connection = awsiot_mqtt_connection_builder.websockets_with_default_aws_signing( region=config.region, credentials_provider=cred_provider, endpoint=config.endpoint, client_id=create_client_id(), client_bootstrap=bootstrap) self._test_connection(connection)
def _test_connection(self): config = Config.get() elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) tls_opts = TlsContextOptions.create_client_with_mtls( config.cert, config.key) tls = ClientTlsContext(tls_opts) client = Client(bootstrap, tls) connection = Connection(client=client, client_id=create_client_id(), host_name=config.endpoint, port=8883) connection.connect().result(TIMEOUT) return connection
def test_on_message(self): config = Config.get() elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) tls_opts = TlsContextOptions.create_client_with_mtls( config.cert, config.key) tls = ClientTlsContext(tls_opts) client = Client(bootstrap, tls) connection = Connection(client=client, client_id=create_client_id(), host_name=config.endpoint, port=8883) received = Future() def on_message(**kwargs): received.set_result(kwargs) # on_message for connection has to be set before connect, or possible race will happen connection.on_message(on_message) connection.connect().result(TIMEOUT) # subscribe without callback subscribed, packet_id = connection.subscribe(self.TEST_TOPIC, QoS.AT_LEAST_ONCE) subscribed.result(TIMEOUT) # publish published, packet_id = connection.publish(self.TEST_TOPIC, self.TEST_MSG, QoS.AT_LEAST_ONCE) puback = published.result(TIMEOUT) # receive message rcv = received.result(TIMEOUT) self.assertEqual(self.TEST_TOPIC, rcv['topic']) self.assertEqual(self.TEST_MSG, rcv['payload']) self.assertFalse(rcv['dup']) self.assertEqual(QoS.AT_LEAST_ONCE, rcv['qos']) self.assertFalse(rcv['retain']) # disconnect connection.disconnect().result(TIMEOUT)
def test_connect_failure(self): elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) handler = ConnectionHandler(self._fail_test_from_callback) future = ClientConnection.connect(handler=handler, host_name="fake", port=99, bootstrap=bootstrap) failure = future.exception(TIMEOUT) self.assertTrue(isinstance(failure, Exception)) self.assertIsNotNone(handler.record.setup_call) self.assertIsNone(handler.record.setup_call['connection']) self.assertTrue( isinstance(handler.record.setup_call['error'], Exception)) self.assertIsNone(handler.record.shutdown_call) self._assertNoFailuresFromCallbacks()
def _new_h2_client_connection(self, url): event_loop_group = EventLoopGroup() host_resolver = DefaultHostResolver(event_loop_group) bootstrap = ClientBootstrap(event_loop_group, host_resolver) port = 443 scheme = 'https' tls_ctx_options = TlsContextOptions() tls_ctx = ClientTlsContext(tls_ctx_options) tls_conn_opt = tls_ctx.new_connection_options() tls_conn_opt.set_server_name(url.hostname) tls_conn_opt.set_alpn_list(["h2"]) connection_future = HttpClientConnection.new(host_name=url.hostname, port=port, bootstrap=bootstrap, tls_connection_options=tls_conn_opt) return connection_future.result(self.timeout)
def _create_connection(self, auth_type=AuthType.CERT_AND_KEY, use_static_singletons=False): config = Config(auth_type) if auth_type == AuthType.CERT_AND_KEY: tls_opts = TlsContextOptions.create_client_with_mtls_from_path(config.cert_path, config.key_path) tls = ClientTlsContext(tls_opts) elif auth_type == AuthType.PKCS11: try: pkcs11_lib = Pkcs11Lib( file=config.pkcs11_lib_path, behavior=Pkcs11Lib.InitializeFinalizeBehavior.STRICT) tls_opts = TlsContextOptions.create_client_with_mtls_pkcs11( pkcs11_lib=pkcs11_lib, user_pin=config.pkcs11_pin, token_label=config.pkcs11_token_label, private_key_label=config.pkcs11_key_label, cert_file_path=config.cert_path) tls = ClientTlsContext(tls_opts) except Exception as e: if 'AWS_ERROR_UNIMPLEMENTED' in str(e): raise unittest.SkipTest(f'TLS with PKCS#11 not supported on this platform ({sys.platform})') else: # re-raise exception raise if use_static_singletons: client = Client(tls_ctx=tls) else: elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) client = Client(bootstrap, tls) connection = Connection( client=client, client_id=create_client_id(), host_name=config.endpoint, port=8883) return connection
def s3_client_new(secure, region, part_size=0): event_loop_group = EventLoopGroup() host_resolver = DefaultHostResolver(event_loop_group) bootstrap = ClientBootstrap(event_loop_group, host_resolver) credential_provider = AwsCredentialsProvider.new_default_chain(bootstrap) tls_option = None if secure: opt = TlsContextOptions() ctx = ClientTlsContext(opt) tls_option = TlsConnectionOptions(ctx) s3_client = S3Client(bootstrap=bootstrap, region=region, credential_provider=credential_provider, tls_connection_options=tls_option, part_size=part_size) return s3_client
def connect(self): elg = EventLoopGroup() resolver = DefaultHostResolver(elg) bootstrap = ClientBootstrap(elg, resolver) socket_options = SocketOptions() socket_options.domain = SocketDomain.Local amender = MessageAmendment.create_static_authtoken_amender(getenv("SVCUID")) hostname = getenv("AWS_GG_NUCLEUS_DOMAIN_SOCKET_FILEPATH_FOR_COMPONENT") connection = Connection( host_name=hostname, port=8033, bootstrap=bootstrap, socket_options=socket_options, connect_message_amender=amender, ) self.lifecycle_handler = LifecycleHandler() connect_future = connection.connect(self.lifecycle_handler) connect_future.result(config_utils.TIMEOUT) return connection
def _new_client_connection(self, secure, proxy_options=None): if secure: tls_ctx_opt = TlsContextOptions() tls_ctx_opt.override_default_trust_store_from_path(None, 'test/resources/ca.crt') tls_ctx = ClientTlsContext(tls_ctx_opt) tls_conn_opt = tls_ctx.new_connection_options() tls_conn_opt.set_server_name(self.hostname) else: tls_conn_opt = None event_loop_group = EventLoopGroup() host_resolver = DefaultHostResolver(event_loop_group) bootstrap = ClientBootstrap(event_loop_group, host_resolver) connection_future = HttpClientConnection.new(host_name=self.hostname, port=self.port, bootstrap=bootstrap, tls_connection_options=tls_conn_opt, proxy_options=proxy_options) return connection_future.result(self.timeout)
def new_profile(cls, client_bootstrap=None, profile_name=None, config_filepath=None, credentials_filepath=None): """ Creates a provider that sources credentials from key-value profiles loaded from the aws credentials file. Args: client_bootstrap (Optional[ClientBootstrap]): Client bootstrap to use when initiating socket connection. If not set, uses the static default ClientBootstrap instead. profile_name (Optional[str]): Name of profile to use. If not set, uses value from AWS_PROFILE environment variable. If that is not set, uses value of "default" config_filepath (Optional[str]): Path to profile config file. If not set, uses value from AWS_CONFIG_FILE environment variable. If that is not set, uses value of "~/.aws/config" credentials_filepath (Optional[str]): Path to profile credentials file. If not set, uses value from AWS_SHARED_CREDENTIALS_FILE environment variable. If that is not set, uses value of "~/.aws/credentials" Returns: AwsCredentialsProvider: """ assert isinstance(client_bootstrap, ClientBootstrap) or client_bootstrap is None assert isinstance(profile_name, str) or profile_name is None assert isinstance(config_filepath, str) or config_filepath is None assert isinstance(credentials_filepath, str) or credentials_filepath is None if client_bootstrap is None: client_bootstrap = ClientBootstrap.get_or_create_static_default() binding = _awscrt.credentials_provider_new_profile( client_bootstrap, profile_name, config_filepath, credentials_filepath) return cls(binding)