# Cryptowatch Python SDK
The Cryptowatch Python library provides a convenient access to the [Cryptowatch API](https://docs.cryptowat.ch/home/) from applications written in the Python language.
It includes the following features:
* Auto-serialization of API responses into Python objects
* Websocket client with transparent handling of protobuf messages
* API credentials automatically read from your `~/.cw/credentials.yml` config file
* Custom exceptions for API-specific issues (e.g.: Requests Allowance)
* Smart back-off retries in case of API connectivity loss
## Installation
```
pip install cryptowatch-sdk
```
#### Note:
The [`cryptowatch` library](https://pypi.org/project/cryptowatch/) is **not** related with [Cryptowatch](https://cryptowat.ch/). If you installed it by mistake run `pip uninstall cryptowatch` to remove it.
The correct library name is `cryptowatch-sdk`.
## Example
Showing all Kraken markets that already gained at least 5% over the current weekly candle.
```python
import cryptowatch as cw
from datetime import datetime, timedelta
# Get all Kraken markets
kraken = cw.markets.list("kraken")
# For each Kraken market...
for market in kraken.markets:
# Forge current market ticker, like KRAKEN:BTCUSD
ticker = "{}:{}".format(market.exchange, market.pair).upper()
# Request weekly candles for that market
candles = cw.markets.get(ticker, ohlc=True, periods=["1w"])
# Each candle is a list of [close_timestamp, open, high, low, close, volume, volume_quote]
# Get close_timestamp, open and close from the most recent weekly candle
close_ts, wkly_open, wkly_close = (
candles.of_1w[-1][0],
candles.of_1w[-1][1],
candles.of_1w[-1][4],
)
# Compute market performance, skip if open was 0
if wkly_open == 0:
continue
perf = (wkly_open - wkly_close) * 100 / wkly_open
# If the market performance was 5% or more, print it
if perf >= 5:
open_ts = datetime.utcfromtimestamp(close_ts) - timedelta(days=7)
print("{} gained {:.2f}% since {}".format(ticker, perf, open_ts))
```
### Requirements
* python v3.7+
* requests v0.8.8+
* marshmallow v3.2.2+
* pyyaml v5.1.2+
* websocket-client v0.56+
* protobuf v3.11.3+
## API Crendential
Using a credential file will allow you to authenticate your requests and grant you the API access of your Cryptowatch account.
Your account Credits will be consumed for the REST and WebSocket API. Specific Credit cost details can be found on the [Pricing page](https://cryptowat.ch/pricing).
### Setup your credential file
1. Generate an Cryptowatch API key from [your account](https://cryptowat.ch/account/api-access)
2. Create your credential file on your machine by running in order:
2.1 `mkdir $HOME/.cw`
2.2 `echo "apikey: 123" > $HOME/.cw/credentials.yml` (where `123` is your 20 digits **public key**)
3. Verify with `cat $HOME/.cw/credentials.yml` that you see something like below (`123` being your public key):
```
apikey: 123
```
The SDK will read your public key as soon as `import cryptowatch` is ran in your script.
## Usage
### REST API
```python
import cryptowatch as cw
# Set your API Key, it is by default read from your ~/.cw/credentials.yml file
cw.api_key = "123"
# Assets
cw.assets.list()
cw.assets.get("BTC")
# Exchanges
cw.exchanges.list()
cw.exchanges.get("KRAKEN")
# Instruments
cw.instruments.list()
cw.instruments.get("BTCUSD")
# Markets
cw.markets.list() # Returns list of all markets on all exchanges
cw.markets.list("BINANCE") # Returns all markets on Binance
# Returns market summary (last, high, low, change, volume)
cw.markets.get("KRAKEN:BTCUSD")
# Return market candlestick info (open, high, low, close, volume) on some timeframes
cw.markets.get("KRAKEN:BTCUSD", ohlc=True, periods=["4h", "1h", "1d"])
# Returns market last trades
cw.markets.get("KRAKEN:BTCUSD", trades=True)
# Return market current orderbook
cw.markets.get("KRAKEN:BTCUSD", orderbook=True)
# Return market current orderbook liquidity
cw.markets.get("KRAKEN:BTCUSD", liquidity=True)
```
You can access the raw HTTP response received via the `_http_response` attribute which is a [`requests.Response`](https://requests.readthedocs.io/en/stable/api/#requests.Response) object:
```python
import cryptowatch as cw
bitcoin = cw.assets.get('btc')
print(bitcoin._http_response)
```
### Websocket
```python
import cryptowatch as cw
# Set your API Key
cw.api_key = "123"
# Subscribe to resources (https://docs.cryptowat.ch/websocket-api/data-subscriptions#resources)
cw.stream.subscriptions = ["markets:*:trades"]
# What to do on each trade update
def handle_trades_update(trade_update):
"""
trade_update follows Cryptowatch protocol buffer format:
https://github.com/cryptowatch/proto/blob/master/public/markets/market.proto
"""
market_msg = ">>> Market#{} Exchange#{} Pair#{}: {} New Trades".format(
trade_update.marketUpdate.market.marketId,
trade_update.marketUpdate.market.exchangeId,
trade_update.marketUpdate.market.currencyPairId,
len(trade_update.marketUpdate.tradesUpdate.trades),
)
print(market_msg)
for trade in trade_update.marketUpdate.tradesUpdate.trades:
trade_msg = "\tID:{} TIMESTAMP:{} TIMESTAMPNANO:{} PRICE:{} AMOUNT:{}".format(
trade.externalId,
trade.timestamp,
trade.timestampNano,
trade.priceStr,
trade.amountStr,
)
print(trade_msg)
cw.stream.on_trades_update = handle_trades_update
# Start receiving
cw.stream.connect()
# Call disconnect to close the stream connection
# cw.stream.disconnect()
```
See [this script](https://github.com/cryptowatch/cw-sdk-python/tree/master/examples/stream_example.py) for more streaming example.
#### Converting protobuf messages to JSON
If you need to convert the protobuf message to JSON, you can do so with `MessageToJson`. See the example below:
```python
from google.protobuf.json_format import MessageToJson
import cryptowatch as cw
# Set your API Key
cw.api_key = "123"
# Subscribe to resources (https://docs.cryptowat.ch/websocket-api/data-subscriptions#resources)
cw.stream.subscriptions = ["markets:*:trades"]
# What to do on each trade update
def handle_trades_update(trade_update):
"""
trade_update follows Cryptowatch protocol buffer format:
https://github.com/cryptowatch/proto/blob/master/public/markets/market.proto
"""
MessageToJson(trade_update)
cw.stream.on_trades_update = handle_trades_update
# Start receiving
cw.stream.connect()
```
### Logging
Logging can be enabled through Python's `logging` module:
```python
import logging
logging.basicConfig()
logging.getLogger("cryptowatch").setLevel(logging.DEBUG)
```
### CLI
The library exposes a simple utility, named `cryptowatch`, to return last market prices.
#### By default it returns Kraken's BTCUSD market
```
> cryptowatch
7425.0
```
#### Add another Kraken market to return this market last price
```
> cryptowatch btceur
6758.1
```
#### You can also specify your own exchange
```
> cryptowatch binance:ethbtc
0.020359
```
When the market doesn't exist a return code of `1` will be set (`0` otherwise):
```
> cryptowatch binance:nosuchmarketusd
> echo $?
1
```
## Testing
Unit tests are under the [tests](https://github.com/cryptowatch/cw-sdk-python/tree/master/tests) folder and use `pytest`, run them all with:
```
make test
```
Integration tests sending real HTTP requests to the Cryptowatch API can be run with:
```
make test-http-real
```
## Development
Testing and developement dependencies are in the [requirements.txt](https://github.com/cryptowatch/cw-sdk-python/tree/master/requirements.txt) file, install them with:
```
pip install -r requirements.txt
```
The code base use the [Black](https://black.readthedocs.io/en/stable/) linter, run it with:
```
make lint
```
## License
[BSD-2-Clause](https://github.com/cryptowatch/cw-sdk-python/tree/master/LICENSE)
Raw data
{
"_id": null,
"home_page": "https://github.com/cryptowatch/cw-sdk-python",
"name": "cryptowatch-sdk",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "cryptowatch sdk bitcoin crypto",
"author": "Cryptowatch",
"author_email": "infra@cryptowat.ch",
"download_url": "https://files.pythonhosted.org/packages/98/7d/5a8aaf2155327a19dca9e729110323308e808fcaa6e5c2e8371d388a00af/cryptowatch-sdk-0.1.0.tar.gz",
"platform": null,
"description": "# Cryptowatch Python SDK\n\nThe Cryptowatch Python library provides a convenient access to the [Cryptowatch API](https://docs.cryptowat.ch/home/) from applications written in the Python language.\n\nIt includes the following features:\n * Auto-serialization of API responses into Python objects\n * Websocket client with transparent handling of protobuf messages\n * API credentials automatically read from your `~/.cw/credentials.yml` config file\n * Custom exceptions for API-specific issues (e.g.: Requests Allowance)\n * Smart back-off retries in case of API connectivity loss\n\n## Installation\n```\npip install cryptowatch-sdk\n```\n\n#### Note:\n\nThe [`cryptowatch` library](https://pypi.org/project/cryptowatch/) is **not** related with [Cryptowatch](https://cryptowat.ch/). If you installed it by mistake run `pip uninstall cryptowatch` to remove it.\n\nThe correct library name is `cryptowatch-sdk`.\n\n## Example\n\nShowing all Kraken markets that already gained at least 5% over the current weekly candle.\n\n```python\nimport cryptowatch as cw\nfrom datetime import datetime, timedelta\n\n# Get all Kraken markets\nkraken = cw.markets.list(\"kraken\")\n\n# For each Kraken market...\nfor market in kraken.markets:\n\n # Forge current market ticker, like KRAKEN:BTCUSD\n ticker = \"{}:{}\".format(market.exchange, market.pair).upper()\n # Request weekly candles for that market\n candles = cw.markets.get(ticker, ohlc=True, periods=[\"1w\"])\n\n # Each candle is a list of [close_timestamp, open, high, low, close, volume, volume_quote]\n # Get close_timestamp, open and close from the most recent weekly candle\n close_ts, wkly_open, wkly_close = (\n candles.of_1w[-1][0],\n candles.of_1w[-1][1],\n candles.of_1w[-1][4],\n )\n\n # Compute market performance, skip if open was 0\n if wkly_open == 0:\n continue\n perf = (wkly_open - wkly_close) * 100 / wkly_open\n\n # If the market performance was 5% or more, print it\n if perf >= 5:\n open_ts = datetime.utcfromtimestamp(close_ts) - timedelta(days=7)\n print(\"{} gained {:.2f}% since {}\".format(ticker, perf, open_ts))\n```\n\n\n### Requirements\n\n* python v3.7+\n* requests v0.8.8+\n* marshmallow v3.2.2+\n* pyyaml v5.1.2+\n* websocket-client v0.56+\n* protobuf v3.11.3+\n\n## API Crendential\n\nUsing a credential file will allow you to authenticate your requests and grant you the API access of your Cryptowatch account.\n\nYour account Credits will be consumed for the REST and WebSocket API. Specific Credit cost details can be found on the [Pricing page](https://cryptowat.ch/pricing).\n\n### Setup your credential file\n\n1. Generate an Cryptowatch API key from [your account](https://cryptowat.ch/account/api-access)\n2. Create your credential file on your machine by running in order:\n\n 2.1 `mkdir $HOME/.cw`\n\n 2.2 `echo \"apikey: 123\" > $HOME/.cw/credentials.yml` (where `123` is your 20 digits **public key**)\n\n3. Verify with `cat $HOME/.cw/credentials.yml` that you see something like below (`123` being your public key):\n\n```\napikey: 123\n```\n\nThe SDK will read your public key as soon as `import cryptowatch` is ran in your script.\n\n\n## Usage\n\n### REST API\n\n```python\nimport cryptowatch as cw\n\n# Set your API Key, it is by default read from your ~/.cw/credentials.yml file\ncw.api_key = \"123\"\n\n# Assets\ncw.assets.list()\ncw.assets.get(\"BTC\")\n\n# Exchanges\ncw.exchanges.list()\ncw.exchanges.get(\"KRAKEN\")\n\n# Instruments\ncw.instruments.list()\ncw.instruments.get(\"BTCUSD\")\n\n# Markets\ncw.markets.list() # Returns list of all markets on all exchanges\ncw.markets.list(\"BINANCE\") # Returns all markets on Binance\n\n# Returns market summary (last, high, low, change, volume)\ncw.markets.get(\"KRAKEN:BTCUSD\")\n# Return market candlestick info (open, high, low, close, volume) on some timeframes\ncw.markets.get(\"KRAKEN:BTCUSD\", ohlc=True, periods=[\"4h\", \"1h\", \"1d\"])\n\n# Returns market last trades\ncw.markets.get(\"KRAKEN:BTCUSD\", trades=True)\n\n# Return market current orderbook\ncw.markets.get(\"KRAKEN:BTCUSD\", orderbook=True)\n# Return market current orderbook liquidity\ncw.markets.get(\"KRAKEN:BTCUSD\", liquidity=True)\n```\n\nYou can access the raw HTTP response received via the `_http_response` attribute which is a [`requests.Response`](https://requests.readthedocs.io/en/stable/api/#requests.Response) object:\n\n\n```python\nimport cryptowatch as cw\n\nbitcoin = cw.assets.get('btc')\nprint(bitcoin._http_response)\n\n```\n\n### Websocket\n\n```python\nimport cryptowatch as cw\n\n# Set your API Key\ncw.api_key = \"123\"\n\n# Subscribe to resources (https://docs.cryptowat.ch/websocket-api/data-subscriptions#resources)\ncw.stream.subscriptions = [\"markets:*:trades\"]\n\n# What to do on each trade update\ndef handle_trades_update(trade_update):\n \"\"\"\n trade_update follows Cryptowatch protocol buffer format:\n https://github.com/cryptowatch/proto/blob/master/public/markets/market.proto\n \"\"\"\n market_msg = \">>> Market#{} Exchange#{} Pair#{}: {} New Trades\".format(\n trade_update.marketUpdate.market.marketId,\n trade_update.marketUpdate.market.exchangeId,\n trade_update.marketUpdate.market.currencyPairId,\n len(trade_update.marketUpdate.tradesUpdate.trades),\n )\n print(market_msg)\n for trade in trade_update.marketUpdate.tradesUpdate.trades:\n trade_msg = \"\\tID:{} TIMESTAMP:{} TIMESTAMPNANO:{} PRICE:{} AMOUNT:{}\".format(\n trade.externalId,\n trade.timestamp,\n trade.timestampNano,\n trade.priceStr,\n trade.amountStr,\n )\n print(trade_msg)\n\n\ncw.stream.on_trades_update = handle_trades_update\n\n\n# Start receiving\ncw.stream.connect()\n\n# Call disconnect to close the stream connection\n# cw.stream.disconnect()\n```\n\nSee [this script](https://github.com/cryptowatch/cw-sdk-python/tree/master/examples/stream_example.py) for more streaming example.\n\n\n#### Converting protobuf messages to JSON\n\nIf you need to convert the protobuf message to JSON, you can do so with `MessageToJson`. See the example below:\n\n```python\nfrom google.protobuf.json_format import MessageToJson\nimport cryptowatch as cw\n\n# Set your API Key\ncw.api_key = \"123\"\n\n# Subscribe to resources (https://docs.cryptowat.ch/websocket-api/data-subscriptions#resources)\ncw.stream.subscriptions = [\"markets:*:trades\"]\n\n# What to do on each trade update\ndef handle_trades_update(trade_update):\n \"\"\"\n trade_update follows Cryptowatch protocol buffer format:\n https://github.com/cryptowatch/proto/blob/master/public/markets/market.proto\n \"\"\"\n MessageToJson(trade_update)\n\ncw.stream.on_trades_update = handle_trades_update\n\n\n# Start receiving\ncw.stream.connect()\n```\n\n### Logging\n\nLogging can be enabled through Python's `logging` module:\n\n```python\nimport logging\n\nlogging.basicConfig()\nlogging.getLogger(\"cryptowatch\").setLevel(logging.DEBUG)\n```\n\n### CLI\n\nThe library exposes a simple utility, named `cryptowatch`, to return last market prices.\n\n\n#### By default it returns Kraken's BTCUSD market\n\n```\n> cryptowatch\n7425.0\n```\n\n#### Add another Kraken market to return this market last price\n\n```\n> cryptowatch btceur\n6758.1\n```\n\n#### You can also specify your own exchange\n\n```\n> cryptowatch binance:ethbtc\n0.020359\n```\n\nWhen the market doesn't exist a return code of `1` will be set (`0` otherwise):\n\n```\n> cryptowatch binance:nosuchmarketusd\n> echo $?\n1\n```\n\n\n\n## Testing\n\nUnit tests are under the [tests](https://github.com/cryptowatch/cw-sdk-python/tree/master/tests) folder and use `pytest`, run them all with:\n\n```\nmake test\n```\n\nIntegration tests sending real HTTP requests to the Cryptowatch API can be run with:\n\n```\nmake test-http-real\n```\n\n## Development\n\nTesting and developement dependencies are in the [requirements.txt](https://github.com/cryptowatch/cw-sdk-python/tree/master/requirements.txt) file, install them with:\n\n```\npip install -r requirements.txt\n```\n\nThe code base use the [Black](https://black.readthedocs.io/en/stable/) linter, run it with:\n\n```\nmake lint\n```\n\n## License\n\n[BSD-2-Clause](https://github.com/cryptowatch/cw-sdk-python/tree/master/LICENSE)\n",
"bugtrack_url": null,
"license": "BSD-2",
"summary": "Python bindings for the Cryptowatch API. Cryptocurrency markets, assets, instruments and exchanges data.",
"version": "0.1.0",
"split_keywords": [
"cryptowatch",
"sdk",
"bitcoin",
"crypto"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "0a699930b8c6dc489e39357fa1de4d48179620ebf3de2944ca33876f487a53af",
"md5": "8546d699f63fe8265bee6066bf3f2906",
"sha256": "f24184b187804355a7cfe06b0638e6042a9433a49029d7c71fc55057a3912834"
},
"downloads": -1,
"filename": "cryptowatch_sdk-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "8546d699f63fe8265bee6066bf3f2906",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 48112,
"upload_time": "2023-01-12T19:57:05",
"upload_time_iso_8601": "2023-01-12T19:57:05.521745Z",
"url": "https://files.pythonhosted.org/packages/0a/69/9930b8c6dc489e39357fa1de4d48179620ebf3de2944ca33876f487a53af/cryptowatch_sdk-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "987d5a8aaf2155327a19dca9e729110323308e808fcaa6e5c2e8371d388a00af",
"md5": "012bcb57d131a8d2e7fc94e7e7fc29f1",
"sha256": "f85e92ebd414ee3ba874b3a364a2cf94fe2ca274761e2ecd19169b00bd46265b"
},
"downloads": -1,
"filename": "cryptowatch-sdk-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "012bcb57d131a8d2e7fc94e7e7fc29f1",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 42303,
"upload_time": "2023-01-12T19:57:07",
"upload_time_iso_8601": "2023-01-12T19:57:07.064501Z",
"url": "https://files.pythonhosted.org/packages/98/7d/5a8aaf2155327a19dca9e729110323308e808fcaa6e5c2e8371d388a00af/cryptowatch-sdk-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-01-12 19:57:07",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "cryptowatch",
"github_project": "cw-sdk-python",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "cryptowatch-sdk"
}