Skip to content

Commit

Permalink
Added one parameter for get_balance function. This is useragent param…
Browse files Browse the repository at this point in the history
…enter. If it has no been provided use of useragent by default which setup in config file. Added tests for get_rate function. Added parameter data_type for get_supported_currencies. This function may return supported currencies in the kind: list, tuple, dictionary.
  • Loading branch information
AleksandrLeonov committed Mar 4, 2017
1 parent ad9896f commit 7466a08
Show file tree
Hide file tree
Showing 21 changed files with 165 additions and 77 deletions.
3 changes: 2 additions & 1 deletion cryptobalances/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
from cryptobalances.checker import get_balance
from cryptobalances.checker import get_rate
from cryptobalances.validator import autodetect_currency
from cryptobalances.config import get_supported_currencies


__all__ = ["get_balance", "autodetect_currency", "get_rate"]
__all__ = ["get_balance", "get_rate", "autodetect_currency", "get_supported_currencies"]
__version__ = '0.9.4'
9 changes: 5 additions & 4 deletions cryptobalances/checker.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from cryptobalances.validator import autodetect_currency
from cryptobalances.config import default_user_agent
from cryptobalances.services import chain_request
from cryptobalances.services import eth_request
from cryptobalances.services import doge_request
Expand Down Expand Up @@ -37,14 +38,14 @@ def get_request(currency):
return None


def get_balance(currency, identifier):
def get_balance(currency, identifier, useragent=default_user_agent()):

auto_currency = autodetect_currency(identifier)

if not isinstance(auto_currency, list):
currency = auto_currency

return get_request(currency)(currency, identifier)
return get_request(currency)(currency, identifier, useragent)


# Maybe need to add instant=True parameter for getting rates from instant exchanges such as: shapeshift, changelly
Expand All @@ -54,9 +55,9 @@ def get_exchange():
# return [poloniex_rates, shapeshift_rates, changer_rates, coinomat_rates]


def get_rate(from_currency, to_currency):
def get_rate(from_currency, to_currency, useragent=default_user_agent()):
for i in get_exchange():
rate = i(from_currency, to_currency)
rate = i(from_currency, to_currency, useragent)
if rate:
return rate
return None
21 changes: 19 additions & 2 deletions cryptobalances/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,28 @@ def get_exchange_url(exchange):
return api_url[exchange]


def get_supported_currencies():
def get_supported_currencies(data_type):
# parameter data_type - type of return value.
# Such as: list, tuple, dictionary

currencies = ['BTC', 'LTC', 'ETH',
'DOGE', 'XCP', 'DASH',
'PPC', 'CPC', 'GRT',
'BLK', 'XEM', 'XRP',
'OA', 'OMNI', 'ZEC',
'NXT', 'STEEM', 'GOLOS']
return currencies
if data_type == 'list':
return currencies
elif data_type == 'tuple':
temp_list = list()
for i in zip(currencies, currencies):
temp_list.append(i)
return tuple(temp_list)
elif data_type == 'dict':
return dict(zip(currencies, currencies))


def default_user_agent():
return "Mozilla/5.0 (Windows NT 6.1; WOW64) " \
"AppleWebKit/537.36 (KHTML, like Gecko) " \
"Chrome/55.0.2883.87 Safari/537.36"
13 changes: 8 additions & 5 deletions cryptobalances/exchanges/changer.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
import json
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_exchange_url


def get_rates(from_currency, to_currency):
def get_rates(from_currency, to_currency, useragent):
# Supported currencies:
# pm_USD, pmvoucher_USD, okpay_USD, payeer_USD, advcash_USD, btce_USD, bitcoin_BTC, litecoin_LTC, ethereum_ETH,
# dogecoin_DOGE, monero_XMR, maidsafecoin_MAID, dash_DASH, tether_USDT, ethereumclassic_ETC, lisk_LSK, bytecoin_BCN,
Expand All @@ -21,10 +22,12 @@ def get_rates(from_currency, to_currency):
'PPC': 'peercoin_PPC',
'NMC': 'namecoin_NMC'}
try:
with urlopen(get_exchange_url('changer').format(
from_currency=currency_map.get(from_currency.upper()),
to_currency=currency_map.get(to_currency.upper())),
timeout=60) as f:
request = Request(get_exchange_url('changer').format(
from_currency=currency_map.get(from_currency.upper()),
to_currency=currency_map.get(to_currency.upper())), method='GET')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
response = json.loads(f.read().decode('utf-8'))
return response.get('rate')
except HTTPError as error:
Expand Down
13 changes: 8 additions & 5 deletions cryptobalances/exchanges/coinomat.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
import json
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_exchange_url


