Skip to content

Commit 3a41ed0

Browse files
authored
Merge pull request corpetty#9 from taylorjdawson/url-build-alt-design
Url build alternative design
2 parents c5ed783 + 352c7d0 commit 3a41ed0

11 files changed

+117
-136
lines changed
178 Bytes
Binary file not shown.
4.62 KB
Binary file not shown.
2.7 KB
Binary file not shown.
797 Bytes
Binary file not shown.
1005 Bytes
Binary file not shown.
1.08 KB
Binary file not shown.

etherscan/accounts.py

Lines changed: 34 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,19 @@
55
class Account(Client):
66
def __init__(self, address=Client.dao_address, api_key='YourApiKeyToken'):
77
Client.__init__(self, address=address, api_key=api_key)
8-
self.module = self.URL_BASES['module'] + 'account'
9-
10-
def make_url(self, call_type=''):
11-
if call_type == 'balance':
12-
self.url = self.URL_BASES['prefix'] \
13-
+ self.module \
14-
+ self.action \
15-
+ self.address \
16-
+ self.tag \
17-
+ self.key
18-
elif call_type == 'transactions':
19-
self.url = self.URL_BASES['prefix'] \
20-
+ self.module \
21-
+ self.action \
22-
+ self.address \
23-
+ self.offset \
24-
+ self.page \
25-
+ self.key
26-
elif call_type == 'blocks':
27-
self.url = self.URL_BASES['prefix'] \
28-
+ self.module \
29-
+ self.action \
30-
+ self.address \
31-
+ self.blocktype \
32-
+ self.offset \
33-
+ self.page \
34-
+ self.key
8+
self.url_dict[self.MODULE] = 'account'
359

3610
def get_balance(self):
37-
self.action = self.URL_BASES['action'] + 'balance'
38-
self.tag = self.URL_BASES['tag'] + 'latest'
39-
self.make_url(call_type='transactions')
11+
self.url_dict[self.ACTION] = 'balance'
12+
self.url_dict[self.TAG] = 'latest'
13+
self.build_url()
4014
req = self.connect()
4115
return req['result']
4216

4317
def get_balance_multiple(self):
44-
self.action = self.URL_BASES['action'] + 'balancemulti'
45-
self.tag = self.URL_BASES['tag'] + 'latest'
46-
self.make_url(call_type='balance')
18+
self.url_dict[self.ACTION] = 'balancemulti'
19+
self.url_dict[self.TAG] = 'latest'
20+
self.build_url()
4721
req = self.connect()
4822
return req['result']
4923

