def test1(): # ocean instance config = ExampleConfig.get_config() ConfigProvider.set_config(config) Web3Provider.init_web3( provider=get_web3_connection_provider(config.network_url)) ContractHandler.set_artifacts_path(config.artifacts_path) ocean = Ocean(config) OCEAN_address_before = ocean.OCEAN_address # deploy, distribute, etc deploy_fake_OCEAN() # test: OCEAN address should have changed OCEAN_address_after = ocean.OCEAN_address assert OCEAN_address_before != OCEAN_address_after # test: TEST_PRIVATE_KEY{1,2} should each hold OCEAN wallet1 = Wallet(ocean.web3, private_key=os.getenv("TEST_PRIVATE_KEY1")) wallet2 = Wallet(ocean.web3, private_key=os.getenv("TEST_PRIVATE_KEY2")) OCEAN_after = BToken(ocean.OCEAN_address) assert OCEAN_after.balanceOf(wallet1.address) > 0 assert OCEAN_after.balanceOf(wallet2.address) > 0
def run_events_monitor(): setup_logging() logger.info('EventsMonitor: preparing') required_env_vars = ['EVENTS_RPC', 'CONFIG_FILE'] for envvar in required_env_vars: if not os.getenv(envvar): raise AssertionError( f'env var {envvar} is missing, make sure to set the following ' f'environment variables before starting the events monitor: {required_env_vars}' ) network_rpc = os.environ.get('EVENTS_RPC', 'http:127.0.0.1:8545') config_file = os.getenv('CONFIG_FILE', 'config.ini') logger.info( f'EventsMonitor: starting with the following values: rpc={network_rpc}' ) ConfigProvider.set_config(Config(config_file)) from ocean_lib.ocean.util import get_web3_connection_provider Web3Provider.init_web3(provider=get_web3_connection_provider(network_rpc)) ContractHandler.set_artifacts_path(get_artifacts_path()) if get_network_name().lower() == 'rinkeby': from web3.middleware import geth_poa_middleware Web3Provider.get_web3().middleware_stack.inject(geth_poa_middleware, layer=0) monitor = EventsMonitor(Web3Provider.get_web3(), config_file) monitor.start_events_monitor() logger.info(f'EventsMonitor: started') while True: time.sleep(5)
def setup_all(): config = ExampleConfig.get_config() ConfigProvider.set_config(config) Web3Provider.init_web3( provider=get_web3_connection_provider(config.network_url)) ContractHandler.set_artifacts_path(config.artifacts_path) network = Web3Helper.get_network_name() wallet = get_ganache_wallet() if network in ["ganache", "development"] and wallet: print( f"sender: {wallet.key}, {wallet.address}, {wallet.password}, {wallet.keysStr()}" ) print( f"sender balance: {Web3Helper.from_wei(Web3Helper.get_ether_balance(wallet.address))}" ) assert Web3Helper.from_wei(Web3Helper.get_ether_balance( wallet.address)) > 10 from ocean_lib.models.data_token import DataToken OCEAN_token = DataToken(get_ocean_token_address(network)) amt_distribute = 1000 amt_distribute_base = to_base_18(float(amt_distribute)) for w in (get_publisher_wallet(), get_consumer_wallet()): if Web3Helper.from_wei(Web3Helper.get_ether_balance( w.address)) < 2: Web3Helper.send_ether(wallet, w.address, 4) if OCEAN_token.token_balance(w.address) < 100: OCEAN_token.transfer(w.address, amt_distribute_base, from_wallet=wallet)
def init_components(config=None): if config is None: config = Config(os.getenv(ENV_CONFIG_FILE)) ConfigProvider.set_config(config) Web3Provider.init_web3(provider=get_web3_connection_provider(config.network_url)) ContractHandler.set_artifacts_path(config.artifacts_path)
def test_get_contracts_addresses(): config = Config(os.getenv(ENV_CONFIG_FILE)) ConfigProvider.set_config(config) addresses = util.get_contracts_addresses("ganache", config) assert addresses assert isinstance(addresses, dict) assert ("DTFactory" and "BFactory" and "FixedRateExchange" and "Metadata" and "Ocean" in addresses) assert len(addresses) == 5 for _, value in addresses.items(): assert value.startswith("0x")
def initialize(private_key): load_dotenv(".env") config = Config(os.getenv('config.ini')) config = Config(os.getenv('config.ini')) print(config.network_url) # config.network_url="https://rinkeby.infura.io/v3/31d95be121a545b688a0e07e4de4d256" ConfigProvider.set_config(config) Web3Provider.init_web3( provider=get_web3_connection_provider(config.network_url)) ContractHandler.set_artifacts_path(config.artifacts_path) ocean = Ocean() wallet = Wallet(ocean.web3, private_key=private_key) return ocean, wallet
def test_build_specific_endpoints(): """Tests that a specific list of agreed endpoints is supported on the DataServiceProvider.""" config = ConfigProvider.get_config() endpoints = TEST_SERVICE_ENDPOINTS def get_service_endpoints(_provider_uri=None): return TEST_SERVICE_ENDPOINTS.copy() original_func = DataSP.get_service_endpoints DataSP.get_service_endpoints = get_service_endpoints base_uri = DataSP.get_root_uri(config.provider_url) assert DataSP.build_download_endpoint()[1] == urljoin( base_uri, endpoints["download"][1]) assert DataSP.build_initialize_endpoint()[1] == urljoin( base_uri, endpoints["initialize"][1]) assert DataSP.build_encrypt_endpoint()[1] == urljoin( base_uri, endpoints["encrypt"][1]) assert DataSP.build_fileinfo()[1] == urljoin(base_uri, endpoints["fileinfo"][1]) assert DataSP.build_compute_endpoint()[1] == urljoin( base_uri, endpoints["computeStatus"][1]) assert DataSP.build_compute_endpoint()[1] == urljoin( base_uri, endpoints["computeStart"][1]) assert DataSP.build_compute_endpoint()[1] == urljoin( base_uri, endpoints["computeStop"][1]) assert DataSP.build_compute_endpoint()[1] == urljoin( base_uri, endpoints["computeDelete"][1]) DataSP.get_service_endpoints = original_func
def delist_ddo(did): assert request.json and isinstance(request.json, dict), 'invalid payload format.' data = request.json address = data.get('adminAddress', None) if not address or not has_update_request_permission(address): return jsonify(error=f'Unauthorized.'), 401 _address = None signature = data.get('signature', None) if signature: _address = get_signer_address(address, signature, logger) if not _address or _address.lower() != address.lower(): return jsonify(error=f'Unauthorized.'), 401 try: asset_record = dao.get(did) if not asset_record: return jsonify(error=f'Asset {did} not found.'), 404 updater = MetadataUpdater(oceandb=dao.oceandb, web3=Web3Provider.get_web3(), config=ConfigProvider.get_config()) updater.do_single_update(asset_record) return jsonify('acknowledged.'), 200 except Exception as e: logger.error(f'get_metadata: {str(e)}') return f'{did} asset DID is not in OceanDB', 404
def build_service_privacy_attributes( trusted_algorithms: list = None, allow_raw_algorithm: bool = False, allow_all_published_algorithms: bool = False, allow_network_access: bool = False, ): """ :param trusted_algorithms: list of algorithm did to be trusted by the compute service provider :param allow_raw_algorithm: bool -- when True, unpublished raw algorithm code can be run on this dataset :param allow_all_published_algorithms: bool -- when True, any published algorithm can be run on this dataset The list of `trusted_algorithms` will be ignored in this case. :param allow_network_access: bool -- allow/disallow the algorithm network access during execution :return: dict """ privacy = { "allowRawAlgorithm": allow_raw_algorithm, "allowAllPublishedAlgorithms": allow_all_published_algorithms, "publisherTrustedAlgorithms": [], "allowNetworkAccess": allow_network_access, } if trusted_algorithms: privacy["publisherTrustedAlgorithms"] = create_publisher_trusted_algorithms( trusted_algorithms, ConfigProvider.get_config().metadata_cache_uri ) return privacy
def test_build_endpoint(): """Tests that service endpoints are correctly built from URL and service name.""" def get_service_endpoints(_provider_uri=None): _endpoints = TEST_SERVICE_ENDPOINTS.copy() _endpoints.update( {"newEndpoint": ["GET", "/api/v1/services/newthing"]}) return _endpoints original_func = DataSP.get_service_endpoints DataSP.get_service_endpoints = get_service_endpoints config = ConfigProvider.get_config() endpoints = get_service_endpoints() uri = "http://ppp.com" method, endpnt = DataSP.build_endpoint("newEndpoint", provider_uri=uri) assert endpnt == urljoin(uri, endpoints["newEndpoint"][1]) # config has no effect when provider_uri is set assert (endpnt == DataSP.build_endpoint("newEndpoint", provider_uri=uri, config=config)[1]) method, endpnt = DataSP.build_endpoint("newEndpoint", config=config) assert endpnt == urljoin(DataSP.get_root_uri(config.provider_url), endpoints["newEndpoint"][1]) assert (endpnt == DataSP.build_endpoint( "newEndpoint", provider_uri=config.provider_url)[1]) uri = "http://ppp.com:8030/api/v1/services/newthing" method, endpnt = DataSP.build_endpoint("download", provider_uri=uri) assert method == endpoints["download"][0] assert endpnt == urljoin(DataSP.get_root_uri(uri), endpoints["download"][1]) DataSP.get_service_endpoints = original_func
def __init__(self, web3, config_file, metadata_contract=None): self._oceandb = OceanDb(config_file).plugin self._other_db_index = f'{self._oceandb.driver.db_index}_plus' self._oceandb.driver.es.indices.create(index=self._other_db_index, ignore=400) self._web3 = web3 self._pool_monitor = None if bool(int(os.getenv('PROCESS_POOL_EVENTS', 1)) == 1): self._pool_monitor = MetadataUpdater( self._oceandb, self._other_db_index, self._web3, ConfigProvider.get_config() ) if not metadata_contract: metadata_contract = get_metadata_contract(self._web3) self._contract = metadata_contract self._contract_address = self._contract.address self._ecies_private_key = os.getenv('EVENTS_ECIES_PRIVATE_KEY', '') self._ecies_account = None if self._ecies_private_key: self._ecies_account = Account.privateKeyToAccount(self._ecies_private_key) metadata_block = int(os.getenv('METADATA_CONTRACT_BLOCK', 0)) try: self.get_last_processed_block() except Exception: self.store_last_processed_block(metadata_block) allowed_publishers = set() try: publishers_str = os.getenv('ALLOWED_PUBLISHERS', '') allowed_publishers = set(json.loads(publishers_str)) if publishers_str else set() except (JSONDecodeError, TypeError, Exception) as e: logger.error(f'Reading list of allowed publishers failed: {e}\n' f'ALLOWED_PUBLISHER is set to "{os.getenv("ALLOWED_PUBLISHER")}"') self._allowed_publishers = set(sanitize_addresses(allowed_publishers)) logger.debug(f'allowed publishers: {self._allowed_publishers}') logger.debug(f'EventsMonitor: using Metadata contract address {self._contract_address}.') self._monitor_is_on = False default_sleep_time = 10 try: self._monitor_sleep_time = int(os.getenv('OCN_EVENTS_MONITOR_QUITE_TIME', default_sleep_time)) except ValueError: self._monitor_sleep_time = default_sleep_time self._monitor_sleep_time = max(self._monitor_sleep_time, default_sleep_time) if not self._contract or not self._web3.isAddress(self._contract_address): logger.error( f"Contract address {self._contract_address} is not a valid address. Events thread not starting") self._contract = None self._purgatory_enabled = bool(int(os.getenv('PROCESS_PURGATORY', 1)) == 1) self._purgatory_list = set() self._purgatory_update_time = None
def create_compute_service(attributes, provider_uri=None): service_endpoint = provider_uri or DataServiceProvider.get_url( ConfigProvider.get_config() ) return ServiceDescriptor.compute_service_descriptor( attributes, service_endpoint )
def check_output_dict(output_def, consumer_address, data_provider, config=None): """ Validate the `output_def` dict and fills in defaults for missing values. :param output_def: dict :param consumer_address: hex str the consumer ethereum address :param data_provider: DataServiceProvider class or similar interface :param config: Config instance :return: dict a valid `output_def` object """ if not config: config = ConfigProvider.get_config() default_output_def = { "nodeUri": config.network_url, "brizoUri": data_provider.get_url(config), "brizoAddress": config.provider_address, "metadata": dict(), "metadataUri": config.metadata_cache_uri, "owner": consumer_address, "publishOutput": 0, "publishAlgorithmLog": 0, "whitelist": [], } output_def = output_def if isinstance(output_def, dict) else dict() default_output_def.update(output_def) return default_output_def
def setup_all(request): # a test can skip setup_all() via decorator "@pytest.mark.nosetup_all" if "nosetup_all" in request.keywords: return config = ExampleConfig.get_config() ConfigProvider.set_config(config) Web3Provider.init_web3( provider=get_web3_connection_provider(config.network_url)) ContractHandler.set_artifacts_path(config.artifacts_path) wallet = get_ganache_wallet() if not wallet: return addresses_file = config.address_file if not os.path.exists(addresses_file): return with open(addresses_file) as f: network_addresses = json.load(f) print( f"sender: {wallet.key}, {wallet.address}, {wallet.password}, {wallet.keysStr()}" ) print(f"sender balance: {from_wei(get_ether_balance(wallet.address))}") assert (from_wei(get_ether_balance(wallet.address)) > 10), "Ether balance less than 10." from ocean_lib.models.data_token import DataToken OCEAN_token = DataToken(address=network_addresses["development"]["Ocean"]) amt_distribute = 1000 amt_distribute_base = to_base_18(float(amt_distribute)) for w in (get_publisher_wallet(), get_consumer_wallet()): if from_wei(get_ether_balance(w.address)) < 2: send_ether(wallet, w.address, 4) if OCEAN_token.token_balance(w.address) < 100: OCEAN_token.mint(wallet.address, amt_distribute_base, from_wallet=wallet) OCEAN_token.transfer(w.address, amt_distribute_base, from_wallet=wallet)
def trying_algorithm_run(did, wallet, order_tx_id, nonce): load_dotenv(".env") config = Config(os.getenv('config.ini')) print(config.network_url) # config.network_url="https://rinkeby.infura.io/v3/31d95be121a545b688a0e07e4de4d256" ConfigProvider.set_config(config) ocean_auth = OceanAuth("./storage_tokens") token = ocean_auth.get(wallet) print(config.provider_url) ocean_compute = OceanCompute(ocean_auth, config, config.provider_url) job_id = ocean_compute.start(did, wallet, order_tx_id, nonce, algorithm_meta=algo_metadata) return job_id
def get_provider_address(provider_uri=None): """ Return the provider address """ if not provider_uri: provider_uri = ConfigProvider.get_config().provider_url provider_info = DataServiceProvider._http_method("get", provider_uri).json() return provider_info["providerAddress"]
def events_object(): global EVENTS_INSTANCE if not EVENTS_INSTANCE: config_file = os.getenv('CONFIG_FILE', 'config.ini') network_rpc = os.environ.get('EVENTS_RPC', 'http://127.0.0.1:8545') ConfigProvider.set_config(Config(config_file)) from ocean_lib.ocean.util import get_web3_connection_provider Web3Provider.init_web3( provider=get_web3_connection_provider(network_rpc)) ContractHandler.set_artifacts_path(get_artifacts_path()) EVENTS_INSTANCE = EventsMonitor(Web3Provider.get_web3(), app.config['CONFIG_FILE']) EVENTS_INSTANCE.store_last_processed_block(0) return EVENTS_INSTANCE
def mint_fake_OCEAN(): """ Does the following: 1. Mints tokens 2. Distributes tokens to TEST_PRIVATE_KEY1 and TEST_PRIVATE_KEY2 """ config = ExampleConfig.get_config() ConfigProvider.set_config(config) Web3Provider.init_web3( provider=get_web3_connection_provider(config.network_url)) ContractHandler.set_artifacts_path(config.artifacts_path) addresses_file = config.address_file ocean = get_publisher_ocean_instance() web3 = ocean.web3 with open(addresses_file) as f: network_addresses = json.load(f) network = "development" deployer_wallet = get_ganache_wallet() OCEAN_token = DataToken(address=network_addresses[network]["Ocean"]) amt_distribute = 1000 amt_distribute_base = to_base_18(float(amt_distribute)) OCEAN_token.mint(deployer_wallet.address, 2 * amt_distribute_base, from_wallet=deployer_wallet) for key_label in ["TEST_PRIVATE_KEY1", "TEST_PRIVATE_KEY2"]: key = os.environ.get(key_label) if not key: continue w = Wallet(web3, private_key=key) if OCEAN_token.token_balance(w.address) < 1000: OCEAN_token.transfer(w.address, amt_distribute_base, from_wallet=deployer_wallet) if from_wei(get_ether_balance(w.address)) < 2: send_ether(deployer_wallet, w.address, 4)
def get_service_endpoints(): """ Return the service endpoints from the provider URL. """ if DataServiceProvider.provider_info is None: config = ConfigProvider.get_config() DataServiceProvider.provider_info = requests.get(config.provider_url).json() return DataServiceProvider.provider_info['serviceEndpoints']
def build_endpoint(service_name, provider_uri=None, config=None): if not provider_uri: config = config or ConfigProvider.get_config() provider_uri = DataServiceProvider.get_url(config) provider_uri = DataServiceProvider.get_root_uri(provider_uri) service_endpoints = DataServiceProvider.get_service_endpoints(provider_uri) method, url = service_endpoints[service_name] return method, urljoin(provider_uri, url)
def get_service_endpoints(provider_uri=None): """ Return the service endpoints from the provider URL. """ if not provider_uri: provider_uri = DataServiceProvider.get_url(ConfigProvider.get_config()) provider_info = DataServiceProvider._http_method("get", provider_uri).json() return provider_info["serviceEndpoints"]
def download_service( did, service_endpoint, wallet, files, destination_folder, service_id, token_address, order_tx_id, index=None, ): """ Call the provider endpoint to get access to the different files that form the asset. :param did: str id of the asset :param service_endpoint: Url to consume, str :param wallet: hex str Wallet instance of the consumer signing this request :param files: List containing the files to be consumed, list :param destination_folder: Path, str :param service_id: integer the id of the service inside the DDO's service dict :param token_address: hex str the data token address associated with this asset/service :param order_tx_id: hex str the transaction hash for the required data token transfer (tokens of the same token address above) :param index: Index of the document that is going to be downloaded, int :return: True if was downloaded, bool """ indexes = range(len(files)) if index is not None: assert isinstance(index, int), logger.error("index has to be an integer.") assert index >= 0, logger.error( "index has to be 0 or a positive integer.") assert index < len(files), logger.error( "index can not be bigger than the number of files") indexes = [index] base_url = (f"{service_endpoint}" f"?documentId={did}" f"&serviceId={service_id}" f"&serviceType={ServiceTypes.ASSET_ACCESS}" f"&dataToken={token_address}" f"&transferTxId={order_tx_id}" f"&consumerAddress={wallet.address}") config = ConfigProvider.get_config() for i in indexes: signature = DataServiceProvider.sign_message(wallet, did, config) download_url = base_url + f"&signature={signature}&fileIndex={i}" logger.info( f"invoke consume endpoint with this url: {download_url}") response = DataServiceProvider._http_client.get(download_url, stream=True) file_name = DataServiceProvider._get_file_name(response) DataServiceProvider.write_file(response, destination_folder, file_name or f"file-{i}")
def enforce_types_shim(func): try: c = ConfigProvider.get_config() except AssertionError: # handle if ConfigProvider.set_config() not done yet c = config_defaults val = c["util"][NAME_TYPECHECK] typecheck = distutils.util.strtobool(val) if typecheck: return enforce_types(func) return func
def get_provider_address(provider_uri=None): """ Return the provider address """ if not provider_uri: if DataServiceProvider.provider_info is None: config = ConfigProvider.get_config() DataServiceProvider.provider_info = requests.get( config.provider_url).json() return DataServiceProvider.provider_info["provider-address"] provider_info = requests.get(provider_uri).json() return provider_info["provider-address"]
def test_update_trusted_algorithms(): setup = Setup() config = ConfigProvider.get_config() ddo_address = get_contracts_addresses( "ganache", config)[MetadataContract.CONTRACT_NAME] ddo_registry = MetadataContract(ddo_address) # Setup algorithm meta to run raw algorithm algorithm_ddo = get_registered_algorithm_ddo( setup.publisher_ocean_instance, setup.publisher_wallet) # verify the ddo is available in Aquarius _ = setup.publisher_ocean_instance.assets.resolve(algorithm_ddo.did) # Dataset with compute service compute_ddo = get_registered_ddo_with_compute_service( setup.publisher_ocean_instance, setup.publisher_wallet, trusted_algorithms=[algorithm_ddo.did], ) # verify the ddo is available in Aquarius _ = setup.publisher_ocean_instance.assets.resolve(compute_ddo.did) trusted_algo_list = create_publisher_trusted_algorithms( [algorithm_ddo.did], setup.publisher_ocean_instance.config.aquarius_url) compute_ddo.update_compute_privacy(trusted_algorithms=trusted_algo_list, allow_all=False, allow_raw_algorithm=False) tx_id = setup.publisher_ocean_instance.assets.update( compute_ddo, setup.publisher_wallet) tx_receipt = ddo_registry.get_tx_receipt(tx_id) logs = ddo_registry.event_MetadataUpdated.processReceipt(tx_receipt) assert logs[0].args.dataToken == compute_ddo.data_token_address wait_for_update( setup.publisher_ocean_instance, compute_ddo.did, "privacy", {"publisherTrustedAlgorithms": [algorithm_ddo.did]}, ) compute_ddo_updated = setup.publisher_ocean_instance.assets.resolve( compute_ddo.did) run_compute_test( setup.consumer_ocean_instance, setup.publisher_wallet, setup.consumer_wallet, [compute_ddo_updated], algo_ddo=algorithm_ddo, )
def create_access_service(attributes, provider_uri=None): """Publish an asset with an `Access` service according to the supplied attributes. :param attributes: attributes of the access service, dict :param provider_uri: str URL of service provider. This will be used as base to construct the serviceEndpoint for the `access` (download) service :return: Service instance or None """ service_endpoint = provider_uri or DataServiceProvider.get_url( ConfigProvider.get_config()) service = ServiceDescriptor.access_service_descriptor( attributes, service_endpoint) return service
def run_scenario(): config = Config('config.ini') ocean = Ocean(config) wallet = Wallet( ocean.web3, 0x376e05899a4ae00463a3a607c774069b7d6a647860dba723f39b735c91238ddf, None, "EARLYTOBEDANDEARLYTORISE") ConfigProvider.set_config(config) Web3Provider.init_web3( provider=get_web3_connection_provider(config.network_url)) ContractHandler.set_artifacts_path(config.artifacts_path) print(dir(wallet)) print(wallet.address) print(config.network_url) print(config.provider_url) print(config.network_url) print(config.artifacts_path) data_token = ocean.create_data_token('S1Seven', 'S1SV', from_wallet=wallet) print(f'created new datatoken with address {data_token.address}') token_address = data_token.address print(token_address) '''
def trying_compute(wallet): load_dotenv(".env") config = Config(os.getenv('config.ini')) print(config.network_url) # config.network_url="https://rinkeby.infura.io/v3/31d95be121a545b688a0e07e4de4d256" ConfigProvider.set_config(config) ocean_auth = OceanAuth("./storage_tokens") token = ocean_auth.get(wallet) # config=ConfigProvider() print(config.provider_url) ocean_compute = OceanCompute(ocean_auth, config, config.provider_url) build_server_attributes = OceanCompute.build_server_attributes( server_id="1", server_type="homemade", cpu=2, gpu=0, memory=2, disk=10, max_run_time=5000) compute_service_cluster_attribute = OceanCompute.build_cluster_attributes( cluster_type="Kubernetes", url="http://10.96.0.1/") compute_service_container_attributes = OceanCompute.build_container_attributes( image="patanae", tag="patanae", entrypoint="python") compute_service_provider_attributes = OceanCompute.build_service_provider_attributes( "forgeeks", description="providecompute", cluster=compute_service_cluster_attribute, containers=compute_service_container_attributes, servers=build_server_attributes) created_compute_service_attributes = OceanCompute.create_compute_service_attributes( creator="hello", provider_attributes=compute_service_provider_attributes, date_published="", timeout=20000) compute_service_descriptor = ocean_compute.create_compute_service_descriptor( created_compute_service_attributes)
def get_provider_address(provider_uri=None): """ Return the provider address """ try: if not provider_uri: provider_uri = ConfigProvider.get_config().provider_url provider_info = DataServiceProvider._http_method( "get", provider_uri).json() return provider_info["providerAddress"] except requests.exceptions.RequestException: pass return None
def get_service_endpoints(provider_uri=None): """ Return the service endpoints from the provider URL. """ if not provider_uri: provider_uri = DataServiceProvider.get_url( ConfigProvider.get_config()) api_version = DataServiceProvider.get_api_version() if api_version in provider_uri: i = provider_uri.find(api_version) provider_uri = provider_uri[:i] provider_info = DataServiceProvider._http_method("get", provider_uri).json() return provider_info["serviceEndpoints"]