def get_rates(from_currency, to_currency):
def get_rates(from_currency, to_currency, useragent):
try:
# BTC - Bitcoin, LTC - Litecoin, BTCD - BitcoinDark, PPC - Peercoin, NXT - NXT(NeXT), PERFECT - Perfect Money USD,
# EGOPAY - Ego Pay USD, OKPAY - OK Pay USD, VISAMASTER - withdrawal to Visa / Mastercard,
Expand All @@ -15,10 +16,12 @@ def get_rates(from_currency, to_currency):
# This service has problem with ssl cert:
# ssl.SSLError(1,'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)')
# Temporary disabled this api.
with urlopen(get_exchange_url('coinomat').format(
from_currency=from_currency,
to_currency=to_currency),
timeout=60) as f:
request = Request(get_exchange_url('coinomat').format(
from_currency=from_currency,
to_currency=to_currency), method='GET')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
response = json.loads(f.read().decode('utf-8'))
if response.get('error'):
return None
Expand Down
8 changes: 6 additions & 2 deletions cryptobalances/exchanges/poloniex.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# -*- coding: utf-8 -*-
import json
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_exchange_url


def get_rates(from_currency, to_currency):
def get_rates(from_currency, to_currency, useragent):
try:
# currencies have been swapped because poloniex returns incorrect value.
# For example: BTC_ETH returns value 0.0143859. But it's rate ETH to BTC
request = Request(get_exchange_url('poloniex'), method='GET')
request.add_header('User-Agent', useragent)

currency_pair = '{to_currency}_{from_currency}'.format(from_currency=from_currency, to_currency=to_currency)
with urlopen(get_exchange_url('poloniex'), timeout=60) as f:
with urlopen(request, timeout=60) as f:
pair = json.loads(f.read().decode('utf-8')).get(currency_pair)
if pair:
return pair.get('last')
Expand Down
13 changes: 8 additions & 5 deletions cryptobalances/exchanges/shapeshift.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
# -*- coding: utf-8 -*-
import json
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_exchange_url


def get_rates(from_currency, to_currency):
def get_rates(from_currency, to_currency, useragent):
try:
with urlopen(get_exchange_url('shapeshift').format(
from_currency=from_currency,
to_currency=to_currency),
timeout=60) as f:
request = Request(get_exchange_url('shapeshift').format(
from_currency=from_currency,
to_currency=to_currency), method='GET')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
response = json.loads(f.read().decode('utf-8'))
if response.get('error'):
return None
Expand Down
9 changes: 2 additions & 7 deletions cryptobalances/services/chain_cryptoid.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,10 @@
from cryptobalances.config import get_api_url


def pull_request(currency, identifier):
def pull_request(currency, identifier, useragent):
try:
request = Request(get_api_url(currency).format(identifier=identifier), method='GET')

# If perform the request with user-agent the default for python api returns 403 http error
request.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 6.1; WOW64) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/55.0.2883.87 Safari/537.36')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
return f.read().decode('utf-8')
Expand Down
8 changes: 6 additions & 2 deletions cryptobalances/services/chain_so.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# -*- coding: utf-8 -*-
import json
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_api_url


def pull_request(currency, identifier):
def pull_request(currency, identifier, useragent):
try:
with urlopen(get_api_url(currency).format(network=currency, identifier=identifier), timeout=60) as f:
request = Request(get_api_url(currency).format(network=currency, identifier=identifier), method='GET')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
return json.loads(f.read().decode('utf-8'))['data']['confirmed_balance']
except HTTPError as error:
response = json.loads(error.read().decode('utf-8'))
Expand Down
9 changes: 2 additions & 7 deletions cryptobalances/services/counterparty.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@
from cryptobalances.config import get_api_url


def pull_request(currency, identifier):
def pull_request(currency, identifier, useragent):
# TODO: I have noticed that time to time the following api is working very slow:
# TODO: http://xcp.blockscan.com/api2?module=address&action=balance&btc_address={identifier}
# TODO: I think we need to find any alternative api.
try:
request = Request(get_api_url(currency).format(identifier=identifier), method='GET')

# If perform the request with user-agent the default for python api returns 403 http error
request.add_header('User-Agent',
'Mozilla/5.0 (Windows NT 6.1; WOW64) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/55.0.2883.87 Safari/537.36')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
response = json.loads(f.read().decode('utf-8'))
Expand Down
8 changes: 6 additions & 2 deletions cryptobalances/services/doge.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# -*- coding: utf-8 -*-
import json
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_api_url


