├── test.txt ├── test ├── __init__.py ├── data │ ├── catalog_market_orderbooks.csv │ ├── catalog_institutions.csv │ ├── catalog_market_quotes.csv │ ├── catalog_market_trades.csv │ ├── catalog_asset_pairs.csv │ ├── catalog_exchange_assets.csv │ ├── catalog_indexes.csv │ ├── catalog_markets.csv │ ├── catalog_assets_metrics.csv │ ├── catalog_exchanges_metrics.csv │ ├── catalog_asset_pair_candles.csv │ ├── catalog_assets_markets.csv │ ├── catalog_metrics.csv │ └── catalog_exchanges_markets.csv ├── test_security_master_methods.py ├── test_debugging.py ├── test_constituent_methods.py ├── test_rate_limits.py ├── test_blockchain_methods.py ├── test_models.py ├── test_custom_exceptions.py ├── test_api_methods.py ├── test_to_list.py └── test_refd_methods.py ├── coinmetrics ├── py.typed ├── __init__.py ├── constants.py ├── _typing.py ├── _models.py ├── _exceptions.py ├── schema_resolver.py └── build.py ├── MANIFEST.in ├── docs ├── site │ ├── assets │ │ ├── javascripts │ │ │ └── lunr │ │ │ │ └── min │ │ │ │ ├── lunr.jp.min.js │ │ │ │ ├── lunr.vi.min.js │ │ │ │ ├── lunr.multi.min.js │ │ │ │ ├── lunr.th.min.js │ │ │ │ ├── lunr.hy.min.js │ │ │ │ ├── lunr.te.min.js │ │ │ │ ├── lunr.ta.min.js │ │ │ │ ├── lunr.zh.min.js │ │ │ │ ├── lunr.ja.min.js │ │ │ │ ├── lunr.hi.min.js │ │ │ │ ├── lunr.kn.min.js │ │ │ │ ├── lunr.sa.min.js │ │ │ │ ├── lunr.stemmer.support.min.js │ │ │ │ ├── lunr.ko.min.js │ │ │ │ ├── lunr.sv.min.js │ │ │ │ ├── lunr.da.min.js │ │ │ │ ├── lunr.no.min.js │ │ │ │ └── lunr.he.min.js │ │ ├── images │ │ │ ├── logo.png │ │ │ ├── api_flow.png │ │ │ ├── favicon.png │ │ │ ├── API Flow.pptx │ │ │ ├── cm-dark-combination.png │ │ │ └── cm-dark-combination@2x.png │ │ └── stylesheets │ │ │ └── palette.06af60db.min.css.map │ ├── sitemap.xml.gz │ ├── stylesheets │ │ └── extra.css │ └── sitemap.xml ├── docs │ ├── assets │ │ └── images │ │ │ ├── logo.png │ │ │ ├── api_flow.png │ │ │ ├── API Flow.pptx │ │ │ ├── cm-dark-combination.png │ │ │ └── cm-dark-combination@2x.png │ ├── stylesheets │ │ └── extra.css │ ├── user-guide │ │ ├── wildcards.md │ │ └── examples.md │ └── index.md ├── processors │ └── pydoc_markdown_processors.py ├── source │ ├── index.rst │ └── conf.py ├── Makefile ├── make.bat └── mkdocs.yml ├── .flake8 ├── pydoc-markdown.yml ├── examples ├── api_doc_examples │ ├── catalog │ │ ├── assets.py │ │ ├── indexes.py │ │ ├── markets.py │ │ ├── metrics.py │ │ ├── exchanges.py │ │ ├── pairs.py │ │ ├── asset-alerts.py │ │ ├── asset-chains.py │ │ ├── institutions.py │ │ ├── pair-metrics.py │ │ ├── asset-metrics.py │ │ ├── exchange-assets.py │ │ ├── index-candles.py │ │ ├── market-candles.py │ │ ├── market-greeks.py │ │ ├── market-metrics.py │ │ ├── market-quotes.py │ │ ├── market-trades.py │ │ ├── pair-candles.py │ │ ├── exchange-metrics.py │ │ ├── market-orderbooks.py │ │ ├── mempool-feerates.py │ │ ├── institution-metrics.py │ │ ├── market-funding-rates.py │ │ ├── market-liquidations.py │ │ ├── market-openinterest.py │ │ ├── exchange-asset-metrics.py │ │ ├── market-contract-prices.py │ │ ├── transaction-tracker.py │ │ ├── market-implied-volatility.py │ │ └── mining-pool-tips-summary.py │ ├── profile │ │ └── assets.py │ ├── taxonomy │ │ └── assets.py │ ├── catalog-all │ │ ├── assets.py │ │ ├── indexes.py │ │ ├── markets.py │ │ ├── metrics.py │ │ ├── pairs.py │ │ ├── exchanges.py │ │ ├── asset-alerts.py │ │ ├── asset-chains.py │ │ ├── asset-metrics.py │ │ ├── index-candles.py │ │ ├── institutions.py │ │ ├── market-greeks.py │ │ ├── market-quotes.py │ │ ├── market-trades.py │ │ ├── pair-metrics.py │ │ ├── exchange-assets.py │ │ ├── market-candles.py │ │ ├── market-metrics.py │ │ ├── pair-candles.py │ │ ├── exchange-metrics.py │ │ ├── market-orderbooks.py │ │ ├── mempool-feerates.py │ │ ├── institution-metrics.py │ │ ├── market-funding-rates.py │ │ ├── market-liquidations.py │ │ ├── market-openinterest.py │ │ ├── exchange-asset-metrics.py │ │ ├── market-contract-prices.py │ │ ├── transaction-tracker.py │ │ ├── market-implied-volatility.py │ │ └── mining-pool-tips-summary.py │ ├── reference-data │ │ ├── pairs.py │ │ ├── assets.py │ │ ├── indexes.py │ │ ├── markets.py │ │ ├── exchanges.py │ │ ├── asset-metrics.py │ │ ├── pair-metrics.py │ │ ├── market-metrics.py │ │ ├── exchange-metrics.py │ │ ├── institution-metrics.py │ │ └── exchange-asset-metrics.py │ ├── catalog-v2 │ │ ├── asset-chains.py │ │ ├── index-levels.py │ │ ├── pair-candles.py │ │ ├── pair-metrics.py │ │ ├── asset-metrics.py │ │ ├── index-candles.py │ │ ├── market-candles.py │ │ ├── market-greeks.py │ │ ├── market-metrics.py │ │ ├── market-quotes.py │ │ ├── market-trades.py │ │ ├── exchange-metrics.py │ │ ├── market-orderbooks.py │ │ ├── mempool-feerates.py │ │ ├── institution-metrics.py │ │ ├── market-liquidations.py │ │ ├── market-openinterest.py │ │ ├── exchange-asset-metrics.py │ │ ├── market-contract-prices.py │ │ ├── market-funding-rates.py │ │ ├── transaction-tracker.py │ │ ├── market-implied-volatility.py │ │ ├── mining-pool-tips-summary.py │ │ └── market-funding-rates-predicted.py │ ├── security-master │ │ ├── assets.py │ │ └── markets.py │ ├── blockchain-metadata │ │ ├── tags.py │ │ └── tagged-entities.py │ ├── blockchain │ │ └── {asset} │ │ │ ├── blocks │ │ │ ├── {block_hash}.py │ │ │ └── {block_hash} │ │ │ │ └── transactions │ │ │ │ └── {txid}.py │ │ │ ├── transactions │ │ │ └── {txid}.py │ │ │ ├── blocks.py │ │ │ ├── accounts.py │ │ │ ├── transactions.py │ │ │ ├── balance-updates.py │ │ │ └── transaction-tracker.py │ ├── catalog-all-v2 │ │ ├── asset-chains.py │ │ ├── index-levels.py │ │ ├── pair-candles.py │ │ ├── pair-metrics.py │ │ ├── asset-metrics.py │ │ ├── index-candles.py │ │ ├── market-candles.py │ │ ├── market-greeks.py │ │ ├── market-metrics.py │ │ ├── market-quotes.py │ │ ├── market-trades.py │ │ ├── exchange-metrics.py │ │ ├── market-orderbooks.py │ │ ├── mempool-feerates.py │ │ ├── institution-metrics.py │ │ ├── market-funding-rates.py │ │ ├── market-liquidations.py │ │ ├── market-openinterest.py │ │ ├── exchange-asset-metrics.py │ │ ├── market-contract-prices.py │ │ ├── transaction-tracker.py │ │ ├── market-implied-volatility.py │ │ ├── mining-pool-tips-summary.py │ │ └── market-funding-rates-predicted.py │ ├── taxonomy-metadata │ │ └── assets.py │ ├── timeseries-stream │ │ ├── market-trades.py │ │ ├── market-liquidations.py │ │ ├── market-openinterest.py │ │ ├── pair-quotes.py │ │ ├── asset-metrics.py │ │ ├── asset-quotes.py │ │ ├── index-levels.py │ │ ├── market-candles.py │ │ ├── market-quotes.py │ │ └── market-orderbooks.py │ ├── blockchain-v2 │ │ └── {asset} │ │ │ ├── blocks │ │ │ ├── {block_hash}.py │ │ │ └── {block_hash} │ │ │ │ └── transactions │ │ │ │ └── {txid}.py │ │ │ ├── transactions │ │ │ └── {txid}.py │ │ │ ├── blocks.py │ │ │ ├── accounts.py │ │ │ ├── sub-accounts.py │ │ │ ├── transactions.py │ │ │ ├── balance-updates.py │ │ │ └── accounts │ │ │ └── {account} │ │ │ └── balance-updates.py │ ├── timeseries │ │ ├── asset-chains.py │ │ ├── index-levels.py │ │ ├── pair-candles.py │ │ ├── index-candles.py │ │ ├── market-candles.py │ │ ├── market-greeks.py │ │ ├── market-quotes.py │ │ ├── market-trades.py │ │ ├── market-orderbooks.py │ │ ├── mempool-feerates.py │ │ ├── index-constituents.py │ │ ├── market-liquidations.py │ │ ├── market-openinterest.py │ │ ├── market-contract-prices.py │ │ ├── market-funding-rates.py │ │ ├── asset-alerts.py │ │ ├── asset-metrics.py │ │ ├── defi-balance-sheets.py │ │ ├── mining-pool-tips-summary.py │ │ ├── pair-metrics.py │ │ ├── market-implied-volatility.py │ │ ├── market-metrics.py │ │ ├── exchange-metrics.py │ │ ├── market-funding-rates-predicted.py │ │ ├── institution-metrics.py │ │ └── exchange-asset-metrics.py │ ├── constituent-snapshots │ │ └── asset-metrics.py │ └── constituent-timeframes │ │ └── asset-metrics.py └── README.md ├── link_client_to_interpreter.bat ├── mypy.ini ├── get_utc_update_time.py ├── update_version.sh ├── Dockerfile ├── flake.nix ├── LICENSE ├── flake.lock ├── pyproject.toml ├── default.nix ├── Makefile ├── README.md ├── SCHEMA_BUILD.md ├── .gitignore └── .gitlab-ci.yml /test.txt: -------------------------------------------------------------------------------- 1 | test 2 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /coinmetrics/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /coinmetrics/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "2025.9.30.16" 2 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.txt 2 | recursive-include coinmetrics *.txt *.py 3 | -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.jp.min.js: -------------------------------------------------------------------------------- 1 | module.exports=require("./lunr.ja"); -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E501,E226,W504,E731,W503 3 | exclude = 4 | .git, 5 | __pycache__, 6 | -------------------------------------------------------------------------------- /docs/site/sitemap.xml.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/site/sitemap.xml.gz -------------------------------------------------------------------------------- /docs/docs/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/docs/assets/images/logo.png -------------------------------------------------------------------------------- /docs/site/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/site/assets/images/logo.png -------------------------------------------------------------------------------- /docs/docs/assets/images/api_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/docs/assets/images/api_flow.png -------------------------------------------------------------------------------- /docs/site/assets/images/api_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/site/assets/images/api_flow.png -------------------------------------------------------------------------------- /docs/site/assets/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/site/assets/images/favicon.png -------------------------------------------------------------------------------- /docs/docs/assets/images/API Flow.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/docs/assets/images/API Flow.pptx -------------------------------------------------------------------------------- /docs/site/assets/images/API Flow.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/site/assets/images/API Flow.pptx -------------------------------------------------------------------------------- /docs/docs/assets/images/cm-dark-combination.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/docs/assets/images/cm-dark-combination.png -------------------------------------------------------------------------------- /docs/site/assets/images/cm-dark-combination.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/site/assets/images/cm-dark-combination.png -------------------------------------------------------------------------------- /docs/docs/assets/images/cm-dark-combination@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/docs/assets/images/cm-dark-combination@2x.png -------------------------------------------------------------------------------- /docs/site/assets/images/cm-dark-combination@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coinmetrics/api-client-python/HEAD/docs/site/assets/images/cm-dark-combination@2x.png -------------------------------------------------------------------------------- /pydoc-markdown.yml: -------------------------------------------------------------------------------- 1 | loaders: 2 | - type: python 3 | processors: 4 | - type: filter 5 | - type: smart 6 | - type: crossref 7 | - python_file: docs/processors/pydoc_markdown_processors.py 8 | -------------------------------------------------------------------------------- /coinmetrics/constants.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class PagingFrom(Enum): 5 | START = "start" 6 | END = "end" 7 | 8 | 9 | class Backfill(Enum): 10 | LATEST = "latest" 11 | NONE = "none" 12 | -------------------------------------------------------------------------------- /test/data/catalog_market_orderbooks.csv: -------------------------------------------------------------------------------- 1 | market,min_time,max_time 2 | 0,binance-aave-btc-spot,2021-09-14 16:00:00+00:00,2022-07-12 20:00:00+00:00 3 | 1,binance-atom-usdc-spot,2021-09-14 16:00:00+00:00,2022-07-12 21:00:00+00:00 4 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/assets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_assets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/indexes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_indexes().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/markets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_markets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/exchanges.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_exchanges().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/pairs.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_asset_pairs().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/profile/assets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_asset_profiles().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/taxonomy/assets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_taxonomy_assets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/assets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_assets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/indexes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_indexes().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/markets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_markets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/pairs.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_asset_pairs().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/asset-alerts.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_asset_alerts().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/asset-chains.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_asset_chains().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/institutions.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_institutions().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/pair-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_pair_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/pairs.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_pairs().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/exchanges.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_exchanges().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/asset-chains.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_asset_chains_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/index-levels.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_index_levels_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/pair-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_pair_candles_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/pair-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_pair_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_asset_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/exchange-assets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_exchange_assets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/index-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_index_candles().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_candles().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-greeks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_greeks().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-quotes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_quotes().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-trades.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_trades().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/pair-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_asset_pair_candles().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/assets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_assets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/indexes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_indexes().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/markets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_markets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/security-master/assets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.security_master_assets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/security-master/markets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.security_master_markets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-metadata/tags.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.blockchain_metadata_tags().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/asset-alerts.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_asset_alerts().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/asset-chains.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_asset_chains().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_asset_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/index-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_index_candles().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/institutions.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_institutions().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-greeks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_greeks().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-quotes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_quotes().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-trades.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_trades().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/pair-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_pair_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_asset_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/index-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_index_candles_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_candles_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-greeks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_greeks_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-quotes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_quotes_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-trades.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_trades_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/exchange-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_exchange_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-orderbooks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_orderbooks().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/mempool-feerates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_mempool_feerates().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/exchanges.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_exchanges().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain/{asset}/blocks/{block_hash}.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_full_block().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/asset-chains.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_asset_chains_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/index-levels.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_index_levels_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/pair-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_pair_candles_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/pair-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_pair_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/exchange-assets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_exchange_assets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_candles().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/pair-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_asset_pair_candles().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/exchange-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_exchange_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-orderbooks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_orderbooks_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/mempool-feerates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_mempool_feerates_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/institution-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_institution_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-funding-rates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_funding_rates().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-liquidations.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_liquidations().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-openinterest.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_open_interest().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_asset_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/pair-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_pair_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/taxonomy-metadata/assets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_taxonomy_assets_metadata().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/market-trades.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_market_trades().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /test/data/catalog_institutions.csv: -------------------------------------------------------------------------------- 1 | institution,metric,frequency,min_time,max_time 2 | 0,grayscale,gbtc_total_assets,1d,2020-10-16 00:00:00+00:00,2021-01-05 00:00:00+00:00 3 | 1,grayscale,gbtc_shares_outstanding,1h,2020-10-15 03:00:00+00:00,2021-01-06 12:00:00+00:00 4 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-v2/{asset}/blocks/{block_hash}.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_full_block_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain/{asset}/transactions/{txid}.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_full_transaction().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_asset_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/index-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_index_candles_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_candles_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-greeks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_greeks_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-quotes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_quotes_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-trades.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_trades_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/exchange-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_exchange_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-orderbooks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_orderbooks().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/mempool-feerates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_mempool_feerates().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/institution-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_institution_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-liquidations.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_liquidations_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-openinterest.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_open_interest_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/exchange-asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_exchange_asset_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-contract-prices.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_contract_prices().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/transaction-tracker.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_transaction_tracker_assets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/market-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_market_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/asset-chains.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_asset_chains(assets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/index-levels.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_index_levels(indexes='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/pair-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_pair_candles(pairs='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-v2/{asset}/transactions/{txid}.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_full_transaction_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain/{asset}/blocks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_blocks(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/exchange-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_exchange_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-orderbooks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_orderbooks_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/mempool-feerates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_mempool_feerates_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/institution-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_institution_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-funding-rates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_funding_rates().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-liquidations.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_liquidations().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-openinterest.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_open_interest().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/exchange-asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_exchange_asset_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-contract-prices.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_contract_prices_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-funding-rates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_funding_rates_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/market-implied-volatility.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_implied_volatility().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog/mining-pool-tips-summary.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_mining_pool_tips_summaries().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/exchange-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_exchange_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/index-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_index_candles(indexes='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_candles(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-greeks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_greeks(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-quotes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_quotes(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-trades.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_trades(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-metadata/tagged-entities.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.blockchain_metadata_tagged_entities().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-v2/{asset}/blocks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_blocks_v2(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain/{asset}/accounts.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_accounts(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/institution-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_institution_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-funding-rates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_funding_rates_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-liquidations.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_liquidations_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-openinterest.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_open_interest_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/exchange-asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_exchange_asset_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-contract-prices.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_contract_prices().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/transaction-tracker.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_transaction_tracker_assets().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/transaction-tracker.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_transaction_tracker_assets_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/institution-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_institution_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/market-liquidations.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_market_liquidations().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/market-openinterest.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_market_open_interest().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/pair-quotes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_pair_quotes(pairs='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-orderbooks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_orderbooks(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/mempool-feerates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_mempool_feerates(assets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-v2/{asset}/accounts.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_accounts_v2(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain/{asset}/transactions.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_transactions(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/exchange-asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_exchange_asset_metrics_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-contract-prices.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_contract_prices_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/transaction-tracker.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_transaction_tracker_assets_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/market-implied-volatility.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_implied_volatility().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all/mining-pool-tips-summary.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_mining_pool_tips_summaries().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-implied-volatility.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_implied_volatility_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/mining-pool-tips-summary.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_mining_pool_tips_summaries_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/reference-data/exchange-asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.reference_data_exchange_asset_metrics().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_asset_metrics(assets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/asset-quotes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_asset_quotes(assets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/index-levels.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_index_levels(indexes='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/index-constituents.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_index_constituents(indexes='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-liquidations.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_liquidations(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-openinterest.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_open_interest(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-v2/{asset}/sub-accounts.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_sub_accounts_v2(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-v2/{asset}/transactions.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_transactions_v2(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain/{asset}/balance-updates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_balance_updates(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain/{asset}/transaction-tracker.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_transaction_tracker(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-implied-volatility.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_implied_volatility_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/mining-pool-tips-summary.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_mining_pool_tips_summaries_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/market-candles.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_market_candles(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/market-quotes.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_market_quotes(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-contract-prices.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_contract_prices(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-funding-rates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_funding_rates(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /link_client_to_interpreter.bat: -------------------------------------------------------------------------------- 1 | FOR /F "tokens=* USEBACKQ" %%F IN (`python -c "import site;print(site.getsitepackages()[1])"`) DO (SET package_target_path=%%F\coinmetrics) 2 | rmdir %package_target_path% 3 | rmdir /s /q %package_target_path% 4 | mklink /J %package_target_path% .\coinmetrics 5 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-v2/market-funding-rates-predicted.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_market_funding_rates_predicted_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries-stream/market-orderbooks.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_stream_market_orderbooks(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/asset-alerts.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_asset_alerts(assets='', alerts='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_asset_metrics(assets='', metrics='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/defi-balance-sheets.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_defi_balance_sheets(defi_protocols='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/mining-pool-tips-summary.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_mining_pool_tips_summary(assets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/pair-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_pair_metrics(pairs='', metrics='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-v2/{asset}/balance-updates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_balance_updates_v2(asset='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain/{asset}/blocks/{block_hash}/transactions/{txid}.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_full_transaction_for_block().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/catalog-all-v2/market-funding-rates-predicted.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.catalog_full_market_funding_rates_predicted_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-implied-volatility.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_implied_volatility(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_market_metrics(markets='', metrics='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /test/data/catalog_market_quotes.csv: -------------------------------------------------------------------------------- 1 | market,min_time,max_time 2 | 0,coinbase-btc-usd-spot,2019-03-25 18:46:25+00:00,2022-07-12 21:01:40+00:00 3 | 1,coinbase-btc-usdt-spot,2021-08-20 13:00:00+00:00,2022-07-12 21:00:00+00:00 4 | 2,coinbase-eth-usd-spot,2019-03-25 18:46:25+00:00,2022-07-12 21:01:40+00:00 5 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-v2/{asset}/blocks/{block_hash}/transactions/{txid}.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_full_transaction_for_block_v2().first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/exchange-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_exchange_metrics(exchanges='', metrics='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/market-funding-rates-predicted.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_predicted_market_funding_rates(markets='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/constituent-snapshots/asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_snapshots_of_asset_metric_constituents(metric='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/constituent-timeframes/asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_timeframes_of_asset_metric_constituents(metric='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/institution-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_institution_metrics(institutions='', metrics='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /examples/api_doc_examples/timeseries/exchange-asset-metrics.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_exchange_asset_metrics(exchange_assets='', metrics='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /test/data/catalog_market_trades.csv: -------------------------------------------------------------------------------- 1 | market,min_time,max_time 2 | 0,binance-aave-btc-spot,2020-10-15 03:00:01.286000+00:00,2022-07-12 21:00:39.933000+00:00 3 | 1,binance-algo-usdc-spot,2019-06-22 00:00:07.600000+00:00,2020-01-07 07:06:19.943000+00:00 4 | 2,binance-atom-usdc-spot,2019-05-07 12:05:42.347000+00:00,2022-07-12 21:01:25.281000+00:00 5 | -------------------------------------------------------------------------------- /examples/api_doc_examples/blockchain-v2/{asset}/accounts/{account}/balance-updates.py: -------------------------------------------------------------------------------- 1 | 2 | from coinmetrics.api_client import CoinMetricsClient 3 | 4 | api_key = "" 5 | client = CoinMetricsClient(api_key) 6 | 7 | data = client.get_list_of_balance_updates_for_account_v2(asset='', account='').first_page() 8 | print(data) 9 | -------------------------------------------------------------------------------- /mypy.ini: -------------------------------------------------------------------------------- 1 | [mypy] 2 | no_implicit_optional = True 3 | disallow_untyped_defs = True 4 | warn_unused_ignores = True 5 | warn_no_return = True 6 | strict_equality = True 7 | warn_return_any = True 8 | disallow_any_generics = True 9 | warn_redundant_casts = True 10 | ignore_missing_imports = True 11 | 12 | [mypy-coinmetrics._exceptions] 13 | ignore_errors = True 14 | -------------------------------------------------------------------------------- /get_utc_update_time.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import pytz 3 | 4 | def get_utc_update_string() -> str: 5 | utc_tz = pytz.UTC 6 | current_time_utc = datetime.datetime.now(tz=utc_tz) 7 | result_string = f"{current_time_utc.year}.{current_time_utc.month}.{current_time_utc.day}.{current_time_utc.hour}" 8 | return result_string 9 | 10 | if __name__ == '__main__': 11 | print(get_utc_update_string()) 12 | -------------------------------------------------------------------------------- /docs/processors/pydoc_markdown_processors.py: -------------------------------------------------------------------------------- 1 | from pydoc_markdown.interfaces import Processor 2 | 3 | 4 | class DeprecationProcessor(Processor): 5 | def process(self, graph): 6 | for module in graph.modules: 7 | for obj in module.members.values(): 8 | if obj.decorators and 'deprecated' in obj.decorators: 9 | obj.docstring = f"**Deprecated:** {obj.docstring or ''}" 10 | -------------------------------------------------------------------------------- /update_version.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | VERSION=$1 3 | 4 | sed -i.bak -e "s/__version__ = .*/__version__ = \"$VERSION\"/" coinmetrics/__init__.py 5 | sed -i.bak -e "s/version = .*/version = \"$VERSION\"/" pyproject.toml 6 | sed -i.bak -e "s/version = .*/version = \"$VERSION\";/" default.nix 7 | sed -i.bak -e "s/## __version__/## $VERSION/" CHANGELOG.md 8 | 9 | rm -f coinmetrics/__init__.py.bak pyproject.toml.bak default.nix.bak CHANGELOG.md.bak 10 | -------------------------------------------------------------------------------- /test/data/catalog_asset_pairs.csv: -------------------------------------------------------------------------------- 1 | pair,metric,frequency,min_time,max_time 2 | 0,aave-bnb,volume_trusted_spot_usd_1d,1d,2020-10-16 00:00:00+00:00,2021-01-05 00:00:00+00:00 3 | 1,aave-bnb,volume_trusted_spot_usd_1h,1h,2020-10-15 03:00:00+00:00,2021-01-06 12:00:00+00:00 4 | 2,aave-btc,volume_trusted_spot_usd_1d,1d,2020-10-11 00:00:00+00:00,2021-01-05 00:00:00+00:00 5 | 3,aave-btc,volume_trusted_spot_usd_1h,1h,2020-10-10 19:00:00+00:00,2021-01-06 12:00:00+00:00 6 | -------------------------------------------------------------------------------- /docs/docs/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --md-primary-fg-color: #495070; 3 | --md-primary-fg-color--light: #FFFFFF; 4 | --md-primary-fg-color--dark: #161823; 5 | --md-typeset-a-color: #757CA1; 6 | 7 | } 8 | /* a:hover { 9 | text-decoration: underline; 10 | } */ 11 | /* 12 | a { 13 | color: #1E2130; 14 | text-decoration: none; 15 | } */ 16 | 17 | a.custom { 18 | color: var(--primary-color); 19 | text-decoration: underline; 20 | } -------------------------------------------------------------------------------- /docs/site/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --md-primary-fg-color: #495070; 3 | --md-primary-fg-color--light: #FFFFFF; 4 | --md-primary-fg-color--dark: #161823; 5 | --md-typeset-a-color: #757CA1; 6 | 7 | } 8 | /* a:hover { 9 | text-decoration: underline; 10 | } */ 11 | /* 12 | a { 13 | color: #1E2130; 14 | text-decoration: none; 15 | } */ 16 | 17 | a.custom { 18 | color: var(--primary-color); 19 | text-decoration: underline; 20 | } -------------------------------------------------------------------------------- /test/data/catalog_exchange_assets.csv: -------------------------------------------------------------------------------- 1 | exchange_asset,metric,frequency,min_time,max_time 2 | 0,binance-btc,volume_trusted_spot_usd_1d,1d,2020-10-16 00:00:00+00:00,2021-01-05 00:00:00+00:00 3 | 1,binance-btc,volume_trusted_spot_usd_1h,1h,2020-10-15 03:00:00+00:00,2021-01-06 12:00:00+00:00 4 | 2,coinbase-eth,volume_trusted_spot_usd_1d,1d,2020-10-11 00:00:00+00:00,2021-01-05 00:00:00+00:00 5 | 3,coinbase-eth,volume_trusted_spot_usd_1h,1h,2020-10-10 19:00:00+00:00,2021-01-06 12:00:00+00:00 6 | -------------------------------------------------------------------------------- /test/data/catalog_indexes.csv: -------------------------------------------------------------------------------- 1 | index,description,frequency,min_time,max_time 2 | 0,CMBI10,'CMBI10' index.,15s,2020-06-08 20:12:40+00:00,2020-06-08 20:29:30+00:00 3 | 1,CMBIBTC,'CMBIBTC' index.,15s,2010-07-18 20:00:00+00:00,2020-06-08 20:29:45+00:00 4 | 2,CMBIBTC,'CMBIBTC' index.,1d,2010-07-19 00:00:00+00:00,2020-06-08 00:00:00+00:00 5 | 3,CMBIBTC,'CMBIBTC' index.,1d-ny-close,2010-07-18 20:00:00+00:00,2020-06-08 20:00:00+00:00 6 | 4,CMBIBTC,'CMBIBTC' index.,1d-sg-close,2010-07-19 08:00:00+00:00,2020-06-08 08:00:00+00:00 7 | 5,CMBIBTC,'CMBIBTC' index.,1h,2010-07-18 20:00:00+00:00,2020-06-08 20:00:00+00:00 8 | -------------------------------------------------------------------------------- /test/data/catalog_markets.csv: -------------------------------------------------------------------------------- 1 | market,min_time,max_time,exchange,type,symbol,base,quote,size_asset,margin_asset,contract_size,tick_size,listing,expiration,min_time_trades,max_time_trades 2 | 0,bitmex-XBTF15-future,2014-11-24 13:05:32.850000+00:00,2015-01-30 12:00:00+00:00,bitmex,future,XBTF15,btc,usd,XBT,USD,1,0.1,'2014-11-24 13:05:32.850000+00:00','2015-01-30 12:00:00+00:00','2014-11-24 13:05:32.850000+00:00', '2015-01-30 12:00:00+00:00' 3 | 1,bitfinex-agi-btc-spot,2018-04-07 16:25:55+00:00,2020-03-25 20:12:09.639000+00:00,bitfinex,spot,,agi,btc,,,,,,,2018-04-07T16:25:55.000000000Z,2020-03-25T20:12:09.639000000Z 4 | -------------------------------------------------------------------------------- /test/data/catalog_assets_metrics.csv: -------------------------------------------------------------------------------- 1 | asset,full_name,exchanges,markets,metric,frequency,min_time,max_time,min_height,max_height,min_hash,max_hash 2 | btc,Bitcoin,"['binance', 'coinbase', 'kraken']","['binance-btc-usdt-spot', 'binance-eth-btc-spot', 'coinbase-btc-usd-spot', 'coinbase-eth-btc-spot', 'kraken-btc-usd-spot']",TestMetric,1b,2009-01-03 18:15:05+00:00,2020-06-08 20:22:17+00:00,0,10,0abc,0xyz 3 | btc,Bitcoin,"['binance', 'coinbase', 'kraken']","['binance-btc-usdt-spot', 'binance-eth-btc-spot', 'coinbase-btc-usd-spot', 'coinbase-eth-btc-spot', 'kraken-btc-usd-spot']",TestMetric,1d,2009-01-03 00:00:00+00:00,2020-06-07 00:00:00+00:00,,,, -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. Coin Metrics Python API Client documentation master file, created by 2 | sphinx-quickstart on Fri Dec 27 17:31:33 2024. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Coin Metrics Python API Client documentation 7 | ============================================ 8 | 9 | Add your content using ``reStructuredText`` syntax. See the 10 | `reStructuredText `_ 11 | documentation for details. 12 | 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | :caption: Contents: 17 | 18 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11-bookworm 2 | 3 | ARG CM_API_KEY="" 4 | ENV CM_API_KEY=$CM_API_KEY 5 | 6 | RUN apt-get update && \ 7 | DEBIAN_FRONTEND=noninteractive apt-get install -qy \ 8 | cargo \ 9 | make \ 10 | postgresql-server-dev-all \ 11 | python3-dev \ 12 | python3-protobuf \ 13 | build-essential \ 14 | ; 15 | 16 | RUN pip install --upgrade pip 17 | 18 | RUN pip install poetry 19 | COPY pyproject.toml ./poetry.lock ./ 20 | RUN poetry config virtualenvs.create false 21 | 22 | RUN poetry install --no-root --with dev 23 | 24 | COPY ./ ./ 25 | 26 | # Generate minimal schema constants at build time 27 | RUN python coinmetrics/build.py 28 | 29 | CMD [ "python" ] 30 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /coinmetrics/_typing.py: -------------------------------------------------------------------------------- 1 | from datetime import date, datetime 2 | from pathlib import Path 3 | from typing import Any, Callable, Dict, IO, List, Tuple, Union, Optional 4 | from coinmetrics.constants import PagingFrom 5 | from websocket import WebSocket 6 | import pandas as pd 7 | import polars as pl 8 | 9 | 10 | DataFrameType = Union[pd.DataFrame, pl.DataFrame] 11 | FilePathOrBuffer = Union[str, Path, IO[str], IO[bytes], None] 12 | DataReturnType = Dict[str, Union[str, Dict[str, str], List[Dict[str, Any]]]] 13 | DataRetrievalFuncType = Callable[[str, Dict[str, Any]], DataReturnType] 14 | UrlParamTypes = Union[ 15 | str, List[str], Tuple[str], PagingFrom, int, datetime, date, bool, None 16 | ] 17 | MessageHandlerType = Optional[Callable[[WebSocket, Any], None]] 18 | -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.vi.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.vi=function(){this.pipeline.reset(),this.pipeline.add(e.vi.stopWordFilter,e.vi.trimmer)},e.vi.wordCharacters="[A-Za-ẓ̀͐́͑̉̃̓ÂâÊêÔôĂ-ăĐ-đƠ-ơƯ-ư]",e.vi.trimmer=e.trimmerSupport.generateTrimmer(e.vi.wordCharacters),e.Pipeline.registerFunction(e.vi.trimmer,"trimmer-vi"),e.vi.stopWordFilter=e.generateStopWordFilter("là cái nhưng mà".split(" "))}}); -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "Python client for Coin Metrics API v4"; 3 | 4 | inputs = { 5 | flake-utils.url = "github:numtide/flake-utils"; 6 | 7 | nixpkgs = { 8 | url = "github:NixOS/nixpkgs"; 9 | }; 10 | }; 11 | 12 | outputs = { self, flake-utils, nixpkgs }: 13 | flake-utils.lib.eachDefaultSystem (system: 14 | let 15 | pkgs = import nixpkgs { 16 | inherit system; 17 | }; 18 | 19 | lib = import ./.; 20 | in { 21 | packages = { 22 | coinmetrics-api-client-py310 = pkgs.python310Packages.callPackage lib {}; 23 | coinmetrics-api-client-py311 = pkgs.python311Packages.callPackage lib {}; 24 | coinmetrics-api-client-py312 = pkgs.python312Packages.callPackage lib {}; 25 | }; 26 | } 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.multi.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){e.multiLanguage=function(){for(var t=Array.prototype.slice.call(arguments),i=t.join("-"),r="",n=[],s=[],p=0;pNUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/docs/user-guide/wildcards.md: -------------------------------------------------------------------------------- 1 | # Wildcards 2 | 3 | All endpoints for time series support a single wildcard for the first parameter that accepts a list. For example, let's 4 | say you want market candles for BTC trading against any quote currency. The first list parameter is `markets`. 5 | 6 | You have two choices: 7 | 8 | * You use `catalog_market_candles_v2()` to obtain a list of available candles, filter it according to your needs, and pass 9 | an explicit list to the `get_market_candles()` function. 10 | * You use a single wildcard, like so: `get_market_candles(markets='binance-btc-*-spot')`. In the backend, 11 | your wildcarded string is mapped against all possible market strings and all matches are used as argument. 12 | 13 | ## Performance 14 | 15 | If you have a choice of passing a specific list of 100 markets or a wildcard that resolves to 100 markets, we recommend the former. The API client will parallelize the requests across the list of markets resulting in a performance boost. 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.th.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.th=function(){this.pipeline.reset(),this.pipeline.add(e.th.trimmer),r?this.tokenizer=e.th.tokenizer:(e.tokenizer&&(e.tokenizer=e.th.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.th.tokenizer))},e.th.wordCharacters="[฀-๿]",e.th.trimmer=e.trimmerSupport.generateTrimmer(e.th.wordCharacters),e.Pipeline.registerFunction(e.th.trimmer,"trimmer-th");var t=e.wordcut;t.init(),e.th.tokenizer=function(i){if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t):t});var n=i.toString().replace(/^\s+/,"");return t.cut(n).split("|")}}}); -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # For the full list of built-in configuration values, see the documentation: 4 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 5 | 6 | # -- Project information ----------------------------------------------------- 7 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information 8 | 9 | project = 'Coin Metrics Python API Client' 10 | copyright = '2025 Coin Metrics Inc. All rights reserved.' 11 | author = 'Coin Metrics' 12 | 13 | # -- General configuration --------------------------------------------------- 14 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration 15 | 16 | extensions = [] 17 | 18 | templates_path = ['_templates'] 19 | exclude_patterns = [] 20 | 21 | language = 'En' 22 | 23 | # -- Options for HTML output ------------------------------------------------- 24 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output 25 | 26 | html_theme = 'alabaster' 27 | html_static_path = ['_static'] 28 | -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.hy.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.hy=function(){this.pipeline.reset(),this.pipeline.add(e.hy.trimmer,e.hy.stopWordFilter)},e.hy.wordCharacters="[A-Za-z԰-֏ff-ﭏ]",e.hy.trimmer=e.trimmerSupport.generateTrimmer(e.hy.wordCharacters),e.Pipeline.registerFunction(e.hy.trimmer,"trimmer-hy"),e.hy.stopWordFilter=e.generateStopWordFilter("դու և եք էիր էիք հետո նաև նրանք որը վրա է որ պիտի են այս մեջ ն իր ու ի այդ որոնք այն կամ էր մի ես համար այլ իսկ էին ենք հետ ին թ էինք մենք նրա նա դուք եմ էի ըստ որպես ում".split(" ")),e.Pipeline.registerFunction(e.hy.stopWordFilter,"stopWordFilter-hy"),e.hy.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}(),e.Pipeline.registerFunction(e.hy.stemmer,"stemmer-hy")}}); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Oleksandr Buchkovskyi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/test_security_master_methods.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | 4 | from coinmetrics.api_client import CoinMetricsClient 5 | 6 | client = CoinMetricsClient(str(os.environ.get("CM_API_KEY"))) 7 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 8 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 9 | 10 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 11 | "CM_API_KEY not set, tests will not run" 12 | ) 13 | 14 | 15 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 16 | def test_security_master_markets() -> None: 17 | required_market_cols = [ 18 | "market", 19 | "exchange", 20 | "type" 21 | ] 22 | security_master_market = client.security_master_markets().first_page()[0] 23 | assert all([col in security_master_market for col in required_market_cols]) 24 | 25 | 26 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 27 | def test_security_master_assets() -> None: 28 | security_master_asset = client.security_master_assets(assets="btc").first_page()[0] 29 | assert 'asset' in security_master_asset 30 | assert security_master_asset.get("type") == "utxo" 31 | -------------------------------------------------------------------------------- /test/test_debugging.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from coinmetrics.api_client import CoinMetricsClient 4 | import os 5 | from datetime import datetime 6 | 7 | client = CoinMetricsClient(str(os.environ.get("CM_API_KEY")), debug_mode=True) 8 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 9 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 10 | 11 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 12 | "CM_API_KEY not set, tests will not run" 13 | ) 14 | 15 | 16 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 17 | def test_debugging_get_rrs() -> None: 18 | """ 19 | Checks that log file is created as expected 20 | """ 21 | eth_reference_rates = client.get_asset_metrics( 22 | metrics="ReferenceRateUSD", 23 | assets="eth", 24 | start_time=datetime.now().date(), 25 | frequency="1d", 26 | ) 27 | for data in eth_reference_rates: 28 | print(data) 29 | assert any( 30 | list( 31 | map( 32 | lambda file_name: file_name.startswith("cm_api_client_debug_"), 33 | os.listdir(os.getcwd()), 34 | ) 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /test/test_constituent_methods.py: -------------------------------------------------------------------------------- 1 | 2 | import pytest 3 | 4 | from coinmetrics.api_client import CoinMetricsClient 5 | import os 6 | 7 | client = CoinMetricsClient(str(os.environ.get("CM_API_KEY")), verbose=True) 8 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 9 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 10 | 11 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 12 | "CM_API_KEY not set, tests will not run" 13 | ) 14 | 15 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 16 | def test_constituent_snapshots() -> None: 17 | data = client.get_snapshots_of_asset_metric_constituents(metric="volume_trusted_spot_usd_1d").to_list() 18 | assert all(["time" in item for item in data]) 19 | assert all(["exchange" in item for item in data]) 20 | 21 | 22 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 23 | def test_constituent_timeframes() -> None: 24 | data = client.get_timeframes_of_asset_metric_constituents(metric="volume_trusted_spot_usd_1d").to_list() 25 | assert all(["exchange" in item for item in data]) 26 | assert all(["start_time" in item for item in data]) 27 | assert all(["end_time" in item for item in data]) 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/test_rate_limits.py: -------------------------------------------------------------------------------- 1 | import os 2 | import threading 3 | import pytest 4 | 5 | from coinmetrics.api_client import CoinMetricsClient 6 | 7 | client = CoinMetricsClient() 8 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 9 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 10 | 11 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 12 | "CM_API_KEY not set, tests will not run" 13 | ) 14 | 15 | 16 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 17 | def test_rate_limiter_works_as_expected() -> None: 18 | """ 19 | This function tests if a community user can run a 20 second query against our API without tripping the 429 error 20 | """ 21 | def target() -> None: 22 | try: 23 | client.get_asset_metrics(assets="btc,algo,eth,usdc", metrics="ReferenceRateUSD", frequency="1m").to_list() 24 | except Exception as e: 25 | pytest.fail(f"Function failed with exception: {e}") 26 | 27 | test_thread = threading.Thread(target=target) 28 | test_thread.daemon = True 29 | test_thread.start() 30 | 31 | test_thread.join(20) 32 | 33 | if not test_thread.is_alive(): 34 | pytest.fail("Function failed to run for 20 seconds without throwing an exception") 35 | 36 | 37 | if __name__ == '__main__': 38 | pytest.main() -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | Check out the [Tutorials and Examples](https://docs.coinmetrics.io/tutorials-and-examples) section of the Coin Metrics Product Documentation for the most up-to-date examples. 4 | 5 | We recommend beginners to start with the [Python API Client Tutorial](https://docs.coinmetrics.io/tutorials-and-examples/tutorials/walkthrough_community). Then, explore other [tutorials](https://docs.coinmetrics.io/tutorials-and-examples/tutorials) based on the data of interest. 6 | 7 | We also offer how-to guides to help achieve specific outcomes using the Python Client: 8 | 9 | * [How to Export Data](https://docs.coinmetrics.io/tutorials-and-examples/user-guides/exporting-data#python-api-client) has examples for how to export data with and without using parallelization. 10 | * [How To Migrate From Catalog to Catalog V2 and Reference Data](https://docs.coinmetrics.io/tutorials-and-examples/user-guides/how-to-migrate-from-catalog-v1-to-catalog-v2) translates code using the deprecated catalog endpoints to catalog-v2 and reference-data. 11 | * [How to Use the Coin Metrics API (Python Client) Efficiently](https://docs.coinmetrics.io/tutorials-and-examples/user-guides/how-to-use-the-coin-metrics-api-efficiently-http#python-api-client) has tips for making your queries faster. 12 | * [How to Use Websockets](https://docs.coinmetrics.io/tutorials-and-examples/user-guides/how-to-use-websockets) has templates for using the timeseries_stream endpoints. 13 | -------------------------------------------------------------------------------- /test/test_blockchain_methods.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | import pytest 4 | 5 | from coinmetrics.api_client import CoinMetricsClient 6 | import os 7 | 8 | client = CoinMetricsClient(str(os.environ.get("CM_API_KEY")), verbose=True) 9 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 10 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 11 | 12 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 13 | "CM_API_KEY not set, tests will not run" 14 | ) 15 | 16 | 17 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 18 | def test_get_blockchain_list_of_account_balance_updates() -> None: 19 | asset = "btc" 20 | account = "112jmDkNGHSbhhY17JGpxU3sMA9ZExG7b2" 21 | updates = client.get_list_of_balance_updates_for_account_v2(asset=asset, account=account).to_list() 22 | assert updates[0]['block_hash'] == "0000000000000000002c7505ef2272e0677fa53d68d633f8e076ed42dd3380e6" 23 | 24 | 25 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 26 | def test_get_blockchain_metadata() -> None: 27 | owner = next(client.get_blockchain_metadata_owners())['owner_name'] 28 | location = next(client.get_blockchain_metadata_locations())['location'] 29 | tag = next(client.get_blockchain_metadata_tags())['tag'] 30 | tagged_entities = next(client.get_blockchain_metadata_tagged_entities(tags=[tag]))['entity'] 31 | 32 | 33 | if __name__ == "__main__": 34 | pytest.main() 35 | -------------------------------------------------------------------------------- /coinmetrics/_models.py: -------------------------------------------------------------------------------- 1 | from typing import Optional, List, Dict 2 | from dataclasses import dataclass, field 3 | 4 | 5 | @dataclass 6 | class CoinMetricsAPIModel: 7 | 8 | @classmethod 9 | def get_dataframe_cols(cls) -> List[str]: 10 | return list(cls.__annotations__.keys()) 11 | 12 | 13 | @dataclass 14 | class AssetChainsData(CoinMetricsAPIModel): 15 | """ 16 | Class to represent data returned from asset chains data type 17 | """ 18 | asset: str 19 | time: str 20 | chains_count: str 21 | blocks_count_at_tip: str 22 | reorg: Optional[str] = field(default="false") 23 | reorg_depth: str = field(default="0") 24 | chains: List[List[Dict[str, str]]] = field(default_factory=list) 25 | 26 | 27 | @dataclass 28 | class TransactionTrackerData(CoinMetricsAPIModel): 29 | """ 30 | Class to represent data returned from tranasaction-tracker endpoint 31 | """ 32 | txid: str 33 | time: str 34 | first_seen_time: str 35 | status: str 36 | status_update_time: str 37 | status_updates: List[str] 38 | details: str 39 | height: str = field(default="0") 40 | mempool_approx_queue_position: str = field(default="None") 41 | next_block_approx_settlement_probability_pct: str = field(default="0") 42 | block_hash: str = field(default="None") 43 | geo: str = field(default="None") 44 | replacement_for_txid: str = field(default="None") 45 | inputs: List[str] = field(default_factory=list) 46 | outputs: List[str] = field(default_factory=list) 47 | -------------------------------------------------------------------------------- /docs/docs/user-guide/examples.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | Check out the [Tutorials and Examples](https://docs.coinmetrics.io/tutorials-and-examples) section of the Coin Metrics Product Documentation for the most up-to-date examples. 4 | 5 | We recommend beginners to start with the [Python API Client Tutorial](https://docs.coinmetrics.io/tutorials-and-examples/tutorials/walkthrough_community). Then, explore other [tutorials](https://docs.coinmetrics.io/tutorials-and-examples/tutorials) based on the data of interest. 6 | 7 | We also offer how-to guides to help achieve specific outcomes using the Python Client: 8 | 9 | * [How to Export Data](https://docs.coinmetrics.io/tutorials-and-examples/user-guides/exporting-data#python-api-client) has examples for how to export data with and without using parallelization. 10 | * [How To Migrate From Catalog to Catalog V2 and Reference Data](https://docs.coinmetrics.io/tutorials-and-examples/user-guides/how-to-migrate-from-catalog-v1-to-catalog-v2) translates code using the deprecated catalog endpoints to catalog-v2 and reference-data. 11 | * [How to Use the Coin Metrics API (Python Client) Efficiently](https://docs.coinmetrics.io/tutorials-and-examples/user-guides/how-to-use-the-coin-metrics-api-efficiently-http#python-api-client) has tips for making your queries faster. 12 | * [How to Use Websockets](https://docs.coinmetrics.io/tutorials-and-examples/user-guides/how-to-use-websockets) has templates for using the timeseries_stream endpoints. 13 | 14 | ## Archive 15 | 16 | Legacy examples live on the archives folder. The scripts found there are no longer maintained and used at your own risk. They are preserved for backwards compatibility. -------------------------------------------------------------------------------- /docs/site/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://coinmetrics.github.io/api-client-python/site/index.html 5 | 2025-09-30 6 | 7 | 8 | https://coinmetrics.github.io/api-client-python/site/reference/api_client.html 9 | 2025-09-30 10 | 11 | 12 | https://coinmetrics.github.io/api-client-python/site/releases/CHANGELOG.html 13 | 2025-09-30 14 | 15 | 16 | https://coinmetrics.github.io/api-client-python/site/tools/FlatFilesExport.html 17 | 2025-09-30 18 | 19 | 20 | https://coinmetrics.github.io/api-client-python/site/user-guide/best-practices.html 21 | 2025-09-30 22 | 23 | 24 | https://coinmetrics.github.io/api-client-python/site/user-guide/examples.html 25 | 2025-09-30 26 | 27 | 28 | https://coinmetrics.github.io/api-client-python/site/user-guide/introduction.html 29 | 2025-09-30 30 | 31 | 32 | https://coinmetrics.github.io/api-client-python/site/user-guide/troubleshooting.html 33 | 2025-09-30 34 | 35 | 36 | https://coinmetrics.github.io/api-client-python/site/user-guide/wildcards.html 37 | 2025-09-30 38 | 39 | -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.te.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.te=function(){this.pipeline.reset(),this.pipeline.add(e.te.trimmer,e.te.stopWordFilter,e.te.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.te.stemmer))},e.te.wordCharacters="ఀ-ఄఅ-ఔక-హా-ౌౕ-ౖౘ-ౚౠ-ౡౢ-ౣ౦-౯౸-౿఼ఽ్ౝ౷౤౥",e.te.trimmer=e.trimmerSupport.generateTrimmer(e.te.wordCharacters),e.Pipeline.registerFunction(e.te.trimmer,"trimmer-te"),e.te.stopWordFilter=e.generateStopWordFilter("అందరూ అందుబాటులో అడగండి అడగడం అడ్డంగా అనుగుణంగా అనుమతించు అనుమతిస్తుంది అయితే ఇప్పటికే ఉన్నారు ఎక్కడైనా ఎప్పుడు ఎవరైనా ఎవరో ఏ ఏదైనా ఏమైనప్పటికి ఒక ఒకరు కనిపిస్తాయి కాదు కూడా గా గురించి చుట్టూ చేయగలిగింది తగిన తర్వాత దాదాపు దూరంగా నిజంగా పై ప్రకారం ప్రక్కన మధ్య మరియు మరొక మళ్ళీ మాత్రమే మెచ్చుకో వద్ద వెంట వేరుగా వ్యతిరేకంగా సంబంధం".split(" ")),e.te.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.te.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.te.stemmer,"stemmer-te"),e.Pipeline.registerFunction(e.te.stopWordFilter,"stopWordFilter-te")}}); -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1742395967, 24 | "narHash": "sha256-j7kkUoDKMU/Ane3h6IEue9TQdnRiXubpdA5YJJdqQus=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "7c76d3b20bce2e75a95e3e8d403a0779d9a3f053", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "repo": "nixpkgs", 33 | "type": "github" 34 | } 35 | }, 36 | "root": { 37 | "inputs": { 38 | "flake-utils": "flake-utils", 39 | "nixpkgs": "nixpkgs" 40 | } 41 | }, 42 | "systems": { 43 | "locked": { 44 | "lastModified": 1681028828, 45 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 46 | "owner": "nix-systems", 47 | "repo": "default", 48 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 49 | "type": "github" 50 | }, 51 | "original": { 52 | "owner": "nix-systems", 53 | "repo": "default", 54 | "type": "github" 55 | } 56 | } 57 | }, 58 | "root": "root", 59 | "version": 7 60 | } 61 | -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.ta.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ta=function(){this.pipeline.reset(),this.pipeline.add(e.ta.trimmer,e.ta.stopWordFilter,e.ta.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ta.stemmer))},e.ta.wordCharacters="஀-உஊ-ஏஐ-ஙச-ட஠-னப-யர-ஹ஺-ிீ-௉ொ-௏ௐ-௙௚-௟௠-௩௪-௯௰-௹௺-௿a-zA-Za-zA-Z0-90-9",e.ta.trimmer=e.trimmerSupport.generateTrimmer(e.ta.wordCharacters),e.Pipeline.registerFunction(e.ta.trimmer,"trimmer-ta"),e.ta.stopWordFilter=e.generateStopWordFilter("அங்கு அங்கே அது அதை அந்த அவர் அவர்கள் அவள் அவன் அவை ஆக ஆகவே ஆகையால் ஆதலால் ஆதலினால் ஆனாலும் ஆனால் இங்கு இங்கே இது இதை இந்த இப்படி இவர் இவர்கள் இவள் இவன் இவை இவ்வளவு உனக்கு உனது உன் உன்னால் எங்கு எங்கே எது எதை எந்த எப்படி எவர் எவர்கள் எவள் எவன் எவை எவ்வளவு எனக்கு எனது எனவே என் என்ன என்னால் ஏது ஏன் தனது தன்னால் தானே தான் நாங்கள் நாம் நான் நீ நீங்கள்".split(" ")),e.ta.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var t=e.wordcut;t.init(),e.ta.tokenizer=function(r){if(!arguments.length||null==r||void 0==r)return[];if(Array.isArray(r))return r.map(function(t){return isLunr2?new e.Token(t.toLowerCase()):t.toLowerCase()});var i=r.toString().toLowerCase().replace(/^\s+/,"");return t.cut(i).split("|")},e.Pipeline.registerFunction(e.ta.stemmer,"stemmer-ta"),e.Pipeline.registerFunction(e.ta.stopWordFilter,"stopWordFilter-ta")}}); -------------------------------------------------------------------------------- /test/data/catalog_asset_pair_candles.csv: -------------------------------------------------------------------------------- 1 | pair,frequency,min_time,max_time 2 | 0,1inch-usd,1m,2020-12-26 01:00:00+00:00,2022-07-12 17:50:00+00:00 3 | 1,1inch-usd,5m,2020-12-26 01:00:00+00:00,2022-07-12 17:45:00+00:00 4 | 2,1inch-usd,10m,2020-12-26 01:00:00+00:00,2022-07-12 17:40:00+00:00 5 | 3,1inch-usd,15m,2020-12-26 01:00:00+00:00,2022-07-12 17:30:00+00:00 6 | 4,1inch-usd,30m,2020-12-26 01:00:00+00:00,2022-07-12 17:00:00+00:00 7 | 5,1inch-usd,1h,2020-12-26 01:00:00+00:00,2022-07-12 16:00:00+00:00 8 | 6,1inch-usd,4h,2020-12-26 00:00:00+00:00,2022-07-12 12:00:00+00:00 9 | 7,1inch-usd,1d,2020-12-26 00:00:00+00:00,2022-07-11 00:00:00+00:00 10 | 8,aave-usd,1m,2020-10-10 08:13:00+00:00,2022-07-12 17:50:00+00:00 11 | 9,aave-usd,5m,2020-10-10 08:10:00+00:00,2022-07-12 17:45:00+00:00 12 | 10,aave-usd,10m,2020-10-10 08:10:00+00:00,2022-07-12 17:40:00+00:00 13 | 11,aave-usd,15m,2020-10-10 08:00:00+00:00,2022-07-12 17:30:00+00:00 14 | 12,aave-usd,30m,2020-10-10 08:00:00+00:00,2022-07-12 17:00:00+00:00 15 | 13,aave-usd,1h,2020-10-10 08:00:00+00:00,2022-07-12 16:00:00+00:00 16 | 14,aave-usd,4h,2020-10-10 08:00:00+00:00,2022-07-12 12:00:00+00:00 17 | 15,aave-usd,1d,2020-10-10 00:00:00+00:00,2022-07-11 00:00:00+00:00 18 | 16,abt-usd,1m,2018-02-26 00:00:00+00:00,2022-07-12 17:50:00+00:00 19 | 17,abt-usd,5m,2018-02-26 00:00:00+00:00,2022-07-12 17:45:00+00:00 20 | 18,abt-usd,10m,2018-02-26 00:00:00+00:00,2022-07-12 17:40:00+00:00 21 | 19,abt-usd,15m,2018-02-26 00:00:00+00:00,2022-07-12 17:30:00+00:00 22 | 20,abt-usd,30m,2018-02-26 00:00:00+00:00,2022-07-12 17:00:00+00:00 23 | 21,abt-usd,1h,2018-02-26 00:00:00+00:00,2022-07-12 16:00:00+00:00 24 | 22,abt-usd,4h,2018-02-26 00:00:00+00:00,2022-07-12 12:00:00+00:00 25 | 23,abt-usd,1d,2018-02-26 00:00:00+00:00,2022-07-11 00:00:00+00:00 26 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "coinmetrics-api-client" 3 | version = "2025.9.30.16" 4 | description = "Python client for Coin Metrics API v4." 5 | authors = ["Coin Metrics ", "Oleksandr Buchkovskyi "] 6 | license = "MIT" 7 | readme = "README.md" 8 | homepage = "https://coinmetrics.github.io/api-client-python/site/index.html" 9 | repository = "https://github.com/coinmetrics/api-client-python" 10 | packages = [{include = "coinmetrics"}] 11 | include = ["test", "openapi.yaml"] 12 | keywords = ["coin metrics", "coin", "metrics", "crypto", "bitcoin", "network-data", "market-data", "api", "handy"] 13 | documentation = "https://coinmetrics.github.io/api-client-python/site/index.html" 14 | 15 | [tool.poetry.dependencies] 16 | python = "^3.9.0" 17 | requests = "^2.24.0" 18 | orjson = "^3.6.0" 19 | numpy = "^2.0.0" 20 | pandas = "^2.0.0" 21 | polars = "^1.0.0" 22 | websocket-client = "^1.6.0" 23 | python-dateutil = "^2.8.2" 24 | typer = ">=0.7.0" 25 | tqdm = "^4.64.1" 26 | PyYAML = "^6.0" 27 | 28 | [tool.poetry.group.dev] 29 | optional = true 30 | 31 | [tool.poetry.group.dev.dependencies] 32 | mypy = "^1.13.0" 33 | flake8 = "^3.8.3" 34 | black = "^23.1" 35 | mkdocs = "^1.3.1" 36 | mkdocs-material = "^9.1.3" 37 | pydoc-markdown = "^4.8" 38 | 39 | pytest-mock = "^3.2.0" 40 | pytest-timeout = "^2.3.1" 41 | pytest-xdist = "^3.6.1" 42 | 43 | types-python-dateutil = "*" 44 | types-requests = "*" 45 | types-setuptools = "*" 46 | types-ujson = "*" 47 | 48 | [tool.poetry.scripts] 49 | coinmetrics = 'coinmetrics.typer_cli:main' 50 | cm-build-schema = 'coinmetrics.build:main' 51 | 52 | [build-system] 53 | requires = ["poetry-core>=1.0.0", "PyYAML"] 54 | build-backend = "poetry.core.masonry.api" 55 | 56 | [tool.poetry.build] 57 | generate-setup-file = false 58 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { lib 2 | , buildPythonPackage 3 | , fetchPypi 4 | , mypy 5 | , numpy 6 | , orjson 7 | , pandas 8 | , poetry-core 9 | , polars 10 | , pythonOlder 11 | , python-dateutil 12 | , pytestCheckHook 13 | , pytest-mock 14 | , pyyaml 15 | , requests 16 | , tqdm 17 | , typer 18 | , types-python-dateutil 19 | , types-pyyaml 20 | , types-requests 21 | , types-ujson 22 | , websocket-client 23 | }: 24 | 25 | buildPythonPackage rec { 26 | pname = "coinmetrics-api-client"; 27 | version = "2025.9.30.16"; 28 | format = "pyproject"; 29 | 30 | disabled = pythonOlder "3.9"; 31 | 32 | __darwinAllowLocalNetworking = true; 33 | 34 | src = ./.; 35 | 36 | nativeBuildInputs = [ 37 | poetry-core 38 | pyyaml 39 | ]; 40 | 41 | propagatedBuildInputs = [ 42 | numpy 43 | orjson 44 | python-dateutil 45 | requests 46 | typer 47 | websocket-client 48 | tqdm 49 | pandas 50 | polars 51 | pyyaml 52 | ]; 53 | 54 | nativeCheckInputs = [ 55 | mypy 56 | pytestCheckHook 57 | pytest-mock 58 | types-python-dateutil 59 | types-pyyaml 60 | types-requests 61 | types-ujson 62 | ]; 63 | 64 | pythonImportsCheck = [ 65 | "coinmetrics.api_client" 66 | ]; 67 | 68 | preBuild = '' 69 | echo "Generating OpenAPI schema" 70 | python coinmetrics/build.py 71 | ''; 72 | 73 | preCheck = '' 74 | mypy -p coinmetrics -p test 75 | ''; 76 | 77 | passthru = { 78 | optional-dependencies = { 79 | pandas = [ pandas ]; 80 | polars = [ polars ]; 81 | }; 82 | }; 83 | 84 | meta = with lib; { 85 | description = "Coin Metrics API v4 client library"; 86 | homepage = "https://coinmetrics.github.io/api-client-python/site/index.html"; 87 | license = licenses.mit; 88 | maintainers = with maintainers; [ centromere ]; 89 | }; 90 | } -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.zh.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r(require("@node-rs/jieba")):r()(e.lunr)}(this,function(e){return function(r,t){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==r.version[0];r.zh=function(){this.pipeline.reset(),this.pipeline.add(r.zh.trimmer,r.zh.stopWordFilter,r.zh.stemmer),i?this.tokenizer=r.zh.tokenizer:(r.tokenizer&&(r.tokenizer=r.zh.tokenizer),this.tokenizerFn&&(this.tokenizerFn=r.zh.tokenizer))},r.zh.tokenizer=function(n){if(!arguments.length||null==n||void 0==n)return[];if(Array.isArray(n))return n.map(function(e){return i?new r.Token(e.toLowerCase()):e.toLowerCase()});t&&e.load(t);var o=n.toString().trim().toLowerCase(),s=[];e.cut(o,!0).forEach(function(e){s=s.concat(e.split(" "))}),s=s.filter(function(e){return!!e});var u=0;return s.map(function(e,t){if(i){var n=o.indexOf(e,u),s={};return s.position=[n,e.length],s.index=t,u=n,new r.Token(e,s)}return e})},r.zh.wordCharacters="\\w一-龥",r.zh.trimmer=r.trimmerSupport.generateTrimmer(r.zh.wordCharacters),r.Pipeline.registerFunction(r.zh.trimmer,"trimmer-zh"),r.zh.stemmer=function(){return function(e){return e}}(),r.Pipeline.registerFunction(r.zh.stemmer,"stemmer-zh"),r.zh.stopWordFilter=r.generateStopWordFilter("的 一 不 在 人 有 是 为 為 以 于 於 上 他 而 后 後 之 来 來 及 了 因 下 可 到 由 这 這 与 與 也 此 但 并 並 个 個 其 已 无 無 小 我 们 們 起 最 再 今 去 好 只 又 或 很 亦 某 把 那 你 乃 它 吧 被 比 别 趁 当 當 从 從 得 打 凡 儿 兒 尔 爾 该 該 各 给 給 跟 和 何 还 還 即 几 幾 既 看 据 據 距 靠 啦 另 么 麽 每 嘛 拿 哪 您 凭 憑 且 却 卻 让 讓 仍 啥 如 若 使 谁 誰 虽 雖 随 隨 同 所 她 哇 嗡 往 些 向 沿 哟 喲 用 咱 则 則 怎 曾 至 致 着 著 诸 諸 自".split(" ")),r.Pipeline.registerFunction(r.zh.stopWordFilter,"stopWordFilter-zh")}}); -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.ja.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.ja=function(){this.pipeline.reset(),this.pipeline.add(e.ja.trimmer,e.ja.stopWordFilter,e.ja.stemmer),r?this.tokenizer=e.ja.tokenizer:(e.tokenizer&&(e.tokenizer=e.ja.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.ja.tokenizer))};var t=new e.TinySegmenter;e.ja.tokenizer=function(i){var n,o,s,p,a,u,m,l,c,f;if(!arguments.length||null==i||void 0==i)return[];if(Array.isArray(i))return i.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(o=i.toString().toLowerCase().replace(/^\s+/,""),n=o.length-1;n>=0;n--)if(/\S/.test(o.charAt(n))){o=o.substring(0,n+1);break}for(a=[],s=o.length,c=0,l=0;c<=s;c++)if(u=o.charAt(c),m=c-l,u.match(/\s/)||c==s){if(m>0)for(p=t.segment(o.slice(l,c)).filter(function(e){return!!e}),f=l,n=0;n docs/docs/reference/api_client.md 39 | cp -f README.md docs/docs/index.md 40 | cp -f CHANGELOG.md docs/docs/releases/CHANGELOG.md 41 | cp -f examples/README.md docs/docs/user-guide/examples.md 42 | cd docs && mkdocs build 43 | 44 | image: 45 | docker build --tag $(IMAGE) . 46 | 47 | imagetest: 48 | docker run --rm $(IMAGE) python -m mypy -p coinmetrics -p test 49 | docker run --rm $(IMAGE) python -m flake8 coinmetrics 50 | docker run -e CM_API_KEY=$(CM_API_KEY) --rm $(IMAGE) 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 51 | docker run -e CM_API_KEY=$(CM_API_KEY) --rm $(IMAGE) python -m pytest test/test_rate_limits.py 52 | 53 | clean: 54 | rm -rf ./cm_api_client_debug_*.txt 55 | rm -f coinmetrics/_schema_constants.py 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Coin Metrics Python API Client

2 | 3 |

4 | 5 |

6 | 7 | The **Coin Metrics Python API Client** is the official Python wrapper for the [Coin Metrics API](https://docs.coinmetrics.io/api/v4), allowing you to access [Coin Metrics data](https://docs.coinmetrics.io/) using Python. In just a few lines of code, anyone can access clean cryptocurrency data in a familiar form, such as a pandas dataframe. 8 | 9 | This tool offers the following convenient features over simply using `requests` to query the Coin Metrics API: 10 | 11 | - **Automatic Pagination**. The Coin Metrics API limits most endpoints to no more than 10,000 entries, requiring users to handle pagination. The Python API Client handles this automatically. 12 | - **DataFrames**. Users may access Coin Metrics data using pandas DataFrames and potentially other data structures, such as polars. 13 | - **Data Exports**. Users may export API outputs to CSV and JSON files. 14 | - **Typing**. DataFrames are automatically converted to the appropriate data types. 15 | - **Parallelization**. Users may submit many requests at once to extract data much more quickly than sending one request at a time. 16 | 17 | 18 | # Getting Started 19 | 20 | ## Installation and Updates 21 | To install the client you can run the following command: 22 | ``` 23 | pip install coinmetrics-api-client 24 | ``` 25 | 26 | Note that the client is updated regularly to reflect the changes made in [API v4](https://docs.coinmetrics.io/api/v4). Ensure that your latest version matches with what's in [pyPI](https://pypi.org/project/coinmetrics-api-client/) 27 | 28 | To update your version, run the following command: 29 | ``` 30 | pip install coinmetrics-api-client -U 31 | ``` 32 | 33 | ## Initialization 34 | 35 | To initialize the client you should use your API key, and the CoinMetricsClient class like the following. 36 | ```python 37 | from coinmetrics.api_client import CoinMetricsClient 38 | import os 39 | 40 | # we recommend storing your Coin Metrics API key in an environment variable 41 | api_key = os.environ.get("CM_API_KEY") 42 | client = CoinMetricsClient(api_key) 43 | 44 | # or to use community API: 45 | client = CoinMetricsClient() 46 | ``` -------------------------------------------------------------------------------- /docs/docs/index.md: -------------------------------------------------------------------------------- 1 |

Coin Metrics Python API Client

2 | 3 |

4 | 5 |

6 | 7 | The **Coin Metrics Python API Client** is the official Python wrapper for the [Coin Metrics API](https://docs.coinmetrics.io/api/v4), allowing you to access [Coin Metrics data](https://docs.coinmetrics.io/) using Python. In just a few lines of code, anyone can access clean cryptocurrency data in a familiar form, such as a pandas dataframe. 8 | 9 | This tool offers the following convenient features over simply using `requests` to query the Coin Metrics API: 10 | 11 | - **Automatic Pagination**. The Coin Metrics API limits most endpoints to no more than 10,000 entries, requiring users to handle pagination. The Python API Client handles this automatically. 12 | - **DataFrames**. Users may access Coin Metrics data using pandas DataFrames and potentially other data structures, such as polars. 13 | - **Data Exports**. Users may export API outputs to CSV and JSON files. 14 | - **Typing**. DataFrames are automatically converted to the appropriate data types. 15 | - **Parallelization**. Users may submit many requests at once to extract data much more quickly than sending one request at a time. 16 | 17 | 18 | # Getting Started 19 | 20 | ## Installation and Updates 21 | To install the client you can run the following command: 22 | ``` 23 | pip install coinmetrics-api-client 24 | ``` 25 | 26 | Note that the client is updated regularly to reflect the changes made in [API v4](https://docs.coinmetrics.io/api/v4). Ensure that your latest version matches with what's in [pyPI](https://pypi.org/project/coinmetrics-api-client/) 27 | 28 | To update your version, run the following command: 29 | ``` 30 | pip install coinmetrics-api-client -U 31 | ``` 32 | 33 | ## Initialization 34 | 35 | To initialize the client you should use your API key, and the CoinMetricsClient class like the following. 36 | ```python 37 | from coinmetrics.api_client import CoinMetricsClient 38 | import os 39 | 40 | # we recommend storing your Coin Metrics API key in an environment variable 41 | api_key = os.environ.get("CM_API_KEY") 42 | client = CoinMetricsClient(api_key) 43 | 44 | # or to use community API: 45 | client = CoinMetricsClient() 46 | ``` -------------------------------------------------------------------------------- /docs/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Coin Metrics Python API Client 2 | repo_url: https://github.com/coinmetrics/api-client-python 3 | # site_url: https://docs.coinmetrics.io/api-client-python 4 | site_url: https://coinmetrics.github.io/api-client-python/site/ 5 | 6 | theme: 7 | name: material 8 | features: 9 | - navigation.instant 10 | - navigation.tabs 11 | - navigation.tabs.sticky 12 | - navigation.tracking 13 | # - navigation.prune 14 | - navigation.path 15 | - navigation.indexes 16 | - navigation.footer 17 | # - navigation.sections 18 | - toc.follow 19 | - toc.integrate 20 | - search.suggest 21 | - search.highlight 22 | 23 | palette: 24 | # primary: blue grey 25 | primary: custom 26 | font: 27 | text: Lato 28 | logo: 'assets/images/logo.png' 29 | favicon: 'assets/images/logo.png' 30 | 31 | markdown_extensions: 32 | - markdown.extensions.admonition 33 | - markdown.extensions.codehilite: 34 | guess_lang: false 35 | linenums: true 36 | - markdown.extensions.def_list 37 | - markdown.extensions.footnotes 38 | - markdown.extensions.meta 39 | - markdown.extensions.toc: 40 | permalink: true 41 | - pymdownx.arithmatex 42 | - pymdownx.betterem: 43 | smart_enable: all 44 | - pymdownx.caret 45 | - pymdownx.critic 46 | - pymdownx.details 47 | - pymdownx.emoji: 48 | emoji_generator: !!python/name:pymdownx.emoji.to_svg 49 | - pymdownx.inlinehilite 50 | - pymdownx.keys 51 | - pymdownx.magiclink: 52 | repo_url_shorthand: true 53 | user: squidfunk 54 | repo: mkdocs-material 55 | - pymdownx.mark 56 | - pymdownx.smartsymbols 57 | - pymdownx.superfences 58 | - pymdownx.tasklist: 59 | custom_checkbox: true 60 | - pymdownx.tilde 61 | 62 | use_directory_urls: false 63 | 64 | nav: 65 | - User Guide: 66 | - index.md 67 | - Introduction: 68 | - user-guide/introduction.md 69 | - Best Practices: 70 | - user-guide/best-practices.md 71 | - Examples: 72 | - user-guide/examples.md 73 | - Troubleshooting: 74 | - user-guide/troubleshooting.md 75 | - API Reference: 76 | - reference/api_client.md 77 | - Releases: releases/CHANGELOG.md 78 | 79 | extra_css: 80 | - stylesheets/extra.css 81 | 82 | plugins: 83 | - search: 84 | lang: en 85 | 86 | extra: 87 | version: 88 | provider: mike -------------------------------------------------------------------------------- /SCHEMA_BUILD.md: -------------------------------------------------------------------------------- 1 | # Schema Build Process 2 | 3 | This document explains the optimized OpenAPI schema build process implemented to improve startup performance. 4 | 5 | ## Overview 6 | 7 | Instead of parsing the full 787KB `openapi.yaml` file at runtime, the build process extracts only the minimal schema components needed by the application and pre-generates them as Python constants. This reduces: 8 | 9 | - **File size**: From 787KB to 27KB (96.6% reduction) 10 | - **Schema count**: From 649 to 116 schemas (82% reduction) 11 | - **Startup time**: No runtime YAML parsing required 12 | 13 | ## How It Works 14 | 15 | 1. **Build-time extraction**: `coinmetrics/build.py` analyzes which schemas are actually used by the application 16 | 2. **Dependency resolution**: Recursively finds all schemas referenced by the required schemas 17 | 3. **Minimal generation**: Creates `_schema_constants.py` with only the needed components 18 | 4. **Runtime loading**: Schema resolver imports pre-built constants instead of parsing YAML 19 | 20 | ## Usage 21 | 22 | ### Manual Build 23 | ```bash 24 | # Generate schema constants 25 | make build-schema 26 | # or 27 | python coinmetrics/build.py 28 | ``` 29 | 30 | ### Clean Generated Files 31 | ```bash 32 | make clean 33 | ``` 34 | 35 | ## Integration 36 | 37 | - **Docker builds**: Schema generation runs automatically during `docker build` 38 | - **GitLab CI/CD**: Included in both Docker build and documentation stages 39 | - **Development**: Use `make build-schema` or run manually 40 | - **Fallback**: If generated file missing, automatically falls back to runtime YAML parsing 41 | 42 | ## Required Schemas 43 | 44 | The build process extracts these schemas and their dependencies: 45 | 46 | - MarketTrade, MarketCandle, MarketLiquidation 47 | - MarketOrderBook, MarketQuote, MarketFundingRate 48 | - MarketFundingRatePredicted, MarketOpenInterest 49 | - MarketContractPrices, MarketImpliedVolatility, MarketGreeks 50 | - PairCandle, IndexCandle 51 | - BlockchainBalanceUpdateV2, BlockchainBlockInfoV2 52 | - BlockchainFullSingleTransactionResponseV2, BlockchainFullBlockResponseV2 53 | 54 | ## Files 55 | 56 | - `coinmetrics/build.py` - Build script that extracts minimal schemas 57 | - `coinmetrics/_schema_constants.py` - Generated constants (git-ignored) 58 | - `coinmetrics/schema_resolver.py` - Modified to use build-time constants 59 | - `.gitignore` - Excludes generated file from version control -------------------------------------------------------------------------------- /test/test_models.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | import pandas as pd 4 | import pytest 5 | 6 | from coinmetrics.api_client import CoinMetricsClient 7 | from coinmetrics._models import TransactionTrackerData 8 | import os 9 | 10 | client = CoinMetricsClient(str(os.environ.get("CM_API_KEY"))) 11 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 12 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 13 | 14 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 15 | "CM_API_KEY not set, tests will not run" 16 | ) 17 | 18 | 19 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 20 | def test_asset_chains_optional_returns() -> None: 21 | """ 22 | In the old implementation, this test would fail since 'reorg' wouldn't be in the the df columns 23 | """ 24 | r = client.get_asset_chains( 25 | assets='btc', 26 | start_time='2022-10-22T05:40:00', # '2022-10-22T00:00:00', 27 | end_time='2022-10-22T06:40:00' 28 | ) 29 | 30 | print(r) 31 | df = r.to_dataframe() 32 | print(df.columns) 33 | print(df) 34 | assert 'reorg' in df.columns 35 | 36 | 37 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 38 | def test_normal_api_call_asset_chains() -> None: 39 | """ 40 | Tests that when calling get asset chains, the to_dataframe() will contain those with and without reorgs 41 | """ 42 | df: pd.DataFrame = client.get_asset_chains( 43 | assets='btc', 44 | start_time='2022-10-22T05:40:00', # '2022-10-22T00:00:00', 45 | end_time='2022-10-22T10:40:00' 46 | ).to_dataframe(dataframe_type='pandas') 47 | assert df.iloc[4].reorg == False 48 | assert df.iloc[3].reorg == True 49 | 50 | 51 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 52 | def test_get_transaction_tracker_df() -> None: 53 | request = client.get_transaction_tracker( 54 | 'btc', 55 | start_time='2023-03-30T00:00:00', 56 | end_time='2023-03-30T00:05:00', 57 | page_size=200 58 | ) 59 | df = request.to_dataframe() 60 | assert all([col in df.columns for col in TransactionTrackerData.get_dataframe_cols()]) 61 | 62 | 63 | 64 | if __name__ == '__main__': 65 | request = client.get_transaction_tracker( 66 | "btc", 67 | start_time=datetime.datetime.now() - datetime.timedelta(seconds=10), 68 | page_size=100 69 | ) 70 | df = request.to_dataframe() 71 | print("test!") -------------------------------------------------------------------------------- /test/data/catalog_metrics.csv: -------------------------------------------------------------------------------- 1 | metric,full_name,description,category,subcategory,unit,data_type,reviewable,frequency,asset 2 | 0,AdrActCnt,"Addresses, active, count",The sum count of unique addresses that were active in the network (either as a recipient or originator of a ledger change) that interval. All parties in a ledger change action (recipients and originators) are counted. Individual addresses are not double-counted if previously active.,Addresses,Active,Addresses,bigint,,1b,btc 3 | 1,AdrActCnt,"Addresses, active, count",The sum count of unique addresses that were active in the network (either as a recipient or originator of a ledger change) that interval. All parties in a ledger change action (recipients and originators) are counted. Individual addresses are not double-counted if previously active.,Addresses,Active,Addresses,bigint,,1b,eth 4 | 2,AdrActCnt,"Addresses, active, count",The sum count of unique addresses that were active in the network (either as a recipient or originator of a ledger change) that interval. All parties in a ledger change action (recipients and originators) are counted. Individual addresses are not double-counted if previously active.,Addresses,Active,Addresses,bigint,,1d,ada 5 | 3,AdrActCnt,"Addresses, active, count",The sum count of unique addresses that were active in the network (either as a recipient or originator of a ledger change) that interval. All parties in a ledger change action (recipients and originators) are counted. Individual addresses are not double-counted if previously active.,Addresses,Active,Addresses,bigint,,1d,btc 6 | 4,AdrActCnt,"Addresses, active, count",The sum count of unique addresses that were active in the network (either as a recipient or originator of a ledger change) that interval. All parties in a ledger change action (recipients and originators) are counted. Individual addresses are not double-counted if previously active.,Addresses,Active,Addresses,bigint,,1d,eth 7 | 5,FlowInBFXNtv,"Flow, in, to Bitfinex, native units",The sum in native units sent to Bitfinex that interval.,Exchange,Deposits,Native units,decimal,True,1b,btc 8 | 6,FlowInBFXNtv,"Flow, in, to Bitfinex, native units",The sum in native units sent to Bitfinex that interval.,Exchange,Deposits,Native units,decimal,True,1b,eth 9 | 7,FlowInBFXNtv,"Flow, in, to Bitfinex, native units",The sum in native units sent to Bitfinex that interval.,Exchange,Deposits,Native units,decimal,True,1d,btc 10 | 8,FlowInBFXNtv,"Flow, in, to Bitfinex, native units",The sum in native units sent to Bitfinex that interval.,Exchange,Deposits,Native units,decimal,True,1d,eth 11 | -------------------------------------------------------------------------------- /coinmetrics/_exceptions.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, List, Any 2 | from requests import HTTPError, Response 3 | from urllib.parse import urlparse, parse_qs 4 | from functools import reduce 5 | 6 | 7 | class CoinMetricsClientNotFoundError(Exception): 8 | """Raised when a CoinMetricsClient instance is not found.""" 9 | def __init__(self, message="CoinMetricsClient not found"): 10 | self.message = message 11 | super().__init__(self.message) 12 | 13 | 14 | class CoinMetricsClientBadParameterError(HTTPError): 15 | """ 16 | Raised when a request is made with bad parameters (HTTP 400). 17 | """ 18 | def __init__(self, response: Response, *args: Any, **kwargs: Any): 19 | if response.status_code != 400: 20 | response.raise_for_status() 21 | self.response = response 22 | self.request = response.request 23 | error_message = "Bad Parameter: The request contains invalid parameters." 24 | self.msg = error_message 25 | super().__init__(response=response, request=response.request, *args, **kwargs) 26 | 27 | def __str__(self) -> str: 28 | return self.msg 29 | 30 | 31 | class CoinMetricsClientUnauthorizedError(HTTPError): 32 | """ 33 | Raised when a request is unauthorized due to invalid or missing API key (HTTP 401). 34 | """ 35 | def __init__(self, response: Response, *args: Any, **kwargs: Any): 36 | if response.status_code != 401: 37 | response.raise_for_status() 38 | self.response = response 39 | self.request = response.request 40 | error_message = "Unauthorized: The API key is invalid or missing." 41 | self.msg = error_message 42 | super().__init__(response=response, request=response.request, *args, **kwargs) 43 | 44 | def __str__(self) -> str: 45 | return self.msg 46 | 47 | 48 | class CoinMetricsClientForbiddenError(HTTPError): 49 | """ 50 | Raised when a request is forbidden due to insufficient permissions (HTTP 403). 51 | """ 52 | def __init__(self, response: Response, *args: Any, **kwargs: Any): 53 | if response.status_code != 403: 54 | response.raise_for_status() 55 | self.response = response 56 | self.request = response.request 57 | error_message = "Forbidden: The API key does not have permission to access this resource." 58 | self.msg = error_message 59 | super().__init__(response=response, request=response.request, *args, **kwargs) 60 | 61 | def __str__(self) -> str: 62 | return self.msg 63 | 64 | 65 | -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.sa.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sa=function(){this.pipeline.reset(),this.pipeline.add(e.sa.trimmer,e.sa.stopWordFilter,e.sa.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sa.stemmer))},e.sa.wordCharacters="ऀ-ःऄ-एऐ-टठ-यर-िी-ॏॐ-य़ॠ-९॰-ॿ꣠-꣱ꣲ-ꣷ꣸-ꣻ꣼-ꣽꣾ-ꣿᆰ0-ᆰ9",e.sa.trimmer=e.trimmerSupport.generateTrimmer(e.sa.wordCharacters),e.Pipeline.registerFunction(e.sa.trimmer,"trimmer-sa"),e.sa.stopWordFilter=e.generateStopWordFilter('तथा अयम्‌ एकम्‌ इत्यस्मिन्‌ तथा तत्‌ वा अयम्‌ इत्यस्य ते आहूत उपरि तेषाम्‌ किन्तु तेषाम्‌ तदा इत्यनेन अधिकः इत्यस्य तत्‌ केचन बहवः द्वि तथा महत्वपूर्णः अयम्‌ अस्य विषये अयं अस्ति तत्‌ प्रथमः विषये इत्युपरि इत्युपरि इतर अधिकतमः अधिकः अपि सामान्यतया ठ इतरेतर नूतनम्‌ द न्यूनम्‌ कश्चित्‌ वा विशालः द सः अस्ति तदनुसारम् तत्र अस्ति केवलम्‌ अपि अत्र सर्वे विविधाः तत्‌ बहवः यतः इदानीम्‌ द दक्षिण इत्यस्मै तस्य उपरि नथ अतीव कार्यम्‌ सर्वे एकैकम्‌ इत्यादि। एते सन्ति उत इत्थम्‌ मध्ये एतदर्थं . स कस्य प्रथमः श्री. करोति अस्मिन् प्रकारः निर्मिता कालः तत्र कर्तुं समान अधुना ते सन्ति स एकः अस्ति सः अर्थात् तेषां कृते . स्थितम् विशेषः अग्रिम तेषाम्‌ समान स्रोतः ख म समान इदानीमपि अधिकतया करोतु ते समान इत्यस्य वीथी सह यस्मिन् कृतवान्‌ धृतः तदा पुनः पूर्वं सः आगतः किम्‌ कुल इतर पुरा मात्रा स विषये उ अतएव अपि नगरस्य उपरि यतः प्रतिशतं कतरः कालः साधनानि भूत तथापि जात सम्बन्धि अन्यत्‌ ग अतः अस्माकं स्वकीयाः अस्माकं इदानीं अन्तः इत्यादयः भवन्तः इत्यादयः एते एताः तस्य अस्य इदम् एते तेषां तेषां तेषां तान् तेषां तेषां तेषां समानः सः एकः च तादृशाः बहवः अन्ये च वदन्ति यत् कियत् कस्मै कस्मै यस्मै यस्मै यस्मै यस्मै न अतिनीचः किन्तु प्रथमं सम्पूर्णतया ततः चिरकालानन्तरं पुस्तकं सम्पूर्णतया अन्तः किन्तु अत्र वा इह इव श्रद्धाय अवशिष्यते परन्तु अन्ये वर्गाः सन्ति ते सन्ति शक्नुवन्ति सर्वे मिलित्वा सर्वे एकत्र"'.split(" ")),e.sa.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}();var r=e.wordcut;r.init(),e.sa.tokenizer=function(t){if(!arguments.length||null==t||void 0==t)return[];if(Array.isArray(t))return t.map(function(r){return isLunr2?new e.Token(r.toLowerCase()):r.toLowerCase()});var i=t.toString().toLowerCase().replace(/^\s+/,"");return r.cut(i).split("|")},e.Pipeline.registerFunction(e.sa.stemmer,"stemmer-sa"),e.Pipeline.registerFunction(e.sa.stopWordFilter,"stopWordFilter-sa")}}); -------------------------------------------------------------------------------- /test/test_custom_exceptions.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import requests 3 | from datetime import datetime 4 | from coinmetrics._exceptions import ( 5 | CoinMetricsClientQueryParamsException, 6 | # CoinMetricsUnauthorizedException, 7 | ) 8 | from coinmetrics.api_client import CoinMetricsClient 9 | from coinmetrics.data_exporter import CoinMetricsDataExporter 10 | import os 11 | 12 | client = CoinMetricsClient(str(os.environ.get("CM_API_KEY"))) 13 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 14 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 15 | 16 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 17 | "CM_API_KEY not set, tests will not run" 18 | ) 19 | 20 | 21 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 22 | def test_custom_414_error() -> None: 23 | """ 24 | Test for CoinMetricsClientQueryParamsException hitting a 414 error. 25 | """ 26 | markets = [market["market"] for market in client.reference_data_markets()] 27 | try: 28 | intentional_414 = client.reference_data_markets(markets=markets) 29 | except Exception as e: 30 | assert type(e) == CoinMetricsClientQueryParamsException 31 | print(e) 32 | 33 | 34 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 35 | def test_custom_exception_not_raised_for_403() -> None: 36 | """ 37 | Tests that custom exceptions are not raised for unauthorized - just a normal HTTPError, If a different error is 38 | is raised it asserts false 39 | """ 40 | unauthorized_client = CoinMetricsClient(api_key="Invalid API Key") 41 | try: 42 | intentional_401 = unauthorized_client.reference_data_markets() 43 | except requests.HTTPError as e: 44 | assert e.response is not None 45 | assert e.response.status_code == 401 46 | except Exception as e: 47 | assert False 48 | 49 | 50 | # @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 51 | # def test_403_error_message() -> None: 52 | # invalid_api_key = "invalid_key" 53 | # data_exporter = CoinMetricsDataExporter(api_key=invalid_api_key) 54 | # try: 55 | # start_date = datetime(2019, 1, 1) 56 | # end_date = datetime(2019, 1, 31) 57 | # exchanges = ["coinbase", "gemini"] 58 | # data_exporter.export_market_trades_spot_data( 59 | # start_date=start_date, end_date=end_date, exchanges=exchanges, threaded=True 60 | # ) 61 | # except CoinMetricsUnauthorizedException as e: 62 | # assert e.response is not None 63 | # assert e.response.status_code == 403 or e.response.status_code == 401 64 | # print(e) 65 | 66 | 67 | if __name__ == "__main__": 68 | pytest.main() 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Python template 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | pip-wheel-metadata/ 26 | share/python-wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | MANIFEST 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .nox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | *.py,cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | cover/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | .pybuilder/ 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | # For a library or package, you might want to ignore these files since the code is 90 | # intended to run in multiple environments; otherwise, check them in: 91 | # .python-version 92 | 93 | # pipenv 94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 97 | # install all needed dependencies. 98 | #Pipfile.lock 99 | 100 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 101 | __pypackages__/ 102 | 103 | # Celery stuff 104 | celerybeat-schedule 105 | celerybeat.pid 106 | 107 | # SageMath parsed files 108 | *.sage.py 109 | 110 | # Environments 111 | .env 112 | .venv*/ 113 | env/ 114 | venv/ 115 | ENV/ 116 | env.bak/ 117 | venv.bak/ 118 | 119 | # Spyder project settings 120 | .spyderproject 121 | .spyproject 122 | 123 | # Rope project settings 124 | .ropeproject 125 | 126 | # mkdocs documentation 127 | /site 128 | 129 | # mypy 130 | .mypy_cache/ 131 | .dmypy.json 132 | dmypy.json 133 | 134 | # Pyre type checker 135 | .pyre/ 136 | 137 | # pytype static type analyzer 138 | .pytype/ 139 | 140 | # Cython debug symbols 141 | cython_debug/ 142 | 143 | examples/data/ 144 | *.csv 145 | examples/*.txt 146 | examples/*/*.txt 147 | 148 | .idea/ 149 | .DS_Store 150 | 151 | # Debugging 152 | cm_api_client_debug*.txt -------------------------------------------------------------------------------- /test/test_api_methods.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | 3 | from coinmetrics.api_client import CoinMetricsClient 4 | import os 5 | 6 | client = CoinMetricsClient(str(os.environ.get("CM_API_KEY"))) 7 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 8 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 9 | 10 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 11 | "CM_API_KEY not set, tests will not run" 12 | ) 13 | 14 | 15 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 16 | def test_timeseries_pair_candles() -> None: 17 | """ 18 | Tests the timeseries/pair-candles endpoints works as expected - data is returned and the date is in the right format 19 | """ 20 | data = client.get_pair_candles(pairs=["btc-usd", "eth-usd", "sol-usd"]) 21 | assert len(data.first_page()) != 0 22 | expected_cols = [ 23 | "pair", 24 | "time", 25 | "price_open", 26 | "price_close", 27 | "price_high", 28 | "price_low", 29 | ] 30 | assert all(col in expected_cols for col in data.first_page()[0]) 31 | 32 | 33 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 34 | def test_get_list_of_transactions_v2_eth() -> None: 35 | """ 36 | Tests the timeseries get list of transactions v2 for eth 37 | """ 38 | transactions = client.get_list_of_transactions_v2( 39 | asset="eth", start_height=16644700, end_height=16644767 40 | ).to_list() 41 | assert len(transactions) >= 9800 42 | transactions_called_by_id = client.get_list_of_transactions_v2( 43 | asset="eth", 44 | txids="1ec9982bee6cd96049b0ac7745df4374bcd37dce996bae46d09c3d25c5cfd413", 45 | ).first_page()[0] 46 | assert ( 47 | transactions_called_by_id["height"] == "16644767" 48 | and transactions_called_by_id["n_balance_updates"] == "9" 49 | ) 50 | 51 | 52 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 53 | def test_get_list_of_balance_updates_v2() -> None: 54 | asset = "usdc" 55 | accounts = [ 56 | "4a30ff596cc84c630b2998012b0586ff36113cba", 57 | "4dd384f41f3e91f2e204fd462dc0fa73aef029d4", 58 | ] 59 | updates = client.get_list_of_balance_updates_v2( 60 | asset=asset, accounts=accounts, limit_per_account=1 61 | ).to_list() 62 | assert len(updates) == 2 63 | 64 | 65 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 66 | def test_get_asset_profiles() -> None: 67 | data = client.get_asset_profiles().first_page() 68 | print(data) 69 | assert len(data) > 10 70 | one_inch = client.get_asset_profiles(assets="1inch").first_page()[0] 71 | assert one_inch["asset"] == "1inch" 72 | 73 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 74 | def test_get_predicted_market_funding_rates() -> None: 75 | data = client.get_predicted_market_funding_rates( 76 | markets="bybit-1000000VINUUSDT-future" 77 | ).first_page() 78 | print(data) 79 | assert len(data) > 1 80 | predicted_funding_rate = data[0] 81 | assert predicted_funding_rate["market"] == "bybit-1000000VINUUSDT-future" 82 | 83 | 84 | if __name__ == "__main__": 85 | pytest.main() 86 | -------------------------------------------------------------------------------- /test/test_to_list.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | import pytest 4 | 5 | from coinmetrics.api_client import CoinMetricsClient 6 | import os 7 | 8 | client = CoinMetricsClient(str(os.environ.get("CM_API_KEY"))) 9 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 10 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 11 | 12 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 13 | "CM_API_KEY not set, tests will not run" 14 | ) 15 | 16 | 17 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 18 | def test_to_list_works_like_first_page_short_query() -> None: 19 | """ 20 | In theory, on a small query that works on a small number of results should have equivalent results for .first_page() 21 | and also _to_list() 22 | """ 23 | test_time = datetime.datetime(year=2022, month=2, day=1) 24 | assets = ["eth", "algo", "btc"] 25 | data_first_page = client.get_asset_metrics( 26 | assets=assets, 27 | metrics="SplyFF", 28 | limit_per_asset=1, 29 | start_time=test_time, 30 | end_time=test_time, 31 | format="json", 32 | ).first_page() 33 | data_list = client.get_asset_metrics( 34 | assets=assets, 35 | metrics="SplyFF", 36 | limit_per_asset=1, 37 | start_time=test_time, 38 | end_time=test_time, 39 | format="json", 40 | ).to_list() 41 | assert data_list == data_first_page 42 | 43 | 44 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 45 | def test_to_list_doesnt_work_like_first_page_long_query() -> None: 46 | """ 47 | In theory, on a long query, that will have multiple pages of response data should have very different results 48 | as first page 49 | """ 50 | start_time = datetime.datetime(year=2021, month=1, day=1) 51 | end_time = datetime.datetime(year=2022, month=2, day=1) 52 | assets = ["eth", "algo", "btc"] 53 | data_first_page = client.get_asset_metrics( 54 | assets=assets, 55 | metrics="SplyFF", 56 | limit_per_asset=100, 57 | start_time=start_time, 58 | end_time=end_time, 59 | format="json", 60 | ).first_page() 61 | data_list = client.get_asset_metrics( 62 | assets=assets, 63 | metrics="SplyFF", 64 | limit_per_asset=100, 65 | start_time=start_time, 66 | end_time=end_time, 67 | format="json", 68 | ).to_list() 69 | assert data_list != data_first_page 70 | 71 | 72 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 73 | def test_to_list_gets_all_data() -> None: 74 | """ 75 | This tests that .to_list() gets the same amount and the same data as _to_dataframe() 76 | """ 77 | start_time = datetime.datetime(year=2021, month=1, day=1) 78 | end_time = datetime.datetime(year=2022, month=2, day=1) 79 | assets = ["eth"] 80 | data_df = client.get_asset_metrics( 81 | assets=assets, 82 | metrics="ReferenceRateUSD", 83 | start_time=start_time, 84 | end_time=end_time, 85 | ).to_dataframe() 86 | data_list = client.get_asset_metrics( 87 | assets=assets, 88 | metrics="ReferenceRateUSD", 89 | start_time=start_time, 90 | end_time=end_time, 91 | ).to_list() 92 | assert len(data_df) == len(data_list) 93 | 94 | 95 | if __name__ == "__main__": 96 | pytest.main() 97 | -------------------------------------------------------------------------------- /test/data/catalog_exchanges_markets.csv: -------------------------------------------------------------------------------- 1 | exchange,market,min_time,max_time,metrics 2 | 0,bibox,bibox-abt-btc-spot,2019-04-24 11:09:59+00:00,2019-05-18 16:06:10.927000+00:00,"[{'metric': 'volume_reported_spot_usd_1d', 'frequencies': [{'frequency': '1d', 'min_time': '2019-04-30T00:00:00.000000000Z', 'max_time': '2019-06-16T00:00:00.000000000Z'}]}, {'metric': 'volume_reported_spot_usd_1h', 'frequencies': [{'frequency': '1h', 'min_time': '2019-04-29T21:00:00.000000000Z', 'max_time': '2019-06-17T15:00:00.000000000Z'}]}]" 3 | 0,bibox,bibox-etc-usdt-spot,2019-04-24 11:09:59+00:00,2019-05-18 16:06:10.927000+00:00,"[{'metric': 'volume_reported_spot_usd_1d', 'frequencies': [{'frequency': '1d', 'min_time': '2019-04-30T00:00:00.000000000Z', 'max_time': '2019-06-16T00:00:00.000000000Z'}]}, {'metric': 'volume_reported_spot_usd_1h', 'frequencies': [{'frequency': '1h', 'min_time': '2019-04-29T21:00:00.000000000Z', 'max_time': '2019-06-17T15:00:00.000000000Z'}]}]" 4 | 1,binance,binance-BTCUSDT-future,2017-07-14 04:00:00.510000+00:00,2020-06-08 20:33:28.868000+00:00,"[{'metric': 'volume_reported_spot_usd_1d', 'frequencies': [{'frequency': '1d', 'min_time': '2019-04-30T00:00:00.000000000Z', 'max_time': '2019-06-16T00:00:00.000000000Z'}]}, {'metric': 'volume_reported_spot_usd_1h', 'frequencies': [{'frequency': '1h', 'min_time': '2019-04-29T21:00:00.000000000Z', 'max_time': '2019-06-17T15:00:00.000000000Z'}]}]" 5 | 1,binance,binance-LTCUSDT-future,2017-07-14 04:00:00.510000+00:00,2020-06-08 20:33:28.868000+00:00,"[{'metric': 'volume_reported_spot_usd_1d', 'frequencies': [{'frequency': '1d', 'min_time': '2019-04-30T00:00:00.000000000Z', 'max_time': '2019-06-16T00:00:00.000000000Z'}]}, {'metric': 'volume_reported_spot_usd_1h', 'frequencies': [{'frequency': '1h', 'min_time': '2019-04-29T21:00:00.000000000Z', 'max_time': '2019-06-17T15:00:00.000000000Z'}]}]" 6 | 1,binance,binance-ada-bnb-spot,2017-07-14 04:00:00.510000+00:00,2020-06-08 20:33:28.868000+00:00,"[{'metric': 'volume_reported_spot_usd_1d', 'frequencies': [{'frequency': '1d', 'min_time': '2019-04-30T00:00:00.000000000Z', 'max_time': '2019-06-16T00:00:00.000000000Z'}]}, {'metric': 'volume_reported_spot_usd_1h', 'frequencies': [{'frequency': '1h', 'min_time': '2019-04-29T21:00:00.000000000Z', 'max_time': '2019-06-17T15:00:00.000000000Z'}]}]" 7 | 1,binance,binance-btc-usdt-spot,2017-07-14 04:00:00.510000+00:00,2020-06-08 20:33:28.868000+00:00,"[{'metric': 'volume_reported_spot_usd_1d', 'frequencies': [{'frequency': '1d', 'min_time': '2019-04-30T00:00:00.000000000Z', 'max_time': '2019-06-16T00:00:00.000000000Z'}]}, {'metric': 'volume_reported_spot_usd_1h', 'frequencies': [{'frequency': '1h', 'min_time': '2019-04-29T21:00:00.000000000Z', 'max_time': '2019-06-17T15:00:00.000000000Z'}]}]" 8 | 1,binance,binance-bcpt-btc-spot,2017-07-14 04:00:00.510000+00:00,2020-06-08 20:33:28.868000+00:00,"[{'metric': 'volume_reported_spot_usd_1d', 'frequencies': [{'frequency': '1d', 'min_time': '2019-04-30T00:00:00.000000000Z', 'max_time': '2019-06-16T00:00:00.000000000Z'}]}, {'metric': 'volume_reported_spot_usd_1h', 'frequencies': [{'frequency': '1h', 'min_time': '2019-04-29T21:00:00.000000000Z', 'max_time': '2019-06-17T15:00:00.000000000Z'}]}]" 9 | 1,binance,binance-bcd-eth-spot,2017-07-14 04:00:00.510000+00:00,2020-06-08 20:33:28.868000+00:00,"[{'metric': 'volume_reported_spot_usd_1d', 'frequencies': [{'frequency': '1d', 'min_time': '2019-04-30T00:00:00.000000000Z', 'max_time': '2019-06-16T00:00:00.000000000Z'}]}, {'metric': 'volume_reported_spot_usd_1h', 'frequencies': [{'frequency': '1h', 'min_time': '2019-04-29T21:00:00.000000000Z', 'max_time': '2019-06-17T15:00:00.000000000Z'}]}]" 10 | -------------------------------------------------------------------------------- /docs/site/assets/stylesheets/palette.06af60db.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["src/templates/assets/stylesheets/palette/_scheme.scss","../../../../src/templates/assets/stylesheets/palette.scss","src/templates/assets/stylesheets/palette/_accent.scss","src/templates/assets/stylesheets/palette/_primary.scss","src/templates/assets/stylesheets/utilities/_break.scss"],"names":[],"mappings":"AA2BA,cAGE,6BAME,sDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CACA,mDAAA,CACA,6DAAA,CACA,+DAAA,CACA,gEAAA,CAGA,mDAAA,CACA,gDAAA,CAGA,0BAAA,CACA,mCAAA,CAGA,iCAAA,CACA,kCAAA,CACA,mCAAA,CACA,mCAAA,CACA,kCAAA,CACA,iCAAA,CACA,+CAAA,CACA,6DAAA,CACA,gEAAA,CACA,4DAAA,CACA,4DAAA,CACA,6DAAA,CAGA,6CAAA,CAGA,+CAAA,CAGA,uDAAA,CACA,6DAAA,CACA,2DAAA,CAGA,iCAAA,CAGA,yDAAA,CACA,iEAAA,CAGA,mDAAA,CACA,mDAAA,CAGA,qDAAA,CACA,uDAAA,CAGA,8DAAA,CAKA,8DAAA,CAKA,0DAAA,CAvEA,iBCeF,CD6DE,kHAEE,YC3DJ,CDkFE,yDACE,4BChFJ,CD+EE,2DACE,4BC7EJ,CD4EE,gEACE,4BC1EJ,CDyEE,2DACE,4BCvEJ,CDsEE,yDACE,4BCpEJ,CDmEE,0DACE,4BCjEJ,CDgEE,gEACE,4BC9DJ,CD6DE,0DACE,4BC3DJ,CD0DE,2OACE,4BC/CJ,CDsDA,+FAGE,iCCpDF,CACF,CC/CE,2BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD2CN,CCrDE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDkDN,CC5DE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDyDN,CCnEE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDgEN,CC1EE,8BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDuEN,CCjFE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD8EN,CCxFE,kCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDqFN,CC/FE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD4FN,CCtGE,4BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDmGN,CC7GE,6BACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCD0GN,CCpHE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDiHN,CC3HE,4BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCD2HN,CClIE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDkIN,CCzIE,6BACE,yBAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDyIN,CChJE,8BACE,4BAAA,CACA,2CAAA,CAIE,8BAAA,CACA,qCDgJN,CCvJE,mCACE,4BAAA,CACA,2CAAA,CAOE,yBAAA,CACA,qCDoJN,CEzJE,4BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsJN,CEjKE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8JN,CEzKE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsKN,CEjLE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8KN,CEzLE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsLN,CEjME,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8LN,CEzME,mCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsMN,CEjNE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8MN,CEzNE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsNN,CEjOE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8NN,CEzOE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsON,CEjPE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFiPN,CEzPE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFyPN,CEjQE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFiQN,CEzQE,+BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAIE,+BAAA,CACA,sCFyQN,CEjRE,oCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCF8QN,CEzRE,8BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCFsRN,CEjSE,6BACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BF0RN,CE1SE,kCACE,6BAAA,CACA,oCAAA,CACA,mCAAA,CAOE,0BAAA,CACA,sCAAA,CAKA,4BFmSN,CEpRE,sEACE,4BFuRJ,CExRE,+DACE,4BF2RJ,CE5RE,iEACE,4BF+RJ,CEhSE,gEACE,4BFmSJ,CEpSE,iEACE,4BFuSJ,CE9RA,8BACE,mDAAA,CACA,4DAAA,CACA,0DAAA,CACA,oDAAA,CACA,2DAAA,CAGA,4BF+RF,CE5RE,yCACE,+BF8RJ,CE3RI,kDAEE,0CAAA,CACA,sCAAA,CAFA,mCF+RN,CG3MI,mCD1EA,+CACE,8CFwRJ,CErRI,qDACE,8CFuRN,CElRE,iEACE,mCFoRJ,CACF,CGtNI,sCDvDA,uCACE,oCFgRJ,CACF,CEvQA,8BACE,kDAAA,CACA,4DAAA,CACA,wDAAA,CACA,oDAAA,CACA,6DAAA,CAGA,4BFwQF,CErQE,yCACE,+BFuQJ,CEpQI,kDAEE,0CAAA,CACA,sCAAA,CAFA,mCFwQN,CEjQE,yCACE,6CFmQJ,CG5NI,0CDhCA,8CACE,gDF+PJ,CACF,CGjOI,0CDvBA,iFACE,6CF2PJ,CACF,CGzPI,sCDKA,uCACE,6CFuPJ,CACF","file":"palette.css"} -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.stemmer.support.min.js: -------------------------------------------------------------------------------- 1 | !function(r,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&(e-=i,t[e>>3]&1<<(7&e)))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursors||e>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor>1),f=0,l=o0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o=0;m--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var _=t[s];if(o>=_.s_size){if(this.cursor=n-_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n-_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.ko.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.ko=function(){this.pipeline.reset(),this.pipeline.add(e.ko.trimmer,e.ko.stopWordFilter)},e.ko.wordCharacters="[A-Za-z가-힣]",e.ko.trimmer=e.trimmerSupport.generateTrimmer(e.ko.wordCharacters),e.Pipeline.registerFunction(e.ko.trimmer,"trimmer-ko"),e.ko.stopWordFilter=e.generateStopWordFilter("아 휴 아이구 아이쿠 아이고 어 나 우리 저희 따라 의해 을 를 에 의 가 으로 로 에게 뿐이다 의거하여 근거하여 입각하여 기준으로 예하면 예를 들면 예를 들자면 저 소인 소생 저희 지말고 하지마 하지마라 다른 물론 또한 그리고 비길수 없다 해서는 안된다 뿐만 아니라 만이 아니다 만은 아니다 막론하고 관계없이 그치지 않다 그러나 그런데 하지만 든간에 논하지 않다 따지지 않다 설사 비록 더라도 아니면 만 못하다 하는 편이 낫다 불문하고 향하여 향해서 향하다 쪽으로 틈타 이용하여 타다 오르다 제외하고 이 외에 이 밖에 하여야 비로소 한다면 몰라도 외에도 이곳 여기 부터 기점으로 따라서 할 생각이다 하려고하다 이리하여 그리하여 그렇게 함으로써 하지만 일때 할때 앞에서 중에서 보는데서 으로써 로써 까지 해야한다 일것이다 반드시 할줄알다 할수있다 할수있어 임에 틀림없다 한다면 등 등등 제 겨우 단지 다만 할뿐 딩동 댕그 대해서 대하여 대하면 훨씬 얼마나 얼마만큼 얼마큼 남짓 여 얼마간 약간 다소 좀 조금 다수 몇 얼마 지만 하물며 또한 그러나 그렇지만 하지만 이외에도 대해 말하자면 뿐이다 다음에 반대로 반대로 말하자면 이와 반대로 바꾸어서 말하면 바꾸어서 한다면 만약 그렇지않으면 까악 툭 딱 삐걱거리다 보드득 비걱거리다 꽈당 응당 해야한다 에 가서 각 각각 여러분 각종 각자 제각기 하도록하다 와 과 그러므로 그래서 고로 한 까닭에 하기 때문에 거니와 이지만 대하여 관하여 관한 과연 실로 아니나다를가 생각한대로 진짜로 한적이있다 하곤하였다 하 하하 허허 아하 거바 와 오 왜 어째서 무엇때문에 어찌 하겠는가 무슨 어디 어느곳 더군다나 하물며 더욱이는 어느때 언제 야 이봐 어이 여보시오 흐흐 흥 휴 헉헉 헐떡헐떡 영차 여차 어기여차 끙끙 아야 앗 아야 콸콸 졸졸 좍좍 뚝뚝 주룩주룩 솨 우르르 그래도 또 그리고 바꾸어말하면 바꾸어말하자면 혹은 혹시 답다 및 그에 따르는 때가 되어 즉 지든지 설령 가령 하더라도 할지라도 일지라도 지든지 몇 거의 하마터면 인젠 이젠 된바에야 된이상 만큼\t어찌됏든 그위에 게다가 점에서 보아 비추어 보아 고려하면 하게될것이다 일것이다 비교적 좀 보다더 비하면 시키다 하게하다 할만하다 의해서 연이서 이어서 잇따라 뒤따라 뒤이어 결국 의지하여 기대여 통하여 자마자 더욱더 불구하고 얼마든지 마음대로 주저하지 않고 곧 즉시 바로 당장 하자마자 밖에 안된다 하면된다 그래 그렇지 요컨대 다시 말하자면 바꿔 말하면 즉 구체적으로 말하자면 시작하여 시초에 이상 허 헉 허걱 바와같이 해도좋다 해도된다 게다가 더구나 하물며 와르르 팍 퍽 펄렁 동안 이래 하고있었다 이었다 에서 로부터 까지 예하면 했어요 해요 함께 같이 더불어 마저 마저도 양자 모두 습니다 가까스로 하려고하다 즈음하여 다른 다른 방면으로 해봐요 습니까 했어요 말할것도 없고 무릎쓰고 개의치않고 하는것만 못하다 하는것이 낫다 매 매번 들 모 어느것 어느 로써 갖고말하자면 어디 어느쪽 어느것 어느해 어느 년도 라 해도 언젠가 어떤것 어느것 저기 저쪽 저것 그때 그럼 그러면 요만한걸 그래 그때 저것만큼 그저 이르기까지 할 줄 안다 할 힘이 있다 너 너희 당신 어찌 설마 차라리 할지언정 할지라도 할망정 할지언정 구토하다 게우다 토하다 메쓰겁다 옆사람 퉤 쳇 의거하여 근거하여 의해 따라 힘입어 그 다음 버금 두번째로 기타 첫번째로 나머지는 그중에서 견지에서 형식으로 쓰여 입장에서 위해서 단지 의해되다 하도록시키다 뿐만아니라 반대로 전후 전자 앞의것 잠시 잠깐 하면서 그렇지만 다음에 그러한즉 그런즉 남들 아무거나 어찌하든지 같다 비슷하다 예컨대 이럴정도로 어떻게 만약 만일 위에서 서술한바와같이 인 듯하다 하지 않는다면 만약에 무엇 무슨 어느 어떤 아래윗 조차 한데 그럼에도 불구하고 여전히 심지어 까지도 조차도 하지 않도록 않기 위하여 때 시각 무렵 시간 동안 어때 어떠한 하여금 네 예 우선 누구 누가 알겠는가 아무도 줄은모른다 줄은 몰랏다 하는 김에 겸사겸사 하는바 그런 까닭에 한 이유는 그러니 그러니까 때문에 그 너희 그들 너희들 타인 것 것들 너 위하여 공동으로 동시에 하기 위하여 어찌하여 무엇때문에 붕붕 윙윙 나 우리 엉엉 휘익 윙윙 오호 아하 어쨋든 만 못하다\t하기보다는 차라리 하는 편이 낫다 흐흐 놀라다 상대적으로 말하자면 마치 아니라면 쉿 그렇지 않으면 그렇지 않다면 안 그러면 아니었다면 하든지 아니면 이라면 좋아 알았어 하는것도 그만이다 어쩔수 없다 하나 일 일반적으로 일단 한켠으로는 오자마자 이렇게되면 이와같다면 전부 한마디 한항목 근거로 하기에 아울러 하지 않도록 않기 위해서 이르기까지 이 되다 로 인하여 까닭으로 이유만으로 이로 인하여 그래서 이 때문에 그러므로 그런 까닭에 알 수 있다 결론을 낼 수 있다 으로 인하여 있다 어떤것 관계가 있다 관련이 있다 연관되다 어떤것들 에 대해 이리하여 그리하여 여부 하기보다는 하느니 하면 할수록 운운 이러이러하다 하구나 하도다 다시말하면 다음으로 에 있다 에 달려 있다 우리 우리들 오히려 하기는한데 어떻게 어떻해 어찌됏어 어때 어째서 본대로 자 이 이쪽 여기 이것 이번 이렇게말하자면 이런 이러한 이와 같은 요만큼 요만한 것 얼마 안 되는 것 이만큼 이 정도의 이렇게 많은 것 이와 같다 이때 이렇구나 것과 같이 끼익 삐걱 따위 와 같은 사람들 부류의 사람들 왜냐하면 중의하나 오직 오로지 에 한하다 하기만 하면 도착하다 까지 미치다 도달하다 정도에 이르다 할 지경이다 결과에 이르다 관해서는 여러분 하고 있다 한 후 혼자 자기 자기집 자신 우에 종합한것과같이 총적으로 보면 총적으로 말하면 총적으로 대로 하다 으로서 참 그만이다 할 따름이다 쿵 탕탕 쾅쾅 둥둥 봐 봐라 아이야 아니 와아 응 아이 참나 년 월 일 령 영 일 이 삼 사 오 육 륙 칠 팔 구 이천육 이천칠 이천팔 이천구 하나 둘 셋 넷 다섯 여섯 일곱 여덟 아홉 령 영".split(" ")),e.Pipeline.registerFunction(e.ko.stopWordFilter,"stopWordFilter-ko"),e.ko.stemmer=function(){return function(e){return"function"==typeof e.update?e.update(function(e){return e}):e}}(),e.Pipeline.registerFunction(e.ko.stemmer,"stemmer-ko")}}); -------------------------------------------------------------------------------- /test/test_refd_methods.py: -------------------------------------------------------------------------------- 1 | import os 2 | import threading 3 | import pytest 4 | 5 | from coinmetrics.api_client import CoinMetricsClient 6 | 7 | client = CoinMetricsClient(str(os.environ.get("CM_API_KEY"))) 8 | cm_api_key_set = os.environ.get("CM_API_KEY") is not None 9 | REASON_TO_SKIP = "Need to set CM_API_KEY as an env var in order to run this test" 10 | 11 | print("CM_API_KEY is set - tests will run") if cm_api_key_set else print( 12 | "CM_API_KEY not set, tests will not run" 13 | ) 14 | 15 | COMMON_REFD_COLS = ["metric", 16 | "full_name", 17 | "description", 18 | "product", 19 | "category", 20 | "subcategory", 21 | "unit", 22 | "data_type", 23 | "type", 24 | "display_name"] 25 | 26 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 27 | def test_refd_asset_pairs() -> None: 28 | expected_cols = COMMON_REFD_COLS 29 | asset_pairs = next(client.reference_data_pair_metrics()) 30 | assert all([col in asset_pairs for col in expected_cols]) 31 | 32 | 33 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 34 | def test_refd_institution_metrics() -> None: 35 | expected_cols = COMMON_REFD_COLS 36 | institution_data = next(client.reference_data_institution_metrics()) 37 | assert all([col in institution_data for col in expected_cols]) 38 | 39 | 40 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 41 | def test_refd_exchange_asset_metrics() -> None: 42 | expected_cols = COMMON_REFD_COLS 43 | exchange_asset_metrics = next(client.reference_data_exchange_asset_metrics()) 44 | assert all([col in exchange_asset_metrics for col in expected_cols]) 45 | 46 | 47 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 48 | def test_refd_exchange_metrics() -> None: 49 | expected_cols = COMMON_REFD_COLS 50 | exchange_asset_metrics = next(client.reference_data_exchange_metrics()) 51 | assert all([col in exchange_asset_metrics for col in expected_cols]) 52 | 53 | 54 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 55 | def test_refd_asset_metrics() -> None: 56 | expected_cols = COMMON_REFD_COLS 57 | asset_metrics = next(client.reference_data_exchange_asset_metrics()) 58 | assert all([col in asset_metrics for col in expected_cols]) 59 | 60 | 61 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 62 | def test_refd_assets() -> None: 63 | expected_cols = ["asset", "full_name"] 64 | assets = next(client.reference_data_assets()) 65 | assert all([col in assets for col in expected_cols]) 66 | 67 | 68 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 69 | def test_refd_indexes() -> None: 70 | expected_cols = ["index", "full_name", "description", "type"] 71 | indexes = next(client.reference_data_indexes()) 72 | assert all([col in indexes for col in expected_cols]) 73 | 74 | 75 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 76 | def test_refd_pairs() -> None: 77 | expected_cols = ["pair", "full_name"] 78 | pairs = next(client.reference_data_pairs()) 79 | assert all([col in pairs for col in expected_cols]) 80 | 81 | 82 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 83 | def test_refd_market_metrics() -> None: 84 | expected_cols = ["metric", "full_name", "description", "product", "category", "subcategory", "unit", "data_type", "display_name"] 85 | pairs = next(client.reference_data_market_metrics()) 86 | assert all([col in pairs for col in expected_cols]) 87 | 88 | 89 | @pytest.mark.skipif(not cm_api_key_set, reason=REASON_TO_SKIP) 90 | def test_refd_markets() -> None: 91 | expected_cols = ["market", "exchange", "type"] 92 | markets = next(client.reference_data_markets()) 93 | assert all([col in markets for col in expected_cols]) 94 | 95 | 96 | if __name__ == '__main__': 97 | pytest.main() 98 | -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.sv.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Swedish` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){function e(){var e,r=w.cursor+3;if(o=w.limit,0<=r||r<=w.limit){for(a=r;;){if(e=w.cursor,w.in_grouping(l,97,246)){w.cursor=e;break}if(w.cursor=e,w.cursor>=w.limit)return;w.cursor++}for(;!w.out_grouping(l,97,246);){if(w.cursor>=w.limit)return;w.cursor++}o=w.cursor,o=o&&(w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(u,37),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.in_grouping_b(d,98,121)&&w.slice_del()}}function i(){var e=w.limit_backward;w.cursor>=o&&(w.limit_backward=o,w.cursor=w.limit,w.find_among_b(c,7)&&(w.cursor=w.limit,w.ket=w.cursor,w.cursor>w.limit_backward&&(w.bra=--w.cursor,w.slice_del())),w.limit_backward=e)}function s(){var e,r;if(w.cursor>=o){if(r=w.limit_backward,w.limit_backward=o,w.cursor=w.limit,w.ket=w.cursor,e=w.find_among_b(m,5))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:w.slice_from("lös");break;case 3:w.slice_from("full")}w.limit_backward=r}}var a,o,u=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],c=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],l=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],d=[119,127,149],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,t(),w.cursor=w.limit,i(),w.cursor=w.limit,s(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}}(),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.da.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Danish` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=function(){var r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){function e(){var e,r=f.cursor+3;if(d=f.limit,0<=r&&r<=f.limit){for(a=r;;){if(e=f.cursor,f.in_grouping(w,97,248)){f.cursor=e;break}if(f.cursor=e,e>=f.limit)return;f.cursor++}for(;!f.out_grouping(w,97,248);){if(f.cursor>=f.limit)return;f.cursor++}d=f.cursor,d=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(c,32),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del();break;case 2:f.in_grouping_b(p,97,229)&&f.slice_del()}}function t(){var e,r=f.limit-f.cursor;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.find_among_b(l,4)?(f.bra=f.cursor,f.limit_backward=e,f.cursor=f.limit-r,f.cursor>f.limit_backward&&(f.cursor--,f.bra=f.cursor,f.slice_del())):f.limit_backward=e)}function s(){var e,r,i,n=f.limit-f.cursor;if(f.ket=f.cursor,f.eq_s_b(2,"st")&&(f.bra=f.cursor,f.eq_s_b(2,"ig")&&f.slice_del()),f.cursor=f.limit-n,f.cursor>=d&&(r=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,e=f.find_among_b(m,5),f.limit_backward=r,e))switch(f.bra=f.cursor,e){case 1:f.slice_del(),i=f.limit-f.cursor,t(),f.cursor=f.limit-i;break;case 2:f.slice_from("løs")}}function o(){var e;f.cursor>=d&&(e=f.limit_backward,f.limit_backward=d,f.ket=f.cursor,f.out_grouping_b(w,97,248)?(f.bra=f.cursor,u=f.slice_to(u),f.limit_backward=e,f.eq_v_b(u)&&f.slice_del()):f.limit_backward=e)}var a,d,u,c=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],l=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],m=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],w=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],p=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],f=new i;this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var r=f.cursor;return e(),f.limit_backward=r,f.cursor=f.limit,n(),f.cursor=f.limit,t(),f.cursor=f.limit,s(),f.cursor=f.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}}(),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.no.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Lunr languages, `Norwegian` language 3 | * https://github.com/MihaiValentin/lunr-languages 4 | * 5 | * Copyright 2014, Mihai Valentin 6 | * http://www.mozilla.org/MPL/ 7 | */ 8 | /*! 9 | * based on 10 | * Snowball JavaScript Library v0.3 11 | * http://code.google.com/p/urim/ 12 | * http://snowball.tartarus.org/ 13 | * 14 | * Copyright 2010, Oleg Mazko 15 | * http://www.mozilla.org/MPL/ 16 | */ 17 | 18 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=function(){var r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){function e(){var e,r=w.cursor+3;if(a=w.limit,0<=r||r<=w.limit){for(s=r;;){if(e=w.cursor,w.in_grouping(d,97,248)){w.cursor=e;break}if(e>=w.limit)return;w.cursor=e+1}for(;!w.out_grouping(d,97,248);){if(w.cursor>=w.limit)return;w.cursor++}a=w.cursor,a=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(m,29),w.limit_backward=r,e))switch(w.bra=w.cursor,e){case 1:w.slice_del();break;case 2:n=w.limit-w.cursor,w.in_grouping_b(c,98,122)?w.slice_del():(w.cursor=w.limit-n,w.eq_s_b(1,"k")&&w.out_grouping_b(d,97,248)&&w.slice_del());break;case 3:w.slice_from("er")}}function t(){var e,r=w.limit-w.cursor;w.cursor>=a&&(e=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,w.find_among_b(u,2)?(w.bra=w.cursor,w.limit_backward=e,w.cursor=w.limit-r,w.cursor>w.limit_backward&&(w.cursor--,w.bra=w.cursor,w.slice_del())):w.limit_backward=e)}function o(){var e,r;w.cursor>=a&&(r=w.limit_backward,w.limit_backward=a,w.ket=w.cursor,e=w.find_among_b(l,11),e?(w.bra=w.cursor,w.limit_backward=r,1==e&&w.slice_del()):w.limit_backward=r)}var s,a,m=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],u=[new r("dt",-1,-1),new r("vt",-1,-1)],l=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],c=[119,125,149,1],w=new n;this.setCurrent=function(e){w.setCurrent(e)},this.getCurrent=function(){return w.getCurrent()},this.stem=function(){var r=w.cursor;return e(),w.limit_backward=r,w.cursor=w.limit,i(),w.cursor=w.limit,t(),w.cursor=w.limit,o(),!0}};return function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}}(),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); -------------------------------------------------------------------------------- /docs/site/assets/javascripts/lunr/min/lunr.he.min.js: -------------------------------------------------------------------------------- 1 | !function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");e.he=function(){this.pipeline.reset(),this.pipeline.add(e.he.trimmer,e.he.stopWordFilter,e.he.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.he.stemmer))},e.he.wordCharacters="֑-״א-תa-zA-Za-zA-Z0-90-9",e.he.trimmer=e.trimmerSupport.generateTrimmer(e.he.wordCharacters),e.Pipeline.registerFunction(e.he.trimmer,"trimmer-he"),e.he.stemmer=function(){var e=this;return e.result=!1,e.preRemoved=!1,e.sufRemoved=!1,e.pre={pre1:"ה ו י ת",pre2:"ב כ ל מ ש כש",pre3:"הב הכ הל המ הש בש לכ",pre4:"וב וכ ול ומ וש",pre5:"מה שה כל",pre6:"מב מכ מל ממ מש",pre7:"בה בו בי בת כה כו כי כת לה לו לי לת",pre8:"ובה ובו ובי ובת וכה וכו וכי וכת ולה ולו ולי ולת"},e.suf={suf1:"ך כ ם ן נ",suf2:"ים ות וך וכ ום ון ונ הם הן יכ יך ינ ים",suf3:"תי תך תכ תם תן תנ",suf4:"ותי ותך ותכ ותם ותן ותנ",suf5:"נו כם כן הם הן",suf6:"ונו וכם וכן והם והן",suf7:"תכם תכן תנו תהם תהן",suf8:"הוא היא הם הן אני אתה את אנו אתם אתן",suf9:"ני נו כי כו כם כן תי תך תכ תם תן",suf10:"י ך כ ם ן נ ת"},e.patterns=JSON.parse('{"hebrewPatterns": [{"pt1": [{"c": "ה", "l": 0}]}, {"pt2": [{"c": "ו", "l": 0}]}, {"pt3": [{"c": "י", "l": 0}]}, {"pt4": [{"c": "ת", "l": 0}]}, {"pt5": [{"c": "מ", "l": 0}]}, {"pt6": [{"c": "ל", "l": 0}]}, {"pt7": [{"c": "ב", "l": 0}]}, {"pt8": [{"c": "כ", "l": 0}]}, {"pt9": [{"c": "ש", "l": 0}]}, {"pt10": [{"c": "כש", "l": 0}]}, {"pt11": [{"c": "בה", "l": 0}]}, {"pt12": [{"c": "וב", "l": 0}]}, {"pt13": [{"c": "וכ", "l": 0}]}, {"pt14": [{"c": "ול", "l": 0}]}, {"pt15": [{"c": "ומ", "l": 0}]}, {"pt16": [{"c": "וש", "l": 0}]}, {"pt17": [{"c": "הב", "l": 0}]}, {"pt18": [{"c": "הכ", "l": 0}]}, {"pt19": [{"c": "הל", "l": 0}]}, {"pt20": [{"c": "המ", "l": 0}]}, {"pt21": [{"c": "הש", "l": 0}]}, {"pt22": [{"c": "מה", "l": 0}]}, {"pt23": [{"c": "שה", "l": 0}]}, {"pt24": [{"c": "כל", "l": 0}]}]}'),e.execArray=["cleanWord","removeDiacritics","removeStopWords","normalizeHebrewCharacters"],e.stem=function(){var r=0;for(e.result=!1,e.preRemoved=!1,e.sufRemoved=!1;r=0)return!0},e.normalizeHebrewCharacters=function(){return e.word=e.word.replace("ך","כ"),e.word=e.word.replace("ם","מ"),e.word=e.word.replace("ן","נ"),e.word=e.word.replace("ף","פ"),e.word=e.word.replace("ץ","צ"),!1},function(r){return"function"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}}(),e.Pipeline.registerFunction(e.he.stemmer,"stemmer-he"),e.he.stopWordFilter=e.generateStopWordFilter("אבל או אולי אותו אותי אותך אותם אותן אותנו אז אחר אחרות אחרי אחריכן אחרים אחרת אי איזה איך אין איפה אל אלה אלו אם אנחנו אני אף אפשר את אתה אתכם אתכן אתם אתן באיזה באיזו בגלל בין בלבד בעבור בעזרת בכל בכן בלי במידה במקום שבו ברוב בשביל בשעה ש בתוך גם דרך הוא היא היה היי היכן היתה היתי הם הן הנה הסיבה שבגללה הרי ואילו ואת זאת זה זות יהיה יוכל יוכלו יותר מדי יכול יכולה יכולות יכולים יכל יכלה יכלו יש כאן כאשר כולם כולן כזה כי כיצד כך כל כלל כמו כן כפי כש לא לאו לאיזותך לאן לבין לה להיות להם להן לו לזה לזות לי לך לכם לכן למה למעלה למעלה מ למטה למטה מ למעט למקום שבו למרות לנו לעבר לעיכן לפיכך לפני מאד מאחורי מאיזו סיבה מאין מאיפה מבלי מבעד מדוע מה מהיכן מול מחוץ מי מידע מכאן מכל מכן מלבד מן מנין מסוגל מעט מעטים מעל מצד מקום בו מתחת מתי נגד נגר נו עד עז על עלי עליו עליה עליהם עליך עלינו עם עצמה עצמהם עצמהן עצמו עצמי עצמם עצמן עצמנו פה רק שוב של שלה שלהם שלהן שלו שלי שלך שלכה שלכם שלכן שלנו שם תהיה תחת".split(" ")),e.Pipeline.registerFunction(e.he.stopWordFilter,"stopWordFilter-he")}}); -------------------------------------------------------------------------------- /coinmetrics/schema_resolver.py: -------------------------------------------------------------------------------- 1 | from typing import Any, Dict 2 | from ._schema_constants import OPENAPI_SCHEMA 3 | 4 | # Map endpoints to their schema names 5 | ENDPOINT_SCHEMA_MAP = { 6 | "timeseries/market-trades": "MarketTrade", 7 | "timeseries/market-candles": "MarketCandle", 8 | "timeseries/market-liquidations": "MarketLiquidation", 9 | "timeseries/market-orderbooks": "MarketOrderBook", 10 | "timeseries/market-quotes": "MarketQuote", 11 | "timeseries/market-funding-rates": "MarketFundingRate", 12 | "timeseries/market-funding-rates-predicted": "MarketFundingRatePredicted", 13 | "timeseries/market-openinterest": "MarketOpenInterest", 14 | "timeseries/market-contract-prices": "MarketContractPrices", 15 | "timeseries/market-implied-volatility": "MarketImpliedVolatility", 16 | "timeseries/market-greeks": "MarketGreeks", 17 | "timeseries/pair-candles": "PairCandle", 18 | "timeseries/index-candles": "IndexCandle", 19 | "blockchain-v2/{asset}/balance-updates": "BlockchainBalanceUpdateV2", 20 | "blockchain-v2/{asset}/blocks/{block_hash}": "BlockchainBlockInfoV2", 21 | "blockchain-v2/{asset}/blocks/{block_hash}/transactions/{txid}": "BlockchainFullSingleTransactionResponseV2", 22 | "blockchain-v2/{asset}/transactions/{txid}": "BlockchainFullSingleTransactionResponseV2" 23 | } 24 | 25 | # If mapping between field and type from schemas is suboptimal, override them here 26 | FIELD_TYPE_EXCEPTIONS = { 27 | "bids": "object", 28 | "asks": "object", 29 | "transactions": "object", 30 | "balance_updates": "object", 31 | "sub_accounts": "object", 32 | } 33 | 34 | 35 | def get_schema_for_endpoint(endpoint: str) -> str: 36 | """ 37 | Get the schema name to use for resolving fields based on the API endpoint. 38 | 39 | Args: 40 | endpoint: The API endpoint path 41 | 42 | Returns: 43 | The schema name to use for field resolution 44 | """ 45 | # Get schema name from map, default to None if not found 46 | schema_name = ENDPOINT_SCHEMA_MAP.get(endpoint) 47 | 48 | if not schema_name: 49 | raise ValueError(f"No schema mapping found for endpoint: {endpoint}") 50 | 51 | return schema_name 52 | 53 | 54 | def resolve_schema_field( 55 | prop: Dict[Any, Any], 56 | root: Dict[Any, Any] = OPENAPI_SCHEMA, 57 | prefix: str = '' 58 | ) -> Any: 59 | """Resolve $ref or inline type/description for a schema property.""" 60 | if '$ref' in prop: 61 | ref_path = prop['$ref'].lstrip('#/').split('/') 62 | ref_obj = root 63 | for part in ref_path: 64 | ref_obj = ref_obj[part] 65 | 66 | # Handle allOf composition 67 | if 'allOf' in ref_obj: 68 | nested_fields = {} 69 | for part in ref_obj['allOf']: 70 | nested_fields.update(resolve_schema_field(part, root, prefix)) 71 | return nested_fields 72 | 73 | # Handle nested properties if this is a referenced object 74 | if 'properties' in ref_obj: 75 | nested_fields = {} 76 | for name, nested_prop in ref_obj['properties'].items(): 77 | nested_name = f"{prefix}_{name}" if prefix else name 78 | nested_fields[nested_name] = resolve_schema_field(nested_prop, root, nested_name) 79 | return nested_fields 80 | 81 | return resolve_schema_field(ref_obj, root, prefix) 82 | 83 | # Handle allOf composition directly in property 84 | if 'allOf' in prop: 85 | nested_fields = {} 86 | for part in prop['allOf']: 87 | nested_fields.update(resolve_schema_field(part, root, prefix)) 88 | return nested_fields 89 | 90 | # For non-ref properties that might have nested properties 91 | if 'properties' in prop: 92 | nested_fields = {} 93 | for name, nested_prop in prop['properties'].items(): 94 | nested_name = f"{prefix}_{name}" if prefix else name 95 | nested_fields[nested_name] = resolve_schema_field(nested_prop, root, nested_name) 96 | return nested_fields 97 | 98 | # For array types 99 | if 'items' in prop: 100 | if '$ref' in prop['items']: 101 | return resolve_schema_field(prop['items'], root, prefix) 102 | return resolve_schema_field(prop['items'], root, prefix) 103 | 104 | return prop.get('type', 'object') 105 | 106 | 107 | def get_schema_fields( 108 | schema_name: str, 109 | openapi_schema: Dict[Any, Any] = OPENAPI_SCHEMA 110 | ) -> Dict[str, str]: 111 | """Get all fields from a schema with flattened field names.""" 112 | schema = openapi_schema['components']['schemas'][schema_name] 113 | field_type_map = {} 114 | 115 | # Handle allOf at schema level 116 | if 'allOf' in schema: 117 | for part in schema['allOf']: 118 | fields = resolve_schema_field(part, openapi_schema) 119 | field_type_map.update(fields) 120 | return field_type_map 121 | 122 | # Handle properties at schema level 123 | if 'properties' in schema: 124 | for name, prop in schema['properties'].items(): 125 | field_type_map[name] = resolve_schema_field(prop, openapi_schema, name) 126 | 127 | field_type_map.update(FIELD_TYPE_EXCEPTIONS) 128 | return field_type_map 129 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: docker:${CM_DOCKER_IMAGE_VERSION} 2 | 3 | .check-for-changes: &check-for-changes | 4 | DOCUMENTATION_ERROR_MESSAGE="Failing pipeline build because changes were made to the API Client without generating new documentation" 5 | DOCUMENTATION_SUCCESS_MESSAGE="Documentation properly generated" 6 | lines=$(git status --untracked-files no -s | wc -l) #ignoring changes to these files 7 | if [ $lines -gt 0 ]; then 8 | echo $DOCUMENTATION_ERROR_MESSAGE && echo "git status output:" && git status && exit 1; 9 | else 10 | echo $DOCUMENTATION_SUCCESS_MESSAGE; 11 | fi 12 | 13 | services: 14 | - docker:${CM_DOCKER_IMAGE_VERSION}-dind 15 | 16 | stages: 17 | - build-test-push-image 18 | - generate-docs 19 | - deploy 20 | 21 | variables: 22 | # GIT_SUBMODULE_STRATEGY: recursive 23 | PYPI_PASSWORD: $PYPI_PASSWORD 24 | PYPI_USERNAME: $PYPI_USERNAME 25 | 26 | build-test-push-image: 27 | stage: build-test-push-image 28 | script: 29 | - mkdir -p ~/.docker && echo $DOCKER_AUTH_CONFIG > ~/.docker/config.json && unset DOCKER_AUTH_CONFIG 30 | - apk add git 31 | - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME || true 32 | - 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 . 33 | - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python -m mypy -p coinmetrics -p test --install-types --non-interactive 34 | - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python -m flake8 coinmetrics 35 | - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python -m pytest -n auto --timeout=60 test --ignore test/test_rate_limits.py --ignore test/test_catalog.py --ignore test/test_speed_benchmarks.py 36 | - echo ${CI_REGISTRY_PASSWORD} | docker login ${CI_REGISTRY} -u ${CI_REGISTRY_USER} --password-stdin 37 | - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA 38 | - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME 39 | tags: 40 | - svc-docker 41 | 42 | build-nix: 43 | image: docker.io/coinmetrics/nix-builder:latest 44 | stage: build-test-push-image 45 | variables: 46 | KUBERNETES_CPU_REQUEST: "16" 47 | KUBERNETES_CPU_LIMIT: "16" 48 | KUBERNETES_MEMORY_REQUEST: "24Gi" 49 | KUBERNETES_MEMORY_LIMIT: "24Gi" 50 | script: 51 | - nix -L build .#coinmetrics-api-client-py312 52 | - nix -L build .#coinmetrics-api-client-py311 53 | - nix -L build .#coinmetrics-api-client-py310 54 | allow_failure: true 55 | before_script: 56 | - source /before-script.sh 57 | after_script: 58 | - /after-script.sh 59 | tags: 60 | - rt-containerd 61 | timeout: 8 hours 62 | 63 | generate-docs: 64 | image: python:3.11-slim 65 | stage: generate-docs 66 | tags: 67 | - rt-runc 68 | before_script: 69 | # Git set up 70 | - apt-get update && apt-get install -y git ssh 71 | - eval $(ssh-agent -s) 72 | - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - 73 | - mkdir -p ~/.ssh 74 | - chmod 700 ~/.ssh 75 | - ssh-keyscan gitlab.com >> ~/.ssh/known_hosts 76 | - chmod 644 ~/.ssh/known_hosts 77 | - git config --global user.email "noreply@coinmetrics.io" 78 | - git config --global user.name "Release Bot" 79 | - git fetch 80 | # Python build 81 | - python -m venv .venv 82 | - source .venv/bin/activate 83 | - python -m pip install --upgrade pip 84 | - python -m pip install poetry 85 | - poetry install --with dev 86 | script: 87 | - git checkout -b $CI_COMMIT_REF_NAME-$RANDOM origin/$CI_COMMIT_REF_NAME 88 | - url_host=$(echo "${CI_REPOSITORY_URL}" | sed -e 's|https\?://gitlab-ci-token:.*@|ssh://git@|g') 89 | - echo "${url_host}" 90 | - git remote set-url --push origin "${url_host}" 91 | - git remote show origin 92 | - cd $CI_PROJECT_DIR 93 | - export UPDATE_VERSION=`python get_utc_update_time.py` 94 | - echo "update version:" 95 | - echo $UPDATE_VERSION 96 | - bash update_version.sh $UPDATE_VERSION 97 | - python coinmetrics/build.py # Generate schema constants for documentation build 98 | - export PYTHONPATH=/ && pydoc-markdown -m coinmetrics.api_client > docs/docs/reference/api_client.md 99 | - cp -f README.md docs/docs/index.md 100 | - cp -f CHANGELOG.md docs/docs/releases/CHANGELOG.md 101 | - cp -f examples/README.md docs/docs/user-guide/examples.md 102 | - cd docs && mkdocs build 103 | - git add --all -- :!api-client-python/ 104 | - git status 105 | - git commit -m "Release version $UPDATE_VERSION" || echo "No changes, nothing to commit!" 106 | - git push --follow-tags origin HEAD:$CI_COMMIT_REF_NAME 107 | when: manual 108 | # rules: 109 | # - if: $CI_COMMIT_BRANCH == "master" 110 | 111 | deploy: 112 | stage: deploy 113 | dependencies: 114 | - generate-docs 115 | - build-test-push-image 116 | script: 117 | - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME || true 118 | - 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 PYPI_USERNAME=$PYPI_USERNAME --build-arg PYPI_PASSWORD=$PYPI_PASSWORD 119 | - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python coinmetrics/build.py 120 | - docker run $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA python -m poetry publish --build --username $PYPI_USERNAME --password $PYPI_PASSWORD 121 | tags: 122 | - svc-docker 123 | when: manual 124 | rules: 125 | - if: $CI_COMMIT_BRANCH == "master" 126 | -------------------------------------------------------------------------------- /coinmetrics/build.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Build script to preprocess OpenAPI schema at build time instead of runtime. 4 | Only extracts the minimal schema components needed by the application. 5 | """ 6 | 7 | import yaml 8 | from pathlib import Path 9 | from typing import Any, Dict, Set, Optional 10 | 11 | 12 | # Schema names that are actually used by the application 13 | REQUIRED_SCHEMAS = { 14 | "MarketTrade", 15 | "MarketCandle", 16 | "MarketLiquidation", 17 | "MarketOrderBook", 18 | "MarketQuote", 19 | "MarketFundingRate", 20 | "MarketFundingRatePredicted", 21 | "MarketOpenInterest", 22 | "MarketContractPrices", 23 | "MarketImpliedVolatility", 24 | "MarketGreeks", 25 | "PairCandle", 26 | "IndexCandle", 27 | "BlockchainBalanceUpdateV2", 28 | "BlockchainBlockInfoV2", 29 | "BlockchainFullSingleTransactionResponseV2", 30 | "BlockchainFullBlockResponseV2", 31 | "TaxonomyAsset", 32 | "TaxonomyMetadataAsset", 33 | } 34 | 35 | 36 | def load_openapi_schema() -> Any: 37 | """Load and parse the OpenAPI YAML file.""" 38 | openapi_path = Path(__file__).parent.parent / "openapi.yaml" 39 | if not openapi_path.exists(): 40 | raise FileNotFoundError(f"OpenAPI YAML file not found at {openapi_path}") 41 | with open(openapi_path) as stream: 42 | return yaml.safe_load(stream) 43 | 44 | 45 | def extract_referenced_schemas(schema: Dict[str, Any], all_schemas: Dict[str, Any], visited: Optional[Set[str]] = None) -> Set[str]: 46 | """Recursively extract all schema names referenced by a given schema.""" 47 | if visited is None: 48 | visited = set() 49 | 50 | referenced = set() 51 | 52 | def extract_refs(obj: Any) -> None: 53 | if isinstance(obj, dict): 54 | if '$ref' in obj: 55 | ref_path = obj['$ref'] 56 | if ref_path.startswith('#/components/schemas/'): 57 | schema_name = ref_path.split('/')[-1] 58 | if schema_name not in visited: 59 | visited.add(schema_name) 60 | referenced.add(schema_name) 61 | if schema_name in all_schemas: 62 | referenced.update(extract_referenced_schemas( 63 | all_schemas[schema_name], all_schemas, visited 64 | )) 65 | else: 66 | for value in obj.values(): 67 | extract_refs(value) 68 | elif isinstance(obj, list): 69 | for item in obj: 70 | extract_refs(item) 71 | 72 | extract_refs(schema) 73 | return referenced 74 | 75 | 76 | def extract_minimal_schema_components(openapi_data: Dict[str, Any]) -> Dict[str, Any]: 77 | """Extract only the schema components that are actually used.""" 78 | if 'components' not in openapi_data or 'schemas' not in openapi_data['components']: 79 | return {"components": {"schemas": {}}} 80 | 81 | all_schemas = openapi_data['components']['schemas'] 82 | minimal_schemas = {} 83 | all_required = set(REQUIRED_SCHEMAS) 84 | 85 | # Find all schemas referenced by our required schemas 86 | for schema_name in REQUIRED_SCHEMAS: 87 | if schema_name in all_schemas: 88 | minimal_schemas[schema_name] = all_schemas[schema_name] 89 | # Add any schemas this schema references 90 | referenced = extract_referenced_schemas(all_schemas[schema_name], all_schemas) 91 | all_required.update(referenced) 92 | 93 | # Add all referenced schemas to minimal set 94 | for schema_name in all_required: 95 | if schema_name in all_schemas: 96 | minimal_schemas[schema_name] = all_schemas[schema_name] 97 | 98 | return { 99 | "components": { 100 | "schemas": minimal_schemas 101 | } 102 | } 103 | 104 | 105 | def generate_schema_constants(minimal_schema_data: Dict[str, Any]) -> str: 106 | """Generate Python code with the minimal OpenAPI schema as a constant.""" 107 | 108 | # Convert to a Python repr string to avoid JSON parsing issues 109 | schema_repr = repr(minimal_schema_data) 110 | 111 | return f'''""" 112 | Auto-generated minimal schema constants from OpenAPI YAML. 113 | DO NOT EDIT THIS FILE DIRECTLY - it is generated by build.py 114 | 115 | This file contains only the schema components needed by the application, 116 | extracted from the full OpenAPI specification for faster loading. 117 | """ 118 | 119 | from typing import Any, Dict 120 | 121 | # Minimal OpenAPI schema components loaded at build time 122 | OPENAPI_SCHEMA: Dict[str, Any] = {schema_repr} 123 | ''' 124 | 125 | 126 | def main() -> None: 127 | """Main build function.""" 128 | print("Loading OpenAPI schema...") 129 | openapi_data = load_openapi_schema() 130 | 131 | print("Extracting minimal schema components...") 132 | minimal_schema_data = extract_minimal_schema_components(openapi_data) 133 | 134 | original_count = len(openapi_data.get('components', {}).get('schemas', {})) 135 | minimal_count = len(minimal_schema_data['components']['schemas']) 136 | print(f"Reduced from {original_count} to {minimal_count} schemas ({minimal_count/original_count*100:.1f}% of original)") 137 | 138 | print("Generating schema constants...") 139 | schema_code = generate_schema_constants(minimal_schema_data) 140 | 141 | # Write the generated constants to a new file 142 | output_path = Path(__file__).parent / "_schema_constants.py" 143 | with open(output_path, 'w') as f: 144 | f.write(schema_code) 145 | 146 | print(f"Generated minimal schema constants in {output_path}") 147 | 148 | 149 | if __name__ == "__main__": 150 | main() 151 | --------------------------------------------------------------------------------