@@ -78,29 +52,29 @@ def get_transaction_page(self, page=1, offset=10000, sort='asc', internal=False)
7852
False -> (default) get normal external transactions
7953
"""
8054
if internal:
81-
self.action = self.URL_BASES['action'] + 'txlistinternal'
55+
self.url_dict[self.ACTION] = 'txlistinternal'
8256
else:
83-
self.action = self.URL_BASES['action'] + 'txlist'
84-
self.page = self.URL_BASES['page'] + str(page)
85-
self.offset = self.URL_BASES['offset'] + str(offset)
86-
self.sort = self.URL_BASES['sort'] + sort
87-
self.make_url(call_type='transactions')
57+
self.url_dict[self.ACTION] = 'txlist'
58+
self.url_dict[self.PAGE] = str(page)
59+
self.url_dict[self.OFFSET] = str(offset)
60+
self.url_dict[self.SORT] = sort
61+
self.build_url()
8862
req = self.connect()
8963
return req['result']
9064

9165
def get_all_transactions(self, offset=10000, sort='asc', internal=False) -> list:
9266
if internal:
93-
self.action = self.URL_BASES['action'] + 'txlistinternal'
67+
self.url_dict[self.ACTION] = 'txlistinternal'
9468
else:
95-
self.action = self.URL_BASES['action'] + 'txlist'
96-
self.page = self.URL_BASES['page'] + str(1)
97-
self.offset = self.URL_BASES['offset'] + str(offset)
98-
self.sort = self.URL_BASES['sort'] + sort
99-
self.make_url(call_type='transactions')
69+
self.url_dict[self.ACTION] = 'txlist'
70+
self.url_dict[self.PAGE] = str(1)
71+
self.url_dict[self.OFFSET] = str(offset)
72+
self.url_dict[self.SORT] = sort
73+
self.build_url()
10074

10175
trans_list = []
10276
while True:
103-
self.make_url(call_type='transactions')
77+
self.build_url()
10478
req = self.connect()
10579
if "No transactions found" in req['message']:
10680
print("Total number of transactions: {}".format(len(trans_list)))
@@ -109,9 +83,9 @@ def get_all_transactions(self, offset=10000, sort='asc', internal=False) -> list
10983
else:
11084
trans_list += req['result']
11185
# Find any character block that is a integer of any length
112-
page_number = re.findall(r'[1-9](?:\d{0,2})(?:,\d{3})*(?:\.\d*[1-9])?|0?\.\d*[1-9]|0', self.page)
86+
page_number = re.findall(r'[1-9](?:\d{0,2})(?:,\d{3})*(?:\.\d*[1-9])?|0?\.\d*[1-9]|0', self.url_dict[self.PAGE])
11387
print("page {} added".format(page_number[0]))
114-
self.page = self.URL_BASES['page'] + str(int(page_number[0]) + 1)
88+
self.url_dict[self.PAGE] = str(int(page_number[0]) + 1)
11589

11690
def get_blocks_mined_page(self, blocktype='blocks', page=1, offset=10000) -> list:
11791
"""
@@ -124,22 +98,22 @@ def get_blocks_mined_page(self, blocktype='blocks', page=1, offset=10000) -> lis
12498
'blocks' -> full blocks only
12599
'uncles' -> uncles only
126100
"""
127-
self.action = self.URL_BASES['action'] + 'getminedblocks'
128-
self.blocktype = self.URL_BASES['blocktype'] + blocktype
129-
self.page = self.URL_BASES['page'] + str(page)
130-
self.offset = self.URL_BASES['offset'] + str(offset)
131-
self.make_url(call_type='blocks')
101+
self.url_dict[self.ACTION] = 'getminedblocks'
102+
self.url_dict[self.BLOCK_TYPE] = blocktype
103+
self.url_dict[self.PAGE] = str(page)
104+
self.url_dict[self.OFFSET] = str(offset)
105+
self.build_url()
132106
req = self.connect()
133107
return req['result']
134108

135109
def get_all_blocks_mined(self, blocktype='blocks', offset=10000) -> list:
136-
self.action = self.URL_BASES['action'] + 'getminedblocks'
137-
self.blocktype = self.URL_BASES['blocktype'] + blocktype
138-
self.page = self.URL_BASES['page'] + str(1)
139-
self.offset = self.URL_BASES['offset'] + str(offset)
110+
self.url_dict[self.ACTION] = 'getminedblocks'
111+
self.url_dict[self.BLOCK_TYPE] = blocktype
112+
self.url_dict[self.PAGE] = str(1)
113+
self.url_dict[self.OFFSET] = str(offset)
140114
blocks_list = []
141115
while True:
142-
self.make_url(call_type='blocks')
116+
self.build_url()
143117
req = self.connect()
144118
print(req['message'])
145119
if "No transactions found" in req['message']:
@@ -148,9 +122,9 @@ def get_all_blocks_mined(self, blocktype='blocks', offset=10000) -> list:
148122
else:
149123
blocks_list += req['result']
150124
# Find any character block that is a integer of any length
151-
page_number = re.findall(r'[1-9](?:\d{0,2})(?:,\d{3})*(?:\.\d*[1-9])?|0?\.\d*[1-9]|0', self.page)
125+
page_number = re.findall(r'[1-9](?:\d{0,2})(?:,\d{3})*(?:\.\d*[1-9])?|0?\.\d*[1-9]|0', self.url_dict[self.PAGE])
152126
print("page {} added".format(page_number[0]))
153-
self.page = self.URL_BASES['page'] + str(int(page_number[0]) + 1)
127+
self.url_dict[self.PAGE] = str(int(page_number[0]) + 1)
154128

155129
def get_internal_by_hash(self, tx_hash=''):
156130
"""

etherscan/client.py

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,81 @@
11
import requests
22
import json
3-
3+
import collections
44

55
# Assume user puts his API key in the api_key.json file under variable name "key"
66
class Client(object):
77
dao_address = '0xbb9bc244d798123fde783fcc1c72d3bb8c189413'
8-
URL_BASES = dict(
9-
prefix='https://api.etherscan.io/',
10-
module='api?module=',
11-
action='&action=',
12-
tag='&tag=',
13-
offset='&offset=',
14-
page='&page=',
15-
sort='&sort=',
16-
blocktype='&blocktype=',
17-
key='&apikey=',
18-
address='&address=',
19-
)
208