def pull_request(currency, identifier):
def pull_request(currency, identifier, useragent):
try:
with urlopen(get_api_url(currency).format(identifier=identifier), timeout=60) as f:
request = Request(get_api_url(currency).format(identifier=identifier), method='GET')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
return json.loads(f.read().decode('utf-8'))['balance']
except HTTPError as error:
return json.loads(error.read().decode('utf-8'))['error']
Expand Down
8 changes: 6 additions & 2 deletions cryptobalances/services/ethereum.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
# -*- coding: utf-8 -*-
import json
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_api_url


def pull_request(currency, identifier):
def pull_request(currency, identifier, useragent):

# TODO: We need to perform validation wallet because api returns always positive response.
# TODO: For example: http://api.etherscan.io/api?module=account&action=balance&address=bla-bla-bla&tag=latest
# TODO: returns {"status":"1","message":"OK","result":"0"}, but it's not mean that balance is zero.
# TODO: This is case when address of wallet not valid

try:
with urlopen(get_api_url(currency).format(identifier=identifier), timeout=60) as f:
request = Request(get_api_url(currency).format(identifier=identifier), method='GET')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
response = json.loads(f.read().decode('utf-8'))
if response['message'] == 'NOTOK':
# TODO: We need return more informative message if api returns error. It's not good: "NOTOK. Error!"
Expand Down
2 changes: 1 addition & 1 deletion cryptobalances/services/golos.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from cryptobalances.config import get_api_url


def pull_request(currency, identifier):
def pull_request(currency, identifier, useragent):
try:
client = SteemNodeRPC(get_api_url(currency))
return client.get_account(identifier).get('balance').split(' ')[0]
Expand Down
8 changes: 6 additions & 2 deletions cryptobalances/services/nem.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# -*- coding: utf-8 -*-
import json
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_api_url


def pull_request(currency, identifier):
def pull_request(currency, identifier, useragent):
try:
with urlopen(get_api_url(currency).format(identifier=identifier.replace('-', '')), timeout=60) as f:
request = Request(get_api_url(currency).format(identifier=identifier.replace('-', '')), method='GET')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
response = json.loads(f.read().decode('utf-8'))
if 'error' in response:
return 'Error: {}. Reason: {}'.format(response['error'], response['message'])
Expand Down
18 changes: 12 additions & 6 deletions cryptobalances/services/nxt.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
# -*- coding: utf-8 -*-
import json
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_api_url


def pull_request(currency, identifier):
def pull_request(currency, identifier, useragent):
try:
for i in get_peers(currency):
url = "http://{}:7876/nxt?requestType=getBalance&account={}".format(i, identifier)
for i in get_peers(currency, useragent):
request = Request("http://{}:7876/nxt?requestType=getBalance&account={}".format(i, identifier), method='GET')
request.add_header('User-Agent', useragent)

try:
with urlopen(url, timeout=5) as f:
with urlopen(request, timeout=5) as f:
return str(converter(int(json.loads(f.read().decode('utf-8'))['balanceNQT'])))
except HTTPError as error:
# If we can't connect to peer, trying to connect one more time to another peer.
Expand All @@ -23,12 +26,15 @@ def pull_request(currency, identifier):
return error


def get_peers(currency):
def get_peers(currency, useragent):
try:
# Getting list of available peers from: http://nxtpeers.com/api/peers.php
# Further we can to get balance connecting to peer on port 7876.
# For example: http://{ip or domain of peer}:7876/nxt?requestType=getBalance&account=NXT-7LB8-8ZPX-3YR9-3L85B
with urlopen(get_api_url(currency), timeout=60) as f:
request = Request(get_api_url(currency), method='GET')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
peers = list()
response = json.loads(f.read().decode('utf-8'))
for i in response:
Expand Down
8 changes: 6 additions & 2 deletions cryptobalances/services/omni.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
# -*- coding: utf-8 -*-
from urllib.request import urlopen
from urllib.request import Request
from urllib.error import URLError, HTTPError
from cryptobalances.config import get_api_url


def pull_request(currency, identifier):
def pull_request(currency, identifier, useragent):
property_id = {'OMNI': '1'}

try:
with urlopen(get_api_url(currency).format(property_id=property_id['OMNI'], identifier=identifier), timeout=60) as f:
request = Request(get_api_url(currency).format(property_id=property_id['OMNI'], identifier=identifier), method='GET')
request.add_header('User-Agent', useragent)

with urlopen(request, timeout=60) as f:
return f.read().decode('utf-8')
except HTTPError as error:
return error.reason
Expand Down
Loading

0 comments on commit 7466a08

Please sign in to comment.