Skip to content

Commit

Permalink
added API key to be passed as an environment variable
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrickAlphaC committed Jan 23, 2021
1 parent d94b9bc commit 8e51826
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 93 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ pip3 install cryptocompare
import cryptocompare
```

## API Key

If you have an API key, you can either set it as environment variable `CRYPTOCOMPARE_API_KEY` or set it manually with:

```
cryptocompare.cryptocompare._set_api_key_parameter(KEY_HERE)
```

### Coin List

```python
Expand Down Expand Up @@ -135,7 +143,7 @@ pairs = cryptocompare.get_pairs(exchange='Kraken')

## Developing

Install the dev dependencies and run the tests:
Tests run assuming you have an API key, otherwise they will error due to rate limiting. Install the dev dependencies and run the tests:
```sh
pip3 install -r requirements.txt
python3 -m pytest
Expand Down
20 changes: 16 additions & 4 deletions cryptocompare/cryptocompare.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import time
import datetime
import typing
import os
from typing import Union, Optional, List, Dict
Timestamp = Union[datetime.datetime, datetime.date, int, float]

# API
_URL_COIN_LIST = 'https://www.cryptocompare.com/api/data/coinlist/'
_API_KEY_PARAMETER = ""
_URL_COIN_LIST = 'https://www.cryptocompare.com/api/data/coinlist?'
_URL_PRICE = 'https://min-api.cryptocompare.com/data/pricemulti?fsyms={}&tsyms={}'
_URL_PRICE_MULTI = 'https://min-api.cryptocompare.com/data/pricemulti?fsyms={}&tsyms={}'
_URL_PRICE_MULTI_FULL = 'https://min-api.cryptocompare.com/data/pricemultifull?fsyms={}&tsyms={}'
Expand All @@ -18,7 +20,7 @@
_URL_HIST_PRICE_HOUR = 'https://min-api.cryptocompare.com/data/histohour?fsym={}&tsym={}&limit={}&e={}&toTs={}'
_URL_HIST_PRICE_MINUTE = 'https://min-api.cryptocompare.com/data/histominute?fsym={}&tsym={}&limit={}&e={}&toTs={}'
_URL_AVG = 'https://min-api.cryptocompare.com/data/generateAvg?fsym={}&tsym={}&e={}'
_URL_EXCHANGES = 'https://www.cryptocompare.com/api/data/exchanges'
_URL_EXCHANGES = 'https://www.cryptocompare.com/api/data/exchanges?'
_URL_PAIRS = 'https://min-api.cryptocompare.com/data/pair/mapping/exchange?e={}'

# DEFAULTS
Expand All @@ -27,16 +29,18 @@
###############################################################################


def _query_cryptocompare(url: str, errorCheck: bool = True) -> Optional[Dict]:
def _query_cryptocompare(url: str, errorCheck: bool = True, api_key: str = None) -> Optional[Dict]:
"""
Query the url and return the result or None on failure.
:param url: the url
:param errorCheck: run extra error checks (default: True)
:returns: respones, or nothing if errorCheck=True
:api_key: optional, if you want to add an API Key
"""
api_key_parameter = _set_api_key_parameter(api_key)
try:
response = requests.get(url).json()
response = requests.get(url + api_key_parameter).json()
except Exception as e:
print('Error getting coin information. %s' % str(e))
return None
Expand Down Expand Up @@ -72,6 +76,14 @@ def _format_timestamp(timestamp: Timestamp) -> int:
return int(timestamp)


def _set_api_key_parameter(api_key: str = None) -> str:
if api_key is None:
api_key = os.getenv('CRYPTOCOMPARE_API_KEY')
if api_key is not None:
_API_KEY = "&api_key={}".format(api_key)
return _API_KEY
return ""

###############################################################################


Expand Down
199 changes: 111 additions & 88 deletions tests/test_cryptocompare.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,96 +3,119 @@
import unittest
import cryptocompare
import datetime
import os


class TestCryptoCompare(unittest.TestCase):
def assertCoinAndCurrInPrice(self, coin, curr, price):
if isinstance(coin, list):
for co in coin:
self.assertCoinAndCurrInPrice(co, curr, price)
return
else:
self.assertIn(coin, price)

if isinstance(curr, list):
for cu in curr:
self.assertIn(cu, price[coin])
else:
self.assertIn(curr, price[coin])

def test_coin_list(self):
lst = cryptocompare.get_coin_list()
self.assertTrue('BTC' in lst.keys())
lst = cryptocompare.get_coin_list(True)
self.assertTrue('BTC' in lst)

def test_get_price(self):
coin = 'BTC'
price = cryptocompare.get_price(coin)
self.assertCoinAndCurrInPrice(coin, 'EUR', price)
price = cryptocompare.get_price(coin, curr='USD')
self.assertCoinAndCurrInPrice(coin, 'USD', price)
currencies = ['EUR', 'USD', 'GBP']
price = cryptocompare.get_price(coin, curr=currencies)
self.assertCoinAndCurrInPrice(coin, currencies, price)
coins = ['BTC', 'XMR']
price = cryptocompare.get_price(coins, curr=currencies)
self.assertCoinAndCurrInPrice(coins, currencies, price)

def test_get_price_full(self):
price = cryptocompare.get_price('ETH', full=True)
self.assertIn('RAW', price)
self.assertIn('ETH', price['RAW'])
self.assertIn('EUR', price['RAW']['ETH'])
self.assertIn('PRICE', price['RAW']['ETH']['EUR'])

def test_get_historical_price(self):
coin = 'XMR'
curr = 'EUR'
price = cryptocompare.get_historical_price(
'XMR', timestamp=datetime.date(2017, 6, 6))
self.assertCoinAndCurrInPrice(coin, curr, price)
price2 = cryptocompare.get_historical_price(
'XMR', 'EUR', datetime.datetime(2017, 6, 6))
self.assertCoinAndCurrInPrice(coin, curr, price2)
self.assertEqual(price, price2)

def test_price_day(self):
coin = 'BTC'
curr = 'USD'
price = cryptocompare.get_historical_price_day(coin, curr=curr, limit=3, exchange='CCCAGG', toTs=datetime.datetime(2019,6,6))
for frame in price:
self.assertIn('time', frame)

def test_price_hour(self):
coin = 'BTC'
curr = 'USD'
price = cryptocompare.get_historical_price_hour(coin, curr=curr, limit=3, exchange='CCCAGG', toTs=datetime.datetime(2019,6,6,12))
for frame in price:
self.assertIn('time', frame)

def test_price_minute(self):
coin = 'BTC'
curr = 'USD'
price = cryptocompare.get_historical_price_minute(coin, curr=curr, limit=3, exchange='CCCAGG', toTs=datetime.datetime.now())
for frame in price:
self.assertIn('time', frame)

def test_get_avg(self):
coin = 'BTC'
curr = 'USD'
avg = cryptocompare.get_avg(coin, curr, exchange='Kraken')
self.assertEqual(avg['LASTMARKET'], 'Kraken')
self.assertEqual(avg['FROMSYMBOL'], coin)
self.assertEqual(avg['TOSYMBOL'], curr)

def test_get_exchanges(self):
exchanges = cryptocompare.get_exchanges()
self.assertIn('Kraken', exchanges)

def test_get_pairs(self):
pairs = cryptocompare.get_pairs(exchange='Kraken')
self.assertEqual('Kraken', pairs[0]['exchange'])
def assertCoinAndCurrInPrice(self, coin, curr, price):
if isinstance(coin, list):
for co in coin:
self.assertCoinAndCurrInPrice(co, curr, price)
return
else:
self.assertIn(coin, price)

if isinstance(curr, list):
for cu in curr:
self.assertIn(cu, price[coin])
else:
self.assertIn(curr, price[coin])

def test_coin_list(self):
lst = cryptocompare.get_coin_list()
self.assertTrue('BTC' in lst.keys())
lst = cryptocompare.get_coin_list(True)
self.assertTrue('BTC' in lst)

def test_get_price(self):
coin = 'BTC'
price = cryptocompare.get_price(coin)
self.assertCoinAndCurrInPrice(coin, 'EUR', price)
price = cryptocompare.get_price(coin, curr='USD')
self.assertCoinAndCurrInPrice(coin, 'USD', price)
currencies = ['EUR', 'USD', 'GBP']
price = cryptocompare.get_price(coin, curr=currencies)
self.assertCoinAndCurrInPrice(coin, currencies, price)
coins = ['BTC', 'XMR']
price = cryptocompare.get_price(coins, curr=currencies)
self.assertCoinAndCurrInPrice(coins, currencies, price)

def test_get_price_full(self):
price = cryptocompare.get_price('ETH', full=True)
self.assertIn('RAW', price)
self.assertIn('ETH', price['RAW'])
self.assertIn('EUR', price['RAW']['ETH'])
self.assertIn('PRICE', price['RAW']['ETH']['EUR'])

def test_get_historical_price(self):
coin = 'XMR'
curr = 'EUR'
price = cryptocompare.get_historical_price(
'XMR', timestamp=datetime.date(2017, 6, 6))
self.assertCoinAndCurrInPrice(coin, curr, price)
price2 = cryptocompare.get_historical_price(
'XMR', 'EUR', datetime.datetime(2017, 6, 6))
self.assertCoinAndCurrInPrice(coin, curr, price2)
self.assertEqual(price, price2)

def test_price_day(self):
coin = 'BTC'
curr = 'USD'
price = cryptocompare.get_historical_price_day(
coin, curr=curr, limit=3, exchange='CCCAGG', toTs=datetime.datetime(2019, 6, 6))
for frame in price:
self.assertIn('time', frame)

def test_price_hour(self):
coin = 'BTC'
curr = 'USD'
price = cryptocompare.get_historical_price_hour(
coin, curr=curr, limit=3, exchange='CCCAGG', toTs=datetime.datetime(2019, 6, 6, 12))
for frame in price:
self.assertIn('time', frame)

def test_price_minute(self):
coin = 'BTC'
curr = 'USD'
price = cryptocompare.get_historical_price_minute(
coin, curr=curr, limit=3, exchange='CCCAGG', toTs=datetime.datetime.now())
for frame in price:
self.assertIn('time', frame)

def test_get_avg(self):
coin = 'BTC'
curr = 'USD'
avg = cryptocompare.get_avg(coin, curr, exchange='Kraken')
self.assertEqual(avg['LASTMARKET'], 'Kraken')
self.assertEqual(avg['FROMSYMBOL'], coin)
self.assertEqual(avg['TOSYMBOL'], curr)

def test_get_exchanges(self):
exchanges = cryptocompare.get_exchanges()
self.assertIn('Kraken', exchanges)

def test_get_pairs(self):
pairs = cryptocompare.get_pairs(exchange='Kraken')
self.assertEqual('Kraken', pairs[0]['exchange'])

def test_sets_api_key_using_environment_variable(self):
os.environ["CRYPTOCOMPARE_API_KEY"] = "Key"
api_key_parameter = cryptocompare.cryptocompare._set_api_key_parameter(
None)
assert api_key_parameter == "&api_key=Key"

def test_sets_api_key_with_no_env_var_and_none_passed(self):
if os.getenv("CRYPTOCOMPARE_API_KEY"):
del os.environ['CRYPTOCOMPARE_API_KEY']
api_key_parameter = cryptocompare.cryptocompare._set_api_key_parameter(
None)
assert api_key_parameter == ""

def test_sets_api_key_passed_in_works(self):
api_key_parameter = cryptocompare.cryptocompare._set_api_key_parameter(
"keytest")
assert api_key_parameter == "&api_key=keytest"


if __name__ == "__main__":
unittest.main()
unittest.main()

0 comments on commit 8e51826

Please sign in to comment.