def test_get_api_with_str_none_token(self): factory = ApiClientFactory( token=RefreshingToken(), api_url=source_config_details["api_url"], app_name=source_config_details["app_name"], api_secrets_filename=CredentialsSource.secrets_path(), ) api = factory.build(InstrumentsApi) self.assertIsInstance(api, InstrumentsApi) self.validate_api(api)
def test_wrapped_method(self): factory = ApiClientFactory( api_secrets_filename=CredentialsSource.secrets_path()) wrapped_scopes_api = factory.build(InstrumentsApi) portfolio = InstrumentsApi(wrapped_scopes_api.api_client) self.assertEqual(portfolio.__doc__, wrapped_scopes_api.__doc__) self.assertEqual(portfolio.__module__, wrapped_scopes_api.__module__) self.assertDictEqual(portfolio.__dict__, wrapped_scopes_api.__dict__)
def test_get_api_with_info(self): factory = ApiClientFactory( api_secrets_filename=CredentialsSource.secrets_path()) api = factory.build(InstrumentsApi) self.assertIsInstance(api, InstrumentsApi) result = api.get_instrument_identifier_types( call_info=lambda r: print(r)) self.assertIsNotNone(result)
def test_get_info_with_invalid_param_throws_error(self): factory = ApiClientFactory( api_secrets_filename=CredentialsSource.secrets_path() ) api = factory.build(InstrumentsApi) self.assertIsInstance(api, InstrumentsApi) with self.assertRaises(ValueError) as error: api.get_instrument_identifier_types(call_info="invalid param") self.assertEqual(error.exception.args[0], "call_info value must be a lambda")
def test_get_api_with_token_url_as_env_var(self): token, refresh_token = tu.get_okta_tokens( CredentialsSource.secrets_path()) with patch.dict( 'os.environ', {"FBN_LUSID_API_URL": source_config_details["api_url"]}, clear=True): factory = ApiClientFactory( token=token, app_name=source_config_details["app_name"]) api = factory.build(InstrumentsApi) self.assertIsInstance(api, InstrumentsApi) self.validate_api(api)
def test_get_token(self): original_token, refresh_token = tu.get_okta_tokens(CredentialsSource.secrets_path()) refreshed_token = RefreshingToken(token_url=self.config.token_url, client_id=self.config.client_id, client_secret=self.config.client_secret, initial_access_token=original_token, initial_token_expiry=3600, refresh_token=refresh_token) self.assertIsNotNone(refreshed_token) self.assertEqual(original_token, refreshed_token)
def test_use_apifactory_multiple_threads(self): with patch.dict('os.environ', self.get_env_vars_without_pat(), clear=True): access_token = str(ApiClientFactory( api_secrets_filename=CredentialsSource.secrets_path() ).api_client.configuration.access_token) api_factory = ApiClientFactory( api_secrets_filename=CredentialsSource.secrets_path() ) def get_identifier_types(factory): return factory.build(InstrumentsApi).get_instrument_identifier_types() thread1 = Thread(target=get_identifier_types, args=[api_factory]) thread2 = Thread(target=get_identifier_types, args=[api_factory]) thread3 = Thread(target=get_identifier_types, args=[api_factory]) with patch("requests.post") as identity_mock: identity_mock.side_effect = lambda *args, **kwargs: MockApiResponse( json_data={ "access_token": f"{access_token}", "refresh_token": "mock_refresh_token", "expires_in": 3600 }, status_code=200 ) thread1.start() thread2.start() thread3.start() thread1.join() thread2.join() thread3.join() # Ensure that we only got an access token once self.assertEqual(1, identity_mock.call_count)
def test_can_make_header(self): original_token, refresh_token = tu.get_okta_tokens(CredentialsSource.secrets_path()) refreshed_token = RefreshingToken(token_url=self.config.token_url, client_id=self.config.client_id, client_secret=self.config.client_secret, initial_access_token=original_token, initial_token_expiry=3600, refresh_token=refresh_token) header = "Bearer " + refreshed_token self.assertIsNotNone(header)
def test_get_api_with_correlation_id_from_param(self): env_vars = {config_keys[key]["env"]: value for key, value in source_config_details.items() if value is not None} with patch.dict('os.environ', env_vars, clear=True): factory = ApiClientFactory( api_secrets_filename=CredentialsSource.secrets_path(), correlation_id="param-correlation-id" ) api = factory.build(InstrumentsApi) self.assertIsInstance(api, InstrumentsApi) self.validate_api(api) self.assertTrue("CorrelationId" in api.api_client.default_headers, msg="CorrelationId not found in headers") self.assertEquals(api.api_client.default_headers["CorrelationId"], "param-correlation-id")
def get_okta_tokens(): original_token = "" refresh_token = "" def extract_refresh_token(okta_response): nonlocal refresh_token nonlocal original_token okta_json = okta_response.json() refresh_token = okta_json["refresh_token"] original_token = okta_json["access_token"] ApiClientBuilder().build( CredentialsSource.secrets_path(), extract_refresh_token ) return original_token, refresh_token
def test_token_when_not_expired_does_not_refresh(self): original_token, refresh_token = tu.get_okta_tokens(CredentialsSource.secrets_path()) refreshed_token = RefreshingToken(token_url=self.config.token_url, client_id=self.config.client_id, client_secret=self.config.client_secret, initial_access_token=original_token, initial_token_expiry=3600, refresh_token=refresh_token) self.assertIsNotNone(refreshed_token) # force de-referencing the token value first_value = f"{refreshed_token}" sleep(1) self.assertEqual(first_value, refreshed_token)
def test_use_apifactory_with_id_provider_response_handler(self): """ Ensures that an id_provider_response handler that is passed to the ApiClientFactory can be used during communication with the id provider (if appropriate). """ responses = [] def record_response(id_provider_response): nonlocal responses responses.append(id_provider_response.status_code) api_factory = ApiClientFactory( api_secrets_filename=CredentialsSource.secrets_path(), id_provider_response_handler=record_response) api = api_factory.build(InstrumentsApi) self.validate_api(api) self.assertGreater(len(responses), 0)
def test_get_api_without_tcp_keep_alive(self): api_factory = ApiClientFactory(api_secrets_filename=CredentialsSource.secrets_path()) # Make sure tcp_keep_alive was passed through all of the layers self.assertFalse(api_factory.api_client.configuration.tcp_keep_alive) self.assertIsInstance(api_factory.api_client.rest_client.pool_manager, (PoolManager, ProxyManager))
def setUpClass(cls): # add mock to the module lusid.api.MockApi = MockApi cls.factory = ApiClientFactory(api_secrets_filename=CredentialsSource.secrets_path())
def setUpClass(cls): cls.config = ApiConfigurationLoader.load(CredentialsSource.secrets_path())
def api_client(cls): if not cls._api_client: with cls._lock: if not cls._api_client: cls._api_client = ApiClientBuilder().build(CredentialsSource.secrets_path()) return cls._api_client
def test_get_api_with_configuration(self): factory = ApiClientFactory( api_secrets_filename=CredentialsSource.secrets_path()) api = factory.build(InstrumentsApi) self.assertIsInstance(api, InstrumentsApi) self.validate_api(api)