From 68c670bc1d0ad74000688e797891248c70b04bb1 Mon Sep 17 00:00:00 2001 From: Victor Ramirez Date: Mon, 18 Nov 2024 19:02:15 +0000 Subject: [PATCH] PLAT-1315 Add json_stream --- .gitlab-ci.yml | 2 +- coinmetrics/_data_collection.py | 2 +- coinmetrics/api_client.py | 185 +++++++++++++++++++++++------- test/test_catalog_benchmarks.py | 197 ++++++++++++++++++++++++++++++++ test/test_catalogs_v2.py | 143 ++++++++++++++--------- 5 files changed, 432 insertions(+), 97 deletions(-) create mode 100644 test/test_catalog_benchmarks.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index adc6df1..6ada818 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -31,7 +31,7 @@ build-test-push-image: - docker build --cache-from $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME -t $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --build-arg CM_API_KEY=$CM_API_KEY . - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python -m mypy -p coinmetrics -p test --install-types --non-interactive - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python -m flake8 coinmetrics - - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python -m pytest -n auto --timeout=60 test --ignore test/test_data_exporter.py --ignore test/test_rate_limits.py --ignore test/test_catalog.py + - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python -m pytest -n auto --timeout=60 test --ignore test/test_data_exporter.py --ignore test/test_rate_limits.py --ignore test/test_catalog.py --ignore test/test_catalog_benchmarks.py - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python -m pytest test/test_rate_limits.py - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME diff --git a/coinmetrics/_data_collection.py b/coinmetrics/_data_collection.py index c9d38db..176550b 100644 --- a/coinmetrics/_data_collection.py +++ b/coinmetrics/_data_collection.py @@ -97,7 +97,7 @@ def first_page(self) -> List[Dict[str, Any]]: ) def to_list(self) -> List[Dict[str, Any]]: - return [data for data in self] + return list(self) def __next__(self) -> Any: try: diff --git a/coinmetrics/api_client.py b/coinmetrics/api_client.py index de01502..cf4cd3d 100644 --- a/coinmetrics/api_client.py +++ b/coinmetrics/api_client.py @@ -858,7 +858,7 @@ def catalog_market_contract_prices( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", limit: Optional[str] = None, ) -> CatalogMarketContractPrices: """ @@ -1809,7 +1809,7 @@ def catalog_full_market_contract_prices( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", limit: Optional[str] = None, ) -> CatalogMarketContractPrices: """ @@ -1860,7 +1860,7 @@ def catalog_full_contract_prices_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_strean", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -1880,7 +1880,7 @@ def catalog_full_contract_prices_v2( :type asset: Optional[str] :param symbol: Symbol of derivative markets, full instrument name. :type symbol: Optional[str] - :param format: Format of the response. Supported values are `json`, `json_stream`. + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. :type format: Optional[str] :param page_size: Number of items per single page of results. :type page_size: Optional[int] @@ -1889,6 +1889,7 @@ def catalog_full_contract_prices_v2( :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :return: List of contract prices statistics. :rtype: CatalogV2DataCollection """ @@ -1916,7 +1917,7 @@ def catalog_full_market_implied_volatility( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", limit: Optional[str] = None, ) -> CatalogMarketImpliedVolatility: """ @@ -2105,7 +2106,7 @@ def catalog_market_trades_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2161,7 +2162,7 @@ def catalog_market_candles_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2224,7 +2225,7 @@ def catalog_market_orderbooks_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2287,7 +2288,7 @@ def catalog_market_quotes_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2343,7 +2344,7 @@ def catalog_market_funding_rates_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2399,7 +2400,7 @@ def catalog_market_funding_rates_predicted_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2455,7 +2456,7 @@ def catalog_market_contract_prices_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2511,7 +2512,7 @@ def catalog_market_implied_volatility_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2567,7 +2568,7 @@ def catalog_market_greeks_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2623,7 +2624,7 @@ def catalog_market_open_interest_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2679,7 +2680,7 @@ def catalog_market_liquidations_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2736,7 +2737,7 @@ def catalog_market_metrics_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2805,7 +2806,7 @@ def catalog_full_market_trades_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2861,7 +2862,7 @@ def catalog_full_market_candles_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2924,7 +2925,7 @@ def catalog_full_market_orderbooks_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -2987,7 +2988,7 @@ def catalog_full_market_quotes_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -3043,7 +3044,7 @@ def catalog_full_market_funding_rates_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -3099,7 +3100,7 @@ def catalog_full_market_funding_rates_predicted_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -3155,7 +3156,7 @@ def catalog_full_market_contract_prices_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -3211,7 +3212,7 @@ def catalog_full_market_implied_volatility_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -3267,7 +3268,7 @@ def catalog_full_market_greeks_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -3323,7 +3324,7 @@ def catalog_full_market_open_interest_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -3379,7 +3380,7 @@ def catalog_full_market_liquidations_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -3436,7 +3437,7 @@ def catalog_full_market_metrics_v2( quote: Optional[str] = None, asset: Optional[str] = None, symbol: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, @@ -3504,7 +3505,7 @@ def catalog_asset_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -3555,7 +3556,7 @@ def catalog_full_asset_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -3606,7 +3607,7 @@ def catalog_exchange_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param exchanges: Comma separated list of exchanges. By default all exchanges are returned. @@ -3656,7 +3657,7 @@ def catalog_full_exchange_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param exchanges: Comma separated list of exchanges. By default all exchanges are returned. @@ -3706,7 +3707,7 @@ def catalog_exchange_asset_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param exchange_assets: Comma separated list of exchange-assets. By default, all exchange-assets pairs are returned. @@ -3756,7 +3757,7 @@ def catalog_full_exchange_asset_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param exchange_assets: Comma separated list of exchange-assets. By default, all exchange-assets pairs are returned. @@ -3806,7 +3807,7 @@ def catalog_pair_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param pairs: Comma separated list of asset pairs. By default, all asset pairs are returned. @@ -3821,9 +3822,8 @@ def catalog_pair_metrics_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] - :param format: Format of the response. Supported values are `json`, `json_stream`. + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. :type format: Optional[str] - :return: List of pair metrics. :rtype: CatalogV2DataCollection """ @@ -3856,7 +3856,7 @@ def catalog_full_pair_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param pairs: Comma separated list of asset pairs. By default, all asset pairs are returned. @@ -3906,7 +3906,7 @@ def catalog_institution_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param institutions: Comma separated list of institutions. By default, all institutions are returned. @@ -3956,7 +3956,7 @@ def catalog_full_institution_metrics_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, - format: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param institutions: Comma separated list of institutions. By default, all institutions are returned. @@ -4004,6 +4004,7 @@ def catalog_pair_candles_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param pairs: Comma separated list of asset pairs. By default, all asset pairs are returned. @@ -4014,6 +4015,8 @@ def catalog_pair_candles_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of asset pair candles statistics. :rtype: CatalogV2DataCollection @@ -4023,6 +4026,7 @@ def catalog_pair_candles_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection( self._get_data, @@ -4039,6 +4043,7 @@ def catalog_index_candles_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param indexes: Comma separated list of indexes. By default all assets are returned. @@ -4049,6 +4054,8 @@ def catalog_index_candles_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of index candles statistics. :rtype: CatalogV2DataCollection @@ -4058,6 +4065,7 @@ def catalog_index_candles_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection( self._get_data, @@ -4074,6 +4082,7 @@ def catalog_index_levels_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param indexes: Comma separated list of indexes. By default all indexes are returned. @@ -4084,6 +4093,8 @@ def catalog_index_levels_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of index levels. :rtype: CatalogV2DataCollection @@ -4093,6 +4104,7 @@ def catalog_index_levels_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection( self._get_data, @@ -4109,6 +4121,7 @@ def catalog_asset_chains_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -4119,6 +4132,8 @@ def catalog_asset_chains_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of asset chains assets :rtype: CatalogV2DataCollection @@ -4128,6 +4143,7 @@ def catalog_asset_chains_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection(self._get_data, "catalog-v2/asset-chains", params, client=self) @@ -4137,6 +4153,7 @@ def catalog_mempool_feerates_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -4147,6 +4164,8 @@ def catalog_mempool_feerates_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of mempool feerates assets :rtype: CatalogV2DataCollection @@ -4156,6 +4175,7 @@ def catalog_mempool_feerates_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection(self._get_data, "catalog-v2/mempool-feerates", params, client=self) @@ -4165,6 +4185,7 @@ def catalog_mining_pool_tips_summaries_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream" ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -4175,6 +4196,8 @@ def catalog_mining_pool_tips_summaries_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of mining pool tips assets :rtype: CatalogV2DataCollection @@ -4184,6 +4207,7 @@ def catalog_mining_pool_tips_summaries_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection(self._get_data, "catalog-v2/mining-pool-tips-summary", params, client=self) @@ -4193,6 +4217,7 @@ def catalog_transaction_tracker_assets_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -4212,6 +4237,7 @@ def catalog_transaction_tracker_assets_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection(self._get_data, "catalog-v2/transaction-tracker", params, client=self) @@ -4221,6 +4247,7 @@ def catalog_full_pair_candles_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param pairs: Comma separated list of asset pairs. By default, all asset pairs are returned. @@ -4231,6 +4258,8 @@ def catalog_full_pair_candles_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of asset pair candles statistics. :rtype: CatalogV2DataCollection @@ -4240,6 +4269,7 @@ def catalog_full_pair_candles_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection(self._get_data, "catalog-all-v2/pair-candles", params, client=self) @@ -4249,6 +4279,7 @@ def catalog_full_index_candles_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param indexes: Comma separated list of indexes. By default all assets are returned. @@ -4259,6 +4290,8 @@ def catalog_full_index_candles_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of index candles statistics. :rtype: CatalogV2DataCollection @@ -4268,6 +4301,7 @@ def catalog_full_index_candles_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection( self._get_data, @@ -4284,6 +4318,7 @@ def catalog_full_index_levels_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param indexes: Comma separated list of indexes. By default all indexes are returned. @@ -4294,6 +4329,8 @@ def catalog_full_index_levels_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of index levels. :rtype: CatalogV2DataCollection @@ -4303,6 +4340,7 @@ def catalog_full_index_levels_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection( self._get_data, @@ -4317,6 +4355,7 @@ def catalog_full_asset_chains_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -4327,6 +4366,8 @@ def catalog_full_asset_chains_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of asset chains assets :rtype: CatalogV2DataCollection @@ -4336,6 +4377,7 @@ def catalog_full_asset_chains_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format, } return CatalogV2DataCollection(self._get_data, "catalog-all-v2/asset-chains", params, client=self) @@ -4345,6 +4387,7 @@ def catalog_full_mempool_feerates_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -4355,6 +4398,8 @@ def catalog_full_mempool_feerates_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of mempool feerates assets :rtype: CatalogV2DataCollection @@ -4364,6 +4409,7 @@ def catalog_full_mempool_feerates_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection(self._get_data, "catalog-all-v2/mempool-feerates", params, client=self) @@ -4373,6 +4419,7 @@ def catalog_full_mining_pool_tips_summaries_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream" ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -4383,6 +4430,8 @@ def catalog_full_mining_pool_tips_summaries_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of mining pool tips assets :rtype: CatalogV2DataCollection @@ -4392,6 +4441,7 @@ def catalog_full_mining_pool_tips_summaries_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection(self._get_data, "catalog-all-v2/mining-pool-tips-summary", params, client=self) @@ -4401,6 +4451,7 @@ def catalog_full_transaction_tracker_assets_v2( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> CatalogV2DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -4411,6 +4462,8 @@ def catalog_full_transaction_tracker_assets_v2( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of transaction tracker assets :rtype: CatalogV2DataCollection @@ -4420,6 +4473,7 @@ def catalog_full_transaction_tracker_assets_v2( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return CatalogV2DataCollection(self._get_data, "catalog-all-v2/transaction-tracker", params, client=self) @@ -6906,6 +6960,7 @@ def reference_data_asset_metrics( reviewable: Optional[bool] = None, page_size: Optional[int] = None, paging_from: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param metrics: Comma separated list of metrics. By default all metrics are returned. @@ -6916,6 +6971,8 @@ def reference_data_asset_metrics( :type page_size: Optional[int] :param paging_from: Where does the first page start, at the start of the interval or at the end. :type paging_from: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of asset metrics metadata. :rtype: DataCollection @@ -6925,6 +6982,7 @@ def reference_data_asset_metrics( "reviewable": reviewable, "page_size": page_size, "paging_from": paging_from, + "format": format } return DataCollection( self._get_data, @@ -6948,6 +7006,7 @@ def reference_data_markets( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param markets: Comma separated list of markets. By default all markets are returned. @@ -6970,6 +7029,8 @@ def reference_data_markets( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of markets metadata. :rtype: DataCollection @@ -6985,6 +7046,7 @@ def reference_data_markets( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return DataCollection( self._get_data, @@ -7005,6 +7067,7 @@ def reference_data_exchange_metrics( metrics: Optional[Union[str, List[str]]] = None, page_size: Optional[int] = None, paging_from: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param metrics: Comma separated list of metrics. By default all metrics are returned. @@ -7013,6 +7076,8 @@ def reference_data_exchange_metrics( :type page_size: Optional[int] :param paging_from: Where does the first page start, at the start of the interval or at the end. :type paging_from: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of exchange metrics metadata. :rtype: DataCollection @@ -7021,6 +7086,7 @@ def reference_data_exchange_metrics( "metrics": metrics, "page_size": page_size, "paging_from": paging_from, + "format": format } return DataCollection( self._get_data, @@ -7037,6 +7103,7 @@ def reference_data_exchange_asset_metrics( metrics: Optional[Union[str, List[str]]] = None, page_size: Optional[int] = None, paging_from: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param metrics: Comma separated list of metrics. By default all metrics are returned. @@ -7045,6 +7112,8 @@ def reference_data_exchange_asset_metrics( :type page_size: Optional[int] :param paging_from: Where does the first page start, at the start of the interval or at the end. :type paging_from: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of exchange asset metrics metadata. :rtype: DataCollection @@ -7053,6 +7122,7 @@ def reference_data_exchange_asset_metrics( "metrics": metrics, "page_size": page_size, "paging_from": paging_from, + "format": format } return DataCollection( self._get_data, @@ -7069,6 +7139,7 @@ def reference_data_pair_metrics( metrics: Optional[Union[str, List[str]]] = None, page_size: Optional[int] = None, paging_from: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param metrics: Comma separated list of metrics. By default all metrics are returned. @@ -7077,6 +7148,8 @@ def reference_data_pair_metrics( :type page_size: Optional[int] :param paging_from: Where does the first page start, at the start of the interval or at the end. :type paging_from: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of pair metrics metadata. :rtype: DataCollection @@ -7085,6 +7158,7 @@ def reference_data_pair_metrics( "metrics": metrics, "page_size": page_size, "paging_from": paging_from, + "format": format } return DataCollection( self._get_data, @@ -7101,6 +7175,7 @@ def reference_data_institution_metrics( metrics: Optional[Union[str, List[str]]] = None, page_size: Optional[int] = None, paging_from: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param metrics: Comma separated list of metrics. By default all metrics are returned. @@ -7109,6 +7184,8 @@ def reference_data_institution_metrics( :type page_size: Optional[int] :param paging_from: Where does the first page start, at the start of the interval or at the end. :type paging_from: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of institution metrics metadata. :rtype: DataCollection @@ -7117,6 +7194,7 @@ def reference_data_institution_metrics( "metrics": metrics, "page_size": page_size, "paging_from": paging_from, + "format": format } return DataCollection( self._get_data, @@ -7134,6 +7212,7 @@ def reference_data_assets( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param assets: Comma separated list of assets. By default all assets are returned. @@ -7144,6 +7223,8 @@ def reference_data_assets( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of assets metadata. :rtype: DataCollection @@ -7153,6 +7234,7 @@ def reference_data_assets( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return DataCollection( self._get_data, @@ -7167,6 +7249,7 @@ def reference_data_exchanges( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param exchanges: Comma separated list of exchanges. By default all exchanges are returned. @@ -7177,6 +7260,8 @@ def reference_data_exchanges( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of exchanges metadata. :rtype: DataCollection @@ -7186,6 +7271,7 @@ def reference_data_exchanges( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return DataCollection( self._get_data, @@ -7200,6 +7286,7 @@ def reference_data_indexes( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param indexes: Comma separated list of indexes. By default all indexes are returned. @@ -7210,6 +7297,8 @@ def reference_data_indexes( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of indexes metadata. :rtype: DataCollection @@ -7219,6 +7308,7 @@ def reference_data_indexes( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return DataCollection( self._get_data, @@ -7233,6 +7323,7 @@ def reference_data_pairs( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param pairs: Comma separated list of asset pairs. By default, all asset pairs are returned. @@ -7243,6 +7334,8 @@ def reference_data_pairs( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of pairs metadata. :rtype: DataCollection @@ -7252,6 +7345,7 @@ def reference_data_pairs( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return DataCollection( self._get_data, @@ -7266,6 +7360,7 @@ def reference_data_market_metrics( page_size: Optional[int] = None, paging_from: Optional[str] = None, next_page_token: Optional[str] = None, + format: Optional[str] = "json_stream", ) -> DataCollection: """ :param metrics: Comma separated list of metrics. By default all metrics are returned. @@ -7276,6 +7371,8 @@ def reference_data_market_metrics( :type paging_from: Optional[str] :param next_page_token: Token for receiving the results from the next page of a query. Should not be used directly. To iterate through pages just use `next_page_url` response field. :type next_page_token: Optional[str] + :param format: Default: "json_stream" (Python API Client). Format of the response. Supported values are json, json_stream. + :type format: Optional[str] :return: List of market metrics metadata. :rtype: DataCollection @@ -7285,6 +7382,7 @@ def reference_data_market_metrics( "page_size": page_size, "paging_from": paging_from, "next_page_token": next_page_token, + "format": format } return DataCollection( self._get_data, @@ -7595,7 +7693,10 @@ def _get_data(self, url: str, params: Dict[str, Any]) -> DataReturnType: else: resp = self._send_request(actual_url) try: - data = json.loads(resp.content) + if params.get("format") == "json_stream": + data = {"data": [json.loads(i) for i in resp.iter_lines()]} + else: + data = json.loads(resp.content) except ValueError: if resp.status_code == 414: raise CoinMetricsClientQueryParamsException(response=resp) diff --git a/test/test_catalog_benchmarks.py b/test/test_catalog_benchmarks.py new file mode 100644 index 0000000..e750318 --- /dev/null +++ b/test/test_catalog_benchmarks.py @@ -0,0 +1,197 @@ +# %% +import time +import os +import pandas as pd +import pytest +from coinmetrics.api_client import CoinMetricsClient +from coinmetrics._utils import get_keys_from_catalog +from typing import Tuple, Any, Callable, Dict, no_type_check + +client = CoinMetricsClient(str(os.environ.get("CM_API_KEY")), verbose=True) +cm_api_key_set = os.environ.get("CM_API_KEY") is not None +REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" + +print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( + "CM_API_KEY not set, tests will not run" +) + + +@no_type_check +def benchmark_endpoint( + endpoint_method: Any, output_method: str, **endpoint_method_kwargs: Dict[Any, Any] +) -> Tuple[Any, float, int]: + start_time = time.time() + + if output_method == "to_dataframe": + response = endpoint_method(**endpoint_method_kwargs).to_dataframe() + elif output_method == "to_list": + response = endpoint_method(**endpoint_method_kwargs).to_list() + + end_time = time.time() + response_time = end_time - start_time + row_count = len(response) + return response, response_time, row_count + + +test_cases = [ + # ("/catalog-v2/asset-metrics", client.catalog_asset_metrics_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/exchange-metrics", client.catalog_exchange_metrics_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/exchange-asset-metrics", client.catalog_exchange_asset_metrics_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/pair-metrics", client.catalog_pair_metrics_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/institution-metrics", client.catalog_institution_metrics_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-trades", client.catalog_market_trades_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-candles", client.catalog_market_candles_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-orderbooks", client.catalog_market_orderbooks_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-quotes", client.catalog_market_quotes_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-funding-rates", client.catalog_market_funding_rates_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-funding-rates-predicted", client.catalog_full_market_funding_rates_predicted_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-contract-prices", client.catalog_market_contract_prices_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-implied-volatility", client.catalog_market_implied_volatility_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-openinterest", client.catalog_market_open_interest_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-liquidtations", client.catalog_market_liquidations_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/market-metrics", client.catalog_market_metrics_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/pair-candles", client.catalog_pair_candles_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/index-levels", client.catalog_index_levels_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/index-candles", client.catalog_index_candles_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/asset-chains", client.catalog_asset_chains_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/mempool-feerates", client.catalog_mempool_feerates_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/mining-pool-tips-summary", client.catalog_mining_pool_tips_summaries_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + # ("/catalog-v2/transaction-tracker", client.catalog_transaction_tracker_assets_v2, "to_dataframe", "json", {"page_size": 10000, format: "json"}), + ("/catalog-v2/asset-metrics", client.catalog_asset_metrics_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/exchange-metrics", client.catalog_exchange_metrics_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/exchange-asset-metrics", client.catalog_exchange_asset_metrics_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/pair-metrics", client.catalog_pair_metrics_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/institution-metrics", client.catalog_institution_metrics_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-trades", client.catalog_market_trades_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-candles", client.catalog_market_candles_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-orderbooks", client.catalog_market_orderbooks_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-quotes", client.catalog_market_quotes_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-funding-rates", client.catalog_market_funding_rates_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-funding-rates-predicted", client.catalog_full_market_funding_rates_predicted_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-contract-prices", client.catalog_market_contract_prices_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-implied-volatility", client.catalog_market_implied_volatility_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-openinterest", client.catalog_market_open_interest_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-liquidtations", client.catalog_market_liquidations_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/market-metrics", client.catalog_market_metrics_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/pair-candles", client.catalog_pair_candles_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/index-levels", client.catalog_index_levels_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/index-candles", client.catalog_index_candles_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/asset-chains", client.catalog_asset_chains_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/mempool-feerates", client.catalog_mempool_feerates_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/reference-data/assets", client.reference_data_assets, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/exchanges", client.reference_data_exchanges, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/markets", client.reference_data_markets, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/indexes", client.reference_data_indexes, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/pairs", client.reference_data_pairs, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/asset-metrics", client.reference_data_asset_metrics, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/exchange-metrics", client.reference_data_exchange_metrics, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/exchange-asset-metrics", client.reference_data_exchange_asset_metrics, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/pair-metrics", client.reference_data_pair_metrics, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/institution-metrics", client.reference_data_institution_metrics, "to_list", "json", + {"page_size": 10000, "format": "json"}), + ("/reference-data/market-metrics", client.reference_data_market_metrics, "to_list", "json", + {"page_size": 10000, "format": "json"}), + # ("/catalog-v2/mining-pool-tips-summary", client.catalog_mining_pool_tips_summaries_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + # ("/catalog-v2/transaction-tracker", client.catalog_transaction_tracker_assets_v2, "to_list", "json", {"page_size": 10000, "format": "json"}), + ("/catalog-v2/asset-metrics", client.catalog_asset_metrics_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/exchange-metrics", client.catalog_exchange_metrics_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/exchange-asset-metrics", client.catalog_exchange_asset_metrics_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/pair-metrics", client.catalog_pair_metrics_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/institution-metrics", client.catalog_institution_metrics_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-trades", client.catalog_market_trades_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-candles", client.catalog_market_candles_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-orderbooks", client.catalog_market_orderbooks_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-quotes", client.catalog_market_quotes_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-funding-rates", client.catalog_market_funding_rates_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-funding-rates-predicted", client.catalog_full_market_funding_rates_predicted_v2, "to_list", + "json_stream", {}), + ("/catalog-v2/market-contract-prices", client.catalog_market_contract_prices_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-implied-volatility", client.catalog_market_implied_volatility_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-openinterest", client.catalog_market_open_interest_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-liquidtations", client.catalog_market_liquidations_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/market-metrics", client.catalog_market_metrics_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/pair-candles", client.catalog_pair_candles_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/index-levels", client.catalog_index_levels_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/index-candles", client.catalog_index_candles_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/asset-chains", client.catalog_asset_chains_v2, "to_list", "json_stream", + {}), + ("/catalog-v2/mempool-feerates", client.catalog_mempool_feerates_v2, "to_list", "json_stream", + {}), + ("/reference-data/assets", client.reference_data_assets, "to_list", "json_stream", + {}), + ("/reference-data/exchanges", client.reference_data_exchanges, "to_list", "json_stream", + {}), + ("/reference-data/markets", client.reference_data_markets, "to_list", "json_stream", + {}), + ("/reference-data/indexes", client.reference_data_indexes, "to_list", "json_stream", + {}), + ("/reference-data/pairs", client.reference_data_pairs, "to_list", "json_stream", + {}), + ("/reference-data/asset-metrics", client.reference_data_asset_metrics, "to_list", "json_stream", + {}), + ("/reference-data/exchange-metrics", client.reference_data_exchange_metrics, "to_list", "json_stream", + {}), + ("/reference-data/exchange-asset-metrics", client.reference_data_exchange_asset_metrics, "to_list", "json_stream", + {}), + ("/reference-data/pair-metrics", client.reference_data_pair_metrics, "to_list", "json_stream", + {}), + ("/reference-data/institution-metrics", client.reference_data_institution_metrics, "to_list", "json_stream", + {}), + ("/reference-data/market-metrics", client.reference_data_market_metrics, "to_list", "json_stream", + {}), + # ("/catalog-v2/mining-pool-tips-summary", client.catalog_mining_pool_tips_summaries_v2, "to_list", "json_stream", + # {}), + # ("/catalog-v2/transaction-tracker", client.catalog_transaction_tracker_assets_v2, "to_list", "json_stream", + # {}) +] + + +@no_type_check +@pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) +def benchmark_results() -> None: + benchmark_results = [] + + for name, endpoint_method, output_method, fmt, endpoint_method_kwargs in test_cases: + print(f"Requesting {name} output method {output_method} and format {fmt}.") + response, response_time, row_count = benchmark_endpoint( + endpoint_method, output_method, **endpoint_method_kwargs + ) + benchmark_results.append((name, output_method, fmt, response_time, row_count)) + + # %% + print(f"{'Endpoint':<60} {'Output Method':<20} {'Response Time':>23} {'Rows':>10}") + print("-" * 95) + for name, output_method, fmt, response_time, row_count in benchmark_results: + print(f"{name:<60} {fmt:<20} {response_time:>15.2f} seconds {row_count:>10}") + + # %% + results_df = pd.DataFrame(benchmark_results, columns=["Endpoint", "Output Method", "Format", "Response Time", "Rows"]) + print(results_df) + # results_df.to_csv("benchmark_results.csv", index=False) diff --git a/test/test_catalogs_v2.py b/test/test_catalogs_v2.py index 4cc61c7..7885bfd 100644 --- a/test/test_catalogs_v2.py +++ b/test/test_catalogs_v2.py @@ -15,53 +15,57 @@ @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_trades() -> None: - catalog_market_trades = client.catalog_market_trades_v2(page_size=10).first_page() + catalog_market_trades = client.catalog_market_trades_v2(page_size=10, format='json').first_page() assert len(catalog_market_trades) == 10 assert all(['market' in catalog for catalog in catalog_market_trades]) df_market_trades = client.catalog_market_trades_v2(markets="coinbase-btc-usd-spot").to_dataframe() list_market_trades = client.catalog_market_trades_v2(markets="coinbase-btc-usd-spot").to_list() catalog_fields = get_keys_from_catalog(list_market_trades[0]) + assert len(list_market_trades) > 0 assert set(df_market_trades.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_trades() -> None: - catalog_market_trades = client.catalog_full_market_trades_v2(page_size=10).first_page() + catalog_market_trades = client.catalog_full_market_trades_v2(page_size=10, format='json').first_page() assert len(catalog_market_trades) == 10 assert all(['market' in catalog for catalog in catalog_market_trades]) df_market_trades = client.catalog_full_market_trades_v2(markets="coinbase-btc-usd-spot").to_dataframe() list_market_trades = client.catalog_full_market_trades_v2(markets="coinbase-btc-usd-spot").to_list() catalog_fields = get_keys_from_catalog(list_market_trades[0]) + assert len(list_market_trades) > 0 assert set(df_market_trades.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_candles() -> None: - catalog_market_candles = client.catalog_full_market_candles_v2(page_size=10).first_page() + catalog_market_candles = client.catalog_full_market_candles_v2(page_size=10, format='json').first_page() assert len(catalog_market_candles) == 10 assert all(['market' in catalog for catalog in catalog_market_candles]) assert all(['frequencies' in catalog for catalog in catalog_market_candles]) df_market_candles = client.catalog_full_market_candles_v2(markets="coinbase-btc-usd-spot").to_dataframe() list_market_candles = client.catalog_full_market_candles_v2(markets="coinbase-btc-usd-spot").to_list() catalog_fields = get_keys_from_catalog(list_market_candles[0]) + assert len(list_market_candles) > 0 assert set(df_market_candles.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_candles() -> None: - catalog_market_candles = client.catalog_market_candles_v2(page_size=10).first_page() + catalog_market_candles = client.catalog_market_candles_v2(page_size=10, format='json').first_page() assert len(catalog_market_candles) == 10 assert all(['market' in catalog for catalog in catalog_market_candles]) assert all(['frequencies' in catalog for catalog in catalog_market_candles]) df_market_candles = client.catalog_market_candles_v2(markets="coinbase-btc-usd-spot").to_dataframe() list_market_candles = client.catalog_market_candles_v2(markets="coinbase-btc-usd-spot").to_list() catalog_fields = get_keys_from_catalog(list_market_candles[0]) + assert len(list_market_candles) > 0 assert set(df_market_candles.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_contract_prices() -> None: - catalog_contract_prices = client.catalog_market_contract_prices_v2(page_size=10).first_page() + catalog_contract_prices = client.catalog_market_contract_prices_v2(page_size=10, format='json').first_page() assert len(catalog_contract_prices) == 10 assert all(['market' in catalog for catalog in catalog_contract_prices]) assert all(['min_time' in catalog for catalog in catalog_contract_prices]) @@ -69,12 +73,13 @@ def test_catalogv2_contract_prices() -> None: df_market_contract_prices = client.catalog_market_contract_prices_v2(markets="deribit-BTC-15OCT21-60000-C-option").to_dataframe() list_market_contract_prices = client.catalog_market_contract_prices_v2(markets="deribit-BTC-15OCT21-60000-C-option").to_list() catalog_fields = get_keys_from_catalog(list_market_contract_prices[0]) + assert len(list_market_contract_prices) > 0 assert set(df_market_contract_prices.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_contract_prices() -> None: - catalog_contract_prices = client.catalog_full_market_contract_prices_v2(page_size=10).first_page() + catalog_contract_prices = client.catalog_full_market_contract_prices_v2(page_size=10, format='json').first_page() assert len(catalog_contract_prices) == 10 assert all(['market' in catalog for catalog in catalog_contract_prices]) assert all(['min_time' in catalog for catalog in catalog_contract_prices]) @@ -82,12 +87,13 @@ def test_catalogv2_full_contract_prices() -> None: df_market_contract_prices = client.catalog_full_market_contract_prices_v2(markets="deribit-BTC-15OCT21-60000-C-option").to_dataframe() list_market_contract_prices = client.catalog_full_market_contract_prices_v2(markets="deribit-BTC-15OCT21-60000-C-option").to_list() catalog_fields = get_keys_from_catalog(list_market_contract_prices[0]) + assert len(list_market_contract_prices) > 0 assert set(df_market_contract_prices.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_funding_rates() -> None: - catalog_funding_rates = client.catalog_full_market_funding_rates_v2(page_size=10).first_page() + catalog_funding_rates = client.catalog_full_market_funding_rates_v2(page_size=10, format='json').first_page() assert len(catalog_funding_rates) == 10 assert all(['market' in catalog for catalog in catalog_funding_rates]) assert all(['min_time' in catalog for catalog in catalog_funding_rates]) @@ -99,12 +105,13 @@ def test_catalogv2_full_market_funding_rates() -> None: markets='binance-1000BONKUSDC-future' ).to_list() catalog_fields = get_keys_from_catalog(list_market_funding_rates[0]) + assert len(list_market_funding_rates) > 0 assert set(df_market_funding_rates.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_funding_rates_predicted() -> None: - catalog_funding_rates = client.catalog_full_market_funding_rates_predicted_v2(page_size=10).first_page() + catalog_funding_rates = client.catalog_full_market_funding_rates_predicted_v2(page_size=10, format='json').first_page() assert len(catalog_funding_rates) == 10 assert all(['market' in catalog for catalog in catalog_funding_rates]) assert all(['min_time' in catalog for catalog in catalog_funding_rates]) @@ -116,12 +123,13 @@ def test_catalogv2_full_market_funding_rates_predicted() -> None: markets='bybit-10000000AIDOGEUSDT-future' ).to_list() catalog_fields = get_keys_from_catalog(list_market_funding_rates_predicted[0]) + assert len(list_market_funding_rates_predicted) > 0 assert set(df_market_funding_rates_predicted.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_funding_rates() -> None: - catalog_funding_rates = client.catalog_market_funding_rates_v2(page_size=10).first_page() + catalog_funding_rates = client.catalog_market_funding_rates_v2(page_size=10, format='json').first_page() assert len(catalog_funding_rates) == 10 assert all(['market' in catalog for catalog in catalog_funding_rates]) assert all(['min_time' in catalog for catalog in catalog_funding_rates]) @@ -133,12 +141,13 @@ def test_catalogv2_market_funding_rates() -> None: markets='binance-1000BONKUSDC-future' ).to_list() catalog_fields = get_keys_from_catalog(list_market_funding_rates[0]) + assert len(list_market_funding_rates) > 0 assert set(df_market_funding_rates.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_funding_rates_predicted() -> None: - catalog_funding_rates = client.catalog_market_funding_rates_predicted_v2(page_size=10).first_page() + catalog_funding_rates = client.catalog_market_funding_rates_predicted_v2(page_size=10, format='json').first_page() assert len(catalog_funding_rates) == 10 assert all(['market' in catalog for catalog in catalog_funding_rates]) assert all(['min_time' in catalog for catalog in catalog_funding_rates]) @@ -150,12 +159,13 @@ def test_catalogv2_market_funding_rates_predicted() -> None: markets='bybit-10000000AIDOGEUSDT-future' ).to_list() catalog_fields = get_keys_from_catalog(list_market_funding_rates_predicted[0]) + assert len(list_market_funding_rates_predicted) > 0 assert set(df_market_funding_rates_predicted.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_greeks() -> None: - catalog_greeks = client.catalog_market_greeks_v2(page_size=10).first_page() + catalog_greeks = client.catalog_market_greeks_v2(page_size=10, format='json').first_page() assert len(catalog_greeks) == 10 assert all(['market' in catalog for catalog in catalog_greeks]) assert all(['min_time' in catalog for catalog in catalog_greeks]) @@ -163,12 +173,13 @@ def test_catalogv2_market_greeks() -> None: df_market_greeks = client.catalog_market_greeks_v2(markets="deribit-BTC-15OCT21-60000-C-option").to_dataframe() list_market_greeks = client.catalog_market_greeks_v2(markets="deribit-BTC-15OCT21-60000-C-option").to_list() catalog_fields = get_keys_from_catalog(list_market_greeks[0]) + assert len(list_market_greeks) > 0 assert set(df_market_greeks.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_greeks() -> None: - catalog_greeks = client.catalog_full_market_greeks_v2(page_size=10).first_page() + catalog_greeks = client.catalog_full_market_greeks_v2(page_size=10, format='json').first_page() assert len(catalog_greeks) == 10 assert all(['market' in catalog for catalog in catalog_greeks]) assert all(['min_time' in catalog for catalog in catalog_greeks]) @@ -176,42 +187,45 @@ def test_catalogv2_full_market_greeks() -> None: df_market_greeks = client.catalog_full_market_greeks_v2(markets="deribit-BTC-15OCT21-60000-C-option").to_dataframe() list_market_greeks = client.catalog_full_market_greeks_v2(markets="deribit-BTC-15OCT21-60000-C-option").to_list() catalog_fields = get_keys_from_catalog(list_market_greeks[0]) + assert len(list_market_greeks) > 0 assert set(df_market_greeks.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_implied_volatility() -> None: - catalog_market_implied_vol = client.catalog_full_market_implied_volatility_v2(page_size=10).first_page() + catalog_market_implied_vol = client.catalog_full_market_implied_volatility_v2(page_size=10, format='json').first_page() assert len(catalog_market_implied_vol) == 10 assert all(['market' in catalog for catalog in catalog_market_implied_vol]) assert all(['min_time' in catalog for catalog in catalog_market_implied_vol]) assert all(['max_time' in catalog for catalog in catalog_market_implied_vol]) df_market_implied_volatility = client.catalog_full_market_implied_volatility_v2( - markets='binance-BNB-240620-550-C-option', page_size=10000).to_dataframe() + markets='binance-BNB-240620-550-C-option', page_size=10, format='json').to_dataframe() list_market_implied_volatility = client.catalog_full_market_implied_volatility_v2( - markets='binance-BNB-240620-550-C-option', page_size=10000).to_list() + markets='binance-BNB-240620-550-C-option', page_size=10, format='json').to_list() catalog_fields = get_keys_from_catalog(list_market_implied_volatility[0]) + assert len(list_market_implied_volatility) > 0 assert set(df_market_implied_volatility.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_implied_volatility() -> None: - catalog_market_implied_vol = client.catalog_market_implied_volatility_v2(page_size=10).first_page() + catalog_market_implied_vol = client.catalog_market_implied_volatility_v2(page_size=10, format='json').first_page() assert len(catalog_market_implied_vol) == 10 assert all(['market' in catalog for catalog in catalog_market_implied_vol]) assert all(['min_time' in catalog for catalog in catalog_market_implied_vol]) assert all(['max_time' in catalog for catalog in catalog_market_implied_vol]) df_market_implied_volatility = client.catalog_market_implied_volatility_v2( - markets='binance-BNB-240620-550-C-option', page_size=10000).to_dataframe() + markets='binance-BNB-240620-550-C-option', page_size=10, format='json').to_dataframe() list_market_implied_volatility = client.catalog_market_implied_volatility_v2( - markets='binance-BNB-240620-550-C-option', page_size=10000).to_list() + markets='binance-BNB-240620-550-C-option', page_size=10, format='json').to_list() catalog_fields = get_keys_from_catalog(list_market_implied_volatility[0]) + assert len(list_market_implied_volatility) > 0 assert set(df_market_implied_volatility.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_liquidations() -> None: - catalog_market_liquidations = client.catalog_market_liquidations_v2(page_size=10).first_page() + catalog_market_liquidations = client.catalog_market_liquidations_v2(page_size=10, format='json').first_page() assert len(catalog_market_liquidations) == 10 assert all(['market' in catalog for catalog in catalog_market_liquidations]) assert all(['min_time' in catalog for catalog in catalog_market_liquidations]) @@ -219,12 +233,13 @@ def test_catalogv2_market_liquidations() -> None: df_market_liquidations = client.catalog_market_liquidations_v2(markets="binance-BTCUSDT-future").to_dataframe() list_market_liquidations = client.catalog_market_liquidations_v2(markets="binance-BTCUSDT-future").to_list() catalog_fields = get_keys_from_catalog(list_market_liquidations[0]) + assert len(list_market_liquidations) > 0 assert set(df_market_liquidations.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_liquidations() -> None: - catalog_market_liquidations = client.catalog_full_market_liquidations_v2(page_size=10).first_page() + catalog_market_liquidations = client.catalog_full_market_liquidations_v2(page_size=10, format='json').first_page() assert len(catalog_market_liquidations) == 10 assert all(['market' in catalog for catalog in catalog_market_liquidations]) assert all(['min_time' in catalog for catalog in catalog_market_liquidations]) @@ -232,12 +247,13 @@ def test_catalogv2_full_market_liquidations() -> None: df_market_liquidations = client.catalog_full_market_liquidations_v2(markets="binance-BTCUSDT-future").to_dataframe() list_market_liquidations = client.catalog_full_market_liquidations_v2(markets="binance-BTCUSDT-future").to_list() catalog_fields = get_keys_from_catalog(list_market_liquidations[0]) + assert len(list_market_liquidations) > 0 assert set(df_market_liquidations.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_openinterest() -> None: - catalog_market_openinterest = client.catalog_full_market_open_interest_v2(page_size=10).first_page() + catalog_market_openinterest = client.catalog_full_market_open_interest_v2(page_size=10, format='json').first_page() assert len(catalog_market_openinterest) == 10 assert all(['market' in catalog for catalog in catalog_market_openinterest]) assert all(['min_time' in catalog for catalog in catalog_market_openinterest]) @@ -245,12 +261,13 @@ def test_catalogv2_full_market_openinterest() -> None: df_market_open_interest = client.catalog_full_market_open_interest_v2(markets="binance-BTCUSDT-future").to_dataframe() list_market_open_interest = client.catalog_full_market_open_interest_v2(markets="binance-BTCUSDT-future").to_list() catalog_fields = get_keys_from_catalog(list_market_open_interest[0]) + assert len(list_market_open_interest) > 0 assert set(df_market_open_interest.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_openinterest() -> None: - catalog_market_openinterest = client.catalog_market_open_interest_v2(page_size=10).first_page() + catalog_market_openinterest = client.catalog_market_open_interest_v2(page_size=10, format='json').first_page() assert len(catalog_market_openinterest) == 10 assert all(['market' in catalog for catalog in catalog_market_openinterest]) assert all(['min_time' in catalog for catalog in catalog_market_openinterest]) @@ -258,24 +275,26 @@ def test_catalogv2_market_openinterest() -> None: df_market_open_interest = client.catalog_market_open_interest_v2(markets="binance-BTCUSDT-future").to_dataframe() list_market_open_interest = client.catalog_market_open_interest_v2(markets="binance-BTCUSDT-future").to_list() catalog_fields = get_keys_from_catalog(list_market_open_interest[0]) + assert len(list_market_open_interest) > 0 assert set(df_market_open_interest.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_orderbooks() -> None: - catalog_market_orderbooks = client.catalog_market_orderbooks_v2(page_size=10).first_page() + catalog_market_orderbooks = client.catalog_market_orderbooks_v2(page_size=10, format='json').first_page() assert len(catalog_market_orderbooks) == 10 assert all(['market' in catalog for catalog in catalog_market_orderbooks]) assert all(['depths' in catalog for catalog in catalog_market_orderbooks]) df_market_orderbooks = client.catalog_market_orderbooks_v2(markets="coinbase-btc-usd-spot").to_dataframe() list_market_orderbooks = client.catalog_market_orderbooks_v2(markets="coinbase-btc-usd-spot").to_list() catalog_fields = get_keys_from_catalog(list_market_orderbooks[0]) + assert len(list_market_orderbooks) > 0 assert set(df_market_orderbooks.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_quotes() -> None: - catalog_market_quotes = client.catalog_market_quotes_v2(page_size=10).first_page() + catalog_market_quotes = client.catalog_market_quotes_v2(page_size=10, format='json').first_page() assert len(catalog_market_quotes) == 10 assert all(['market' in catalog for catalog in catalog_market_quotes]) assert all(['min_time' in catalog for catalog in catalog_market_quotes]) @@ -283,12 +302,13 @@ def test_catalogv2_market_quotes() -> None: df_market_quotes = client.catalog_market_quotes_v2(markets="coinbase-btc-usd-spot").to_dataframe() list_market_quotes = client.catalog_market_quotes_v2(markets="coinbase-btc-usd-spot").to_list() catalog_fields = get_keys_from_catalog(list_market_quotes[0]) + assert len(list_market_quotes) > 0 assert set(df_market_quotes.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_quotes() -> None: - catalog_market_quotes = client.catalog_full_market_quotes_v2(page_size=10).first_page() + catalog_market_quotes = client.catalog_full_market_quotes_v2(page_size=10, format='json').first_page() assert len(catalog_market_quotes) == 10 assert all(['market' in catalog for catalog in catalog_market_quotes]) assert all(['min_time' in catalog for catalog in catalog_market_quotes]) @@ -296,24 +316,26 @@ def test_catalogv2_full_market_quotes() -> None: df_market_quotes = client.catalog_full_market_quotes_v2(markets="coinbase-btc-usd-spot").to_dataframe() list_market_quotes = client.catalog_full_market_quotes_v2(markets="coinbase-btc-usd-spot").to_list() catalog_fields = get_keys_from_catalog(list_market_quotes[0]) + assert len(list_market_quotes) > 0 assert set(df_market_quotes.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_orderbooks() -> None: - catalog_market_orderbooks = client.catalog_full_market_orderbooks_v2(page_size=10).first_page() + catalog_market_orderbooks = client.catalog_full_market_orderbooks_v2(page_size=10, format='json').first_page() assert len(catalog_market_orderbooks) == 10 assert all(['market' in catalog for catalog in catalog_market_orderbooks]) assert all(['depths' in catalog for catalog in catalog_market_orderbooks]) list_market_orderbooks = client.catalog_full_market_orderbooks_v2(markets="coinbase-btc-usd-spot").to_list() df_market_orderbooks = client.catalog_full_market_orderbooks_v2(markets="coinbase-btc-usd-spot").to_dataframe() catalog_fields = get_keys_from_catalog(list_market_orderbooks[0]) + assert len(list_market_orderbooks) > 0 assert set(df_market_orderbooks.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_market_metrics() -> None: - catalog_market_metrics = client.catalog_full_market_metrics_v2(page_size=10).first_page() + catalog_market_metrics = client.catalog_full_market_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_market_metrics) == 10 assert all(['market' in catalog for catalog in catalog_market_metrics]) assert all(['metrics' in catalog for catalog in catalog_market_metrics]) @@ -324,12 +346,13 @@ def test_catalogv2_full_market_metrics() -> None: markets='coinbase-btc-usd-spot', metrics='liquidity_slippage_10K_ask_percent' ).to_dataframe() catalog_fields = get_keys_from_catalog(list_market_metrics[0]) + assert len(list_market_metrics) > 0 assert set(df_market_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_market_metrics() -> None: - catalog_market_metrics = client.catalog_market_metrics_v2(page_size=10).first_page() + catalog_market_metrics = client.catalog_market_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_market_metrics) == 10 assert all(['market' in catalog for catalog in catalog_market_metrics]) assert all(['metrics' in catalog for catalog in catalog_market_metrics]) @@ -340,36 +363,39 @@ def test_catalogv2_market_metrics() -> None: markets='coinbase-btc-usd-spot', metrics='liquidity_slippage_10K_ask_percent' ).to_dataframe() catalog_fields = get_keys_from_catalog(list_market_metrics[0]) + assert len(list_market_metrics) > 0 assert set(df_market_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_asset_metrics() -> None: - catalog_asset_metrics = client.catalog_asset_metrics_v2(page_size=10).first_page() + catalog_asset_metrics = client.catalog_asset_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_asset_metrics) == 10 assert all(['asset' in catalog for catalog in catalog_asset_metrics]) assert all(['metrics' in catalog for catalog in catalog_asset_metrics]) list_asset_metrics = client.catalog_asset_metrics_v2(assets='btc', metrics='PriceUSD').to_list() df_asset_metrics = client.catalog_asset_metrics_v2(assets='btc', metrics='PriceUSD').to_dataframe() catalog_fields = get_keys_from_catalog(list_asset_metrics[0]) + assert len(list_asset_metrics) > 0 assert set(df_asset_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_asset_metrics() -> None: - catalog_asset_metrics = client.catalog_full_asset_metrics_v2(page_size=10).first_page() + catalog_asset_metrics = client.catalog_full_asset_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_asset_metrics) == 10 assert all(['asset' in catalog for catalog in catalog_asset_metrics]) assert all(['metrics' in catalog for catalog in catalog_asset_metrics]) list_asset_metrics = client.catalog_full_asset_metrics_v2(assets='btc', metrics='PriceUSD').to_list() df_asset_metrics = client.catalog_full_asset_metrics_v2(assets='btc', metrics='PriceUSD').to_dataframe() catalog_fields = get_keys_from_catalog(list_asset_metrics[0]) + assert len(list_asset_metrics) > 0 assert set(df_asset_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_exchange_metrics() -> None: - catalog_exchange_metrics = client.catalog_exchange_metrics_v2(page_size=10).first_page() + catalog_exchange_metrics = client.catalog_exchange_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_exchange_metrics) == 10 assert all(['exchange' in catalog for catalog in catalog_exchange_metrics]) assert all(['metrics' in catalog for catalog in catalog_exchange_metrics]) @@ -381,12 +407,13 @@ def test_catalogv2_exchange_metrics() -> None: metrics='volume_reported_spot_usd_1h' ).to_dataframe() catalog_fields = get_keys_from_catalog(list_exchange_metrics[0]) + assert len(list_exchange_metrics) > 0 assert set(df_exchange_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_exchange_metrics() -> None: - catalog_exchange_metrics = client.catalog_full_exchange_metrics_v2(page_size=10).first_page() + catalog_exchange_metrics = client.catalog_full_exchange_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_exchange_metrics) == 10 assert all(['exchange' in catalog for catalog in catalog_exchange_metrics]) assert all(['metrics' in catalog for catalog in catalog_exchange_metrics]) @@ -398,11 +425,13 @@ def test_catalogv2_full_exchange_metrics() -> None: metrics='volume_reported_spot_usd_1h' ).to_dataframe() catalog_fields = get_keys_from_catalog(list_exchange_metrics[0]) + assert len(list_exchange_metrics) > 0 assert set(df_exchange_metrics.columns) == catalog_fields + @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_exchange_asset_metrics() -> None: - catalog_exchange_metrics = client.catalog_exchange_asset_metrics_v2(page_size=10).first_page() + catalog_exchange_metrics = client.catalog_exchange_asset_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_exchange_metrics) == 10 assert all(['exchange_asset' in catalog for catalog in catalog_exchange_metrics]) assert all(['metrics' in catalog for catalog in catalog_exchange_metrics]) @@ -415,12 +444,13 @@ def test_catalogv2_exchange_asset_metrics() -> None: metrics='volume_reported_spot_usd_1h' ).to_dataframe() catalog_fields = get_keys_from_catalog(list_exchange_asset_metrics[0]) + assert len(list_exchange_asset_metrics) > 0 assert set(df_exchange_asset_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_exchange_asset_metrics() -> None: - catalog_exchange_metrics = client.catalog_full_exchange_asset_metrics_v2(page_size=10).first_page() + catalog_exchange_metrics = client.catalog_full_exchange_asset_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_exchange_metrics) == 10 assert all(['exchange_asset' in catalog for catalog in catalog_exchange_metrics]) assert all(['metrics' in catalog for catalog in catalog_exchange_metrics]) @@ -433,59 +463,64 @@ def test_catalogv2_full_exchange_asset_metrics() -> None: metrics='volume_reported_spot_usd_1h' ).to_dataframe() catalog_fields = get_keys_from_catalog(list_exchange_asset_metrics[0]) + assert len(list_exchange_asset_metrics) > 0 assert set(df_exchange_asset_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_pair_metrics() -> None: - catalog_pair_metrics = client.catalog_pair_metrics_v2(page_size=10).first_page() + catalog_pair_metrics = client.catalog_pair_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_pair_metrics) == 10 assert all(['pair' in catalog for catalog in catalog_pair_metrics]) assert all(['metrics' in catalog for catalog in catalog_pair_metrics]) list_pair_metrics = client.catalog_pair_metrics_v2(pairs='btc-usd', metrics='volume_reported_spot_usd_1h').to_list() df_pair_metrics = client.catalog_pair_metrics_v2(pairs='btc-usd', metrics='volume_reported_spot_usd_1h').to_dataframe() catalog_fields = get_keys_from_catalog(list_pair_metrics[0]) + assert len(list_pair_metrics) > 0 assert set(df_pair_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_exchange_full_pair_metrics() -> None: - catalog_pair_metrics = client.catalog_full_pair_metrics_v2(page_size=10).first_page() + catalog_pair_metrics = client.catalog_full_pair_metrics_v2(page_size=10, format='json').first_page() assert len(catalog_pair_metrics) == 10 assert all(['pair' in catalog for catalog in catalog_pair_metrics]) assert all(['metrics' in catalog for catalog in catalog_pair_metrics]) list_pair_metrics = client.catalog_full_pair_metrics_v2(pairs='btc-usd', metrics='volume_reported_spot_usd_1h').to_list() df_pair_metrics = client.catalog_full_pair_metrics_v2(pairs='btc-usd', metrics='volume_reported_spot_usd_1h').to_dataframe() catalog_fields = get_keys_from_catalog(list_pair_metrics[0]) + assert len(list_pair_metrics) > 0 assert set(df_pair_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_institution_pair_metrics() -> None: - catalog_institution_metrics = client.catalog_institution_metrics_v2(page_size=10).first_page() + catalog_institution_metrics = client.catalog_institution_metrics_v2(page_size=10, format='json').first_page() assert all(['institution' in catalog for catalog in catalog_institution_metrics]) assert all(['metrics' in catalog for catalog in catalog_institution_metrics]) list_institution_metrics = client.catalog_institution_metrics_v2(institutions='grayscale').to_list() df_institution_metrics = client.catalog_institution_metrics_v2(institutions='grayscale').to_dataframe() catalog_fields = get_keys_from_catalog(list_institution_metrics[0]) + assert len(list_institution_metrics) > 0 assert set(df_institution_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_full_institution_pair_metrics() -> None: - catalog_institution_metrics = client.catalog_full_institution_metrics_v2(page_size=10).first_page() + catalog_institution_metrics = client.catalog_full_institution_metrics_v2(page_size=10, format='json').first_page() assert all(['institution' in catalog for catalog in catalog_institution_metrics]) assert all(['metrics' in catalog for catalog in catalog_institution_metrics]) list_institution_metrics = client.catalog_full_institution_metrics_v2(institutions='grayscale').to_list() df_institution_metrics = client.catalog_full_institution_metrics_v2(institutions='grayscale').to_dataframe() catalog_fields = get_keys_from_catalog(list_institution_metrics[0]) + assert len(list_institution_metrics) > 0 assert set(df_institution_metrics.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_pair_candles() -> None: - catalog_pair_candles = client.catalog_pair_candles_v2(page_size=10).first_page() - catalog_full_pair_candles = client.catalog_full_pair_candles_v2(page_size=10).first_page() + catalog_pair_candles = client.catalog_pair_candles_v2(page_size=10, format='json').first_page() + catalog_full_pair_candles = client.catalog_full_pair_candles_v2(page_size=10, format='json').first_page() assert all(['pair' in catalog for catalog in catalog_pair_candles]) assert all(['pair' in catalog for catalog in catalog_full_pair_candles]) assert all(['frequencies' in catalog for catalog in catalog_pair_candles]) @@ -493,13 +528,14 @@ def test_catalogv2_pair_candles() -> None: df_candles = client.catalog_pair_candles_v2(pairs="btc-usd").to_dataframe() list_candles = client.catalog_pair_candles_v2(pairs="btc-usd").to_list() catalog_fields = get_keys_from_catalog(list_candles[0]) + assert len(list_candles) > 0 assert set(df_candles.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_index_candles() -> None: - catalog_index_candles = client.catalog_index_candles_v2(page_size=10).first_page() - catalog_full_index_candles = client.catalog_full_index_candles_v2(page_size=10).first_page() + catalog_index_candles = client.catalog_index_candles_v2(page_size=10, format='json').first_page() + catalog_full_index_candles = client.catalog_full_index_candles_v2(page_size=10, format='json').first_page() assert all(['index' in catalog for catalog in catalog_index_candles]) assert all(['index' in catalog for catalog in catalog_full_index_candles]) assert all(['frequencies' in catalog for catalog in catalog_index_candles]) @@ -507,13 +543,14 @@ def test_catalogv2_index_candles() -> None: df_candles = client.catalog_index_candles_v2(indexes="CMBI10").to_dataframe() list_candles = client.catalog_index_candles_v2(indexes="CMBI10").to_list() catalog_fields = get_keys_from_catalog(list_candles[0]) + assert len(list_candles) > 0 assert set(df_candles.columns) == catalog_fields @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_asset_chains() -> None: - catalog_asset_chains = client.catalog_asset_chains_v2(page_size=10).first_page() - catalog_full_asset_chains = client.catalog_full_asset_chains_v2(page_size=10).first_page() + catalog_asset_chains = client.catalog_asset_chains_v2(page_size=10, format='json').first_page() + catalog_full_asset_chains = client.catalog_full_asset_chains_v2(page_size=10, format='json').first_page() assert all(['asset' in catalog for catalog in catalog_asset_chains]) assert all(['asset' in catalog for catalog in catalog_full_asset_chains]) assert all(['min_time' in catalog for catalog in catalog_asset_chains]) @@ -524,8 +561,8 @@ def test_catalogv2_asset_chains() -> None: @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_mempool_feerates() -> None: - catalog_mempool_feerates = client.catalog_mempool_feerates_v2(page_size=10).first_page() - catalog_full_mempool_feerates = client.catalog_full_mempool_feerates_v2(page_size=10).first_page() + catalog_mempool_feerates = client.catalog_mempool_feerates_v2(page_size=10, format='json').first_page() + catalog_full_mempool_feerates = client.catalog_full_mempool_feerates_v2(page_size=10, format='json').first_page() assert all(['asset' in catalog for catalog in catalog_mempool_feerates]) assert all(['asset' in catalog for catalog in catalog_full_mempool_feerates]) assert all(['min_time' in catalog for catalog in catalog_mempool_feerates]) @@ -536,8 +573,8 @@ def test_catalogv2_mempool_feerates() -> None: @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_mining_pool_tips() -> None: - catalog_mining_pool_tips = client.catalog_asset_chains_v2(page_size=10).first_page() - catalog_full_mining_pool_tips = client.catalog_full_asset_chains_v2(page_size=10).first_page() + catalog_mining_pool_tips = client.catalog_asset_chains_v2(page_size=10, format='json').first_page() + catalog_full_mining_pool_tips = client.catalog_full_asset_chains_v2(page_size=10, format='json').first_page() assert all(['asset' in catalog for catalog in catalog_mining_pool_tips]) assert all(['asset' in catalog for catalog in catalog_full_mining_pool_tips]) assert all(['min_time' in catalog for catalog in catalog_mining_pool_tips]) @@ -548,8 +585,8 @@ def test_catalogv2_mining_pool_tips() -> None: @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_transaction_tracker() -> None: - catalog_transaction_tracker = client.catalog_transaction_tracker_assets_v2(page_size=10).first_page() - catalog_full_transaction_tracker = client.catalog_full_transaction_tracker_assets_v2(page_size=10).first_page() + catalog_transaction_tracker = client.catalog_transaction_tracker_assets_v2(page_size=10, format='json').first_page() + catalog_full_transaction_tracker = client.catalog_full_transaction_tracker_assets_v2(page_size=10, format='json').first_page() assert all(['asset' in catalog for catalog in catalog_transaction_tracker]) assert all(['asset' in catalog for catalog in catalog_full_transaction_tracker]) assert all(['min_time' in catalog for catalog in catalog_transaction_tracker]) @@ -560,9 +597,9 @@ def test_catalogv2_transaction_tracker() -> None: @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) def test_catalogv2_index_levels() -> None: - catalog_index_levels = client.catalog_index_levels_v2(page_size=10).first_page() - catalog_all_index_levels = client.catalog_index_levels_v2(page_size=10).first_page() - assert all(['index' in catalog for catalog in catalog_all_index_levels]) + catalog_index_levels = client.catalog_index_levels_v2(page_size=10, format='json').first_page() + catalog_all_index_levels = client.catalog_index_levels_v2(page_size=10, format='json').first_page() + assert all(['index' in catalog for catalog in catalog_index_levels]) assert all(['index' in catalog for catalog in catalog_all_index_levels]) assert all(['frequencies' in catalog for catalog in catalog_index_levels]) assert all(['frequencies' in catalog for catalog in catalog_all_index_levels])