Skip to content
This repository was archived by the owner on Apr 11, 2019. It is now read-only.

Optimized API and fixed typos #9

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ resp = transport.post_transaction(
"DDvQqwqPXKd5P8dLAroFsnKR5Q3tKUtvnp", # RecipientAddress
1000000, # Amount
"firstPassphrase", # First passphrase, mandatory
"vendorField", # Vendor field, optionnal
"secondPassphrase") # Second passphrase, optionnal
"vendorField", # Vendor field, optional
"secondPassphrase") # Second passphrase, optional
```

## TODOS
Expand Down
16 changes: 8 additions & 8 deletions pythark/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def get_balance(self, address):
:param address: A valid Ark address.
:return:
"""
resp = self.get("api/accounts/getBalance", address=address)
resp = self.request('get', "api/accounts/getBalance", address=address)
return resp.json()

def get_public_key(self, address):
Expand All @@ -21,25 +21,25 @@ def get_public_key(self, address):
:param address: A valid Ark address.
:return:
"""
resp = self.get("api/accounts/getPublickey", address=address)
resp = self.request('get', "api/accounts/getPublickey", address=address)
return resp.json()

def get_delegate_fee(self):
""" Get the delegate fee of an account.

:return:
"""
resp = self.get("api/accounts/delegates/fee")
resp = self.request('get', "api/accounts/delegates/fee")
return resp.json()

def get_delegates(self, address, **kwargs):
""" Get the delegates of an account.

:param address: A valid Ark address.
:param kwargs: Optionnal parameters. orderBy, limit, offset
:param kwargs: Optional parameters. orderBy, limit, offset
:return:
"""
resp = self.get("api/accounts/delegates", address=address, **kwargs)
resp = self.request('get', "api/accounts/delegates", address=address, **kwargs)
return resp.json()

def get_accounts(self, address):
Expand All @@ -48,14 +48,14 @@ def get_accounts(self, address):
:param address: A valid Ark address.
:return:
"""
resp = self.get("api/accounts", address=address)
resp = self.request('get', "api/accounts", address=address)
return resp.json()

def get_top_accounts(self, **kwargs):
""" Get a list of top account

:param kwargs: Optionnal parameters. limit, offset
:param kwargs: Optional parameters. limit, offset
:return:
"""
resp = self.get("api/accounts/top", **kwargs)
resp = self.request('get', "api/accounts/top", **kwargs)
return resp.json()
145 changes: 50 additions & 95 deletions pythark/api.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
import requests
import random
import json
from retrying import retry

BASE_URL = "https://api.arknode.net/" # "http://37.59.129.164:4001/"
BASE_URL_DEV = "http://167.114.29.52:4002/"
BASE_URL_KAPUMAIN = "https://walletapi.kapu.one/"

FALLBACKS_MAIN_ADDRESSES = []
FALLBACKS_DEV_ADDRESSES = []
FALLBACKS_KAPU_ADDRESSES = []
NETWORKS = {
'main': {
'base_urls': [
'https://node1.arknet.cloud/'
],
'headers': {
'nethash': '6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988',
'version': '1.0.1',
'port': '4001'
}
},
'dev': {
'base_urls': [
'http://167.114.29.52:4002/'
],
'headers': {
'nethash': '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23',
'version': '1.1.1',
'port': '4002'
}
},
'kapu': {
'base_urls': [
'https://walletapi.kapu.one/'
],
'headers': {
'nethash': '6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988',
'version': '1.0.1',
'port': '4001'
}
}
}


class API:
Expand All @@ -20,94 +43,26 @@ def __init__(self, network="main"):
self.network = network

@retry(stop_max_attempt_number=10, wait_fixed=10000)
def get(self, endpoint, **kwargs):
""" Do a HTTP get request to a specified endpoint (with optionnal parameters).
def request(self, req_type, endpoint, **kwargs):
""" Do a HTTP request to a specified endpoint (with optional parameters).

:param req_type: The request type. Either `get` or `post`.
:param endpoint: The endpoint we want to reach.
:param kwargs: Optionnal parameters of the query.
:param kwargs: Optional parameters of the query.
:return: Request response if HTTP code is equal to 200.
"""
payload = {name: kwargs[name] for name in kwargs if kwargs[name] is not None}
try:
if self.network == "main":
headers_main = get_main_network_headers()
r = requests.get("{0}{1}".format(BASE_URL, endpoint), headers=headers_main, params=payload, timeout=10)
if self.network == "dark" or self.network == "dev":
headers_dev = get_dev_network_headers()
r = requests.get("{0}{1}".format(BASE_URL_DEV, endpoint), headers=headers_dev, params=payload, timeout=10)
if self.network == "kapu":
headers_kapu_main = get_kapu_main_network_headers()
r = requests.get("{0}{1}".format(BASE_URL_KAPUMAIN, endpoint), headers=headers_kapu_main, params=payload, timeout=10)
if r.status_code == 200:
return r
except requests.exceptions.Timeout:
if self.network == "dark" or self.network == "dev":
populate_fallback(FALLBACKS_DEV_ADDRESSES, self.network)
url = select_random_ip(FALLBACKS_DEV_ADDRESSES) + "/"
r = requests.get("{0}{1}".format(url, endpoint), headers=headers_dev, params=payload, timeout=10)
elif self.network == "kapu":
populate_fallback(FALLBACKS_KAPU_ADDRESSES, self.network)
url = select_random_ip(FALLBACKS_KAPU_ADDRESSES) + "/"
r = requests.get("{0}{1}".format(url, endpoint), headers=headers_kapu_main, params=payload, timeout=10)
else:
populate_fallback(FALLBACKS_MAIN_ADDRESSES, self.network)
url = select_random_ip(FALLBACKS_MAIN_ADDRESSES) + "/"
r = requests.get("{0}{1}".format(url, endpoint), headers=headers_main, params=payload, timeout=10)
if r.status_code == 200:
return r
except requests.exceptions.ConnectionError as e:
print("Connection error : ", e)
except requests.exceptions.ReadTimeout as e:
print("ReadTimeOut error : ", e)

def post(self, endpoint, **kwargs):
payload = {name: kwargs[name] for name in kwargs if kwargs[name] is not None}
r = requests.post("{0}{1}".format(BASE_URL, endpoint), headers=get_dev_network_headers(), params=payload)
return r


def get_main_network_headers():
headers = {
"nethash": "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988",
"version": "1.0.1",
"port": "4001"
}
return headers


def get_dev_network_headers():
headers = {
"nethash": "578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23",
"version": "1.1.1",
"port": "4002"
}
return headers


def get_kapu_main_network_headers():
headers = {
"nethash": "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988",
"version": "1.0.1",
"port": "4001"
}
return headers


def populate_fallback(fallback, network):
from . import Peer
if network == 'dev':
p = Peer("dev")
elif network == 'kapu':
p = Peer("kapu")
else:
p = Peer()
r = p.get_peers()
for peer in r["peers"]:
if peer["delay"] <= 50:
fallback.append(peer)
return fallback


def select_random_ip(fallback):
rand = random.choice(fallback)
return rand['ip']
headers = NETWORKS[self.network]['headers']
for i, base_url in enumerate(NETWORKS[self.network]['base_urls']):
try:
if req_type == 'post':
r = requests.post(base_url + endpoint, headers=headers, params=payload, timeout=10)
elif req_type == 'get':
r = requests.get(base_url + endpoint, headers=headers, params=payload, timeout=10)
else:
raise ValueError('Invalid request type: ' + req_type)
if r.status_code == 200:
return r
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
print("URL #{} failed: {}".format(i + 1, e))
print('Failed to process {} request'.format(req_type))
24 changes: 12 additions & 12 deletions pythark/block.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,87 +12,87 @@ def get_block(self, id):
:param id: Valid Block ID.
:return:
"""
resp = self.get("api/blocks/get", id=id)
resp = self.request('get', "api/blocks/get", id=id)
return resp.json()

def get_blocks(self, **kwargs):
""" Get all blocks.

:param kwargs: Optionnal parameters. limit, orderBy, offset, generatorPublicKey, totalAmount, totalFee, reward,
:param kwargs: Optional parameters. limit, orderBy, offset, generatorPublicKey, totalAmount, totalFee, reward,
previousBlock, height
:return:
"""
resp = self.get("api/blocks", **kwargs)
resp = self.request('get', "api/blocks", **kwargs)
return resp.json()

def get_height(self):
""" Get the blockchain height.

:return:
"""
resp = self.get("api/blocks/getHeight")
resp = self.request('get', "api/blocks/getHeight")
return resp.json()

def get_epoch(self):
""" Get the blockchain epoch.

:return:
"""
resp = self.get("api/blocks/getEpoch")
resp = self.request('get', "api/blocks/getEpoch")
return resp.json()

def get_nethash(self):
""" Get the blockchain nethash.

:return:
"""
resp = self.get("api/blocks/getNethash")
resp = self.request('get', "api/blocks/getNethash")
return resp.json()

def get_fee(self):
""" Get the transaction fee for sending "normal" transactions.

:return:
"""
resp = self.get("api/blocks/getFee")
resp = self.request('get', "api/blocks/getFee")
return resp.json()

def get_fees(self):
""" Get the network fees.

:return:
"""
resp = self.get("api/blocks/getFees")
resp = self.request('get', "api/blocks/getFees")
return resp.json()

def get_milestone(self):
""" Get the blockchain milestone.

:return:
"""
resp = self.get("api/blocks/getMilestone")
resp = self.request('get', "api/blocks/getMilestone")
return resp.json()

def get_reward(self):
""" Get the blockchain reward.

:return:
"""
resp = self.get("api/blocks/getReward")
resp = self.request('get', "api/blocks/getReward")
return resp.json()

def get_supply(self):
""" Get the blockchain supply.

:return:
"""
resp = self.get("api/blocks/getSupply")
resp = self.request('get', "api/blocks/getSupply")
return resp.json()

def get_status(self):
""" Get the blockchain status.

:return:
"""
resp = self.get("api/blocks/getStatus")
resp = self.request('get', "api/blocks/getStatus")
return resp.json()
Loading