21-
def __init__(self, address, api_key='YourApiKeyToken'):
9+
# Constants
10+
PREFIX = 'https://api.etherscan.io/api?'
11+
MODULE = 'module='
12+
ACTION = '&action='
13+
TOKEN_NAME = '&tokenname='
14+
CONTRACT_ADDRESS = '&contractaddress='
15+
ADDRESS = '&address='
16+
OFFSET = '&offset='
17+
PAGE = '&page='
18+
SORT = '&sort='
19+
BLOCK_TYPE = '&blocktype='
20+
TO = '&to='
21+
VALUE = '&value='
22+
DATA = '&data='
23+
POSITION = '&='
24+
HEX = '&hex='
25+
GAS_PRICE = '&gasPrice='
26+
GAS = '&gas='
27+
START_BLOCK = '&startblock='
28+
END_BLOCK = '&endblock='
29+
BLOCKNO = '&blockno='
30+
TXHASH = '&txhash='
31+
TAG = '&tag='
32+
BOOLEAN = '&boolean='
33+
INDEX = '&index='
34+
API_KEY = '&apikey='
35+
36+
url_dict = {}
37+
38+
def __init__(self, address, api_key=''):
2239
self.http = requests.session()
23-
self.url = ''
24-
self.module = ''
25-
self.action = ''
26-
self.tag = ''
27-
self.offset = ''
28-
self.page = ''
29-
self.sort = ''
30-
self.blocktype = ''
40+
self.url_dict = collections.OrderedDict(
41+
{
42+
self.MODULE: '',
43+
self.ADDRESS: '',
44+
self.OFFSET: '',
45+
self.PAGE: '',
46+
self.SORT: '',
47+
self.BLOCK_TYPE: '',
48+
self.TO: '',
49+
self.VALUE: '',
50+
self.DATA: '',
51+
self.POSITION: '',
52+
self.HEX: '',
53+
self.GAS_PRICE: '',
54+
self.GAS: '',
55+
self.START_BLOCK: '',
56+
self.END_BLOCK: '',
57+
self.BLOCKNO: '',
58+
self.TXHASH: '',
59+
self.TAG: '',
60+
self.BOOLEAN: '',
61+
self.INDEX: '',
62+
self.API_KEY: api_key,
63+
})
3164

32-
self.API_KEY = str(api_key)
65+
# self.url_dict[API_KEY] = str(api_key)
3366
self.check_and_get_api()
34-
self.key = self.URL_BASES['key'] + self.API_KEY
67+
# self.key = self.URL_BASES['key'] + self.API_KEY
68+
3569
if (len(address) > 20) and (type(address) == list):
3670
print("Etherscan only takes 20 addresses at a time")
3771
quit()
3872
elif (type(address) == list) and (len(address) <= 20):
39-
self.address = self.URL_BASES['address'] + ','.join(address)
73+
self.url_dict[self.ADDRESS] = ','.join(address)
4074
else:
41-
self.address = self.URL_BASES['address'] + address
75+
self.url_dict[self.ADDRESS] = address
76+
77+
def build_url(self):
78+
self.url = self.PREFIX + ''.join([param + val if val else '' for param, val in self.url_dict.items()])
4279

4380
def connect(self):
4481
# TODO: deal with "unknown exception" error
@@ -54,11 +91,11 @@ def connect(self):
5491
print("Invalid Request")
5592
exit()
5693
else:
57-
print("problem with connection, status code: ", req.status_code)
94+
print("Problem with connection, status code: ", req.status_code)
5895
exit()
5996

6097
def check_and_get_api(self):
61-
if self.API_KEY != 'YourApiKeyToken':
98+
if self.url_dict[self.API_KEY]: # Check if api_key is empty string
6299
pass
63100
else:
64-
self.API_KEY = input('Please type your EtherScan.io API key: ')
101+
self.url_dict[self.API_KEY] = input('Please type your EtherScan.io API key: ')

etherscan/contracts.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,10 @@
44
class Contract(Client):
55
def __init__(self, address=Client.dao_address, api_key='YourApiKeyToken'):
66
Client.__init__(self, address=address, api_key=api_key)
7-
self.module = self.URL_BASES['module'] + 'contract'
8-
9-
def make_url(self, call_type=''):
10-
if call_type == 'getabi':
11-
self.url = self.URL_BASES['prefix'] \
12-
+ self.module \
13-
+ self.action \
14-
+ self.address \
15-
+ self.key
7+
self.url_dict[self.MODULE] = 'contract'
168

179
def get_abi(self):
18-
self.action = self.URL_BASES['action'] + 'getabi'
19-
self.make_url(call_type='getabi')
10+
self.url_dict[self.ACTION] = 'getabi'
11+
self.build_url()
2012
req = self.connect()
21-
return req['result']
13+
return req['result']

etherscan/stats.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,16 @@
44
class Stats(Client):
55
def __init__(self, api_key='YourApiKeyToken'):
66
Client.__init__(self, address='', api_key=api_key)
7-
self.module = self.URL_BASES['module'] + 'stats'
8-
9-
def make_url(self, call_type=''):
10-
if call_type == 'stats':
11-
self.url = self.URL_BASES['prefix'] \
12-
+ self.module \
13-
+ self.action \
14-
+ self.key
7+
self.url_dict[self.MODULE] = 'stats'
158

169
def get_total_ether_supply(self):
17-
self.action = self.URL_BASES['action'] + 'ethsupply'
18-
self.make_url(call_type='stats')
10+
self.url_dict[self.ACTION] = 'ethsupply'
11+
self.build_url()
1912
req = self.connect()
2013
return req['result']
2114

2215
def get_ether_last_price(self):
23-
self.action = self.URL_BASES['action'] + 'ethprice'
24-
self.make_url(call_type='stats')
16+
self.url_dict[self.ACTION] = 'ethprice'
17+
self.build_url()
2518
req = self.connect()
2619
return req['result']

0 commit comments

Comments
 (0)