-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit_dynamo_table.py
148 lines (115 loc) · 4.5 KB
/
init_dynamo_table.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from urllib.request import urlopen
from decimal import Decimal, getcontext
from json import loads
import boto3
""" Python utility to initialize AWS DynamoDB table with Currency Abbreviations,
Currency Exchange Rates and timestamp of latest update from Currency Layer.
This program should be run once prior to running any version of the
currency exchange monitoring program which relies on DynamoDB for
persistent storage.
Requires that Table be previously created with basic schema defined e.g:
dynamo_db_table {
Abbr: String,
Rate: Decimal,
Tstamp: Decimal
}
Author: Michael O'Connor
Last update: 12/26/18
"""
class CurrencyLayer:
"""[summary]
"""
def __init__(self, base, mode, key):
"""Build URL we will use to query latest exchange rates from
Currency Layer Web Service
Args:
base - base portion of URL
mode - 'live' or 'list'
key - Access Key provided when siging up for CurrencyLayer Account
"""
self.cl_url = base + mode + '?access_key=' + key
self.rate_dict = {}
# Working with Decimal numbers so set precision to prevent strange
# floating point approximations
getcontext().prec = 6
def cl_validate(self):
"""Open URL constructed in init(). If initial open is successful, read
contents to determine if API call was successful. If read is
successful, self.rate_dict will contain dictionary data structure
containing current rate quotes. Successful call will return:
{
"success":true,
"terms":"https://currencylayer.com/terms",
"privacy":"https://currencylayer.com/privacy",
"timestamp":1545855246,
"source":"USD",
"quotes":{
"USDAED":3.67295,
"USDAFN":74.3977,
"USDALL":107.949718
...
}
}
"""
try:
web_url = urlopen(self.cl_url)
except:
print('Sorry, unable to open: {}'.format(self.cl_url))
raise Exception
else:
rate_data = web_url.read()
self.rate_dict = loads(rate_data.decode('utf-8'))
if self.rate_dict['success'] is False:
print('Error= {}'.format(self.rate_dict['error']['info']))
raise Exception
else:
print('SUCCESS: In cl_validate()')
def get_rates(self):
"""Simply return the data structure created in cl_validate()"""
return self.rate_dict
def db_batch_update(table, data):
"""DynamoDB Batch update function which takes DynamoDB table and a
dictionary data structure in the format returned by Currency
Layer Web Service and updates an existing table with Currency
Abbreviation, Rate and Timestamp for each supported currency.
"""
t_stamp = data['timestamp']
with table.batch_writer() as batch:
for exch, cur_rate in data['quotes'].items():
abbr = exch[-3:]
print('Updating: {}...'.format(abbr))
batch.put_item(
Item={
'Abbr': str(abbr),
'Rate': Decimal(str(cur_rate)),
'Tstamp': Decimal(t_stamp)
}
)
def main():
"""Query Currency Layer service for complete list of available Currencies
along with current exchange rate relative to USD and update timestamp.
Use resulting data dictionary to populate the DynamoDB table with initial
values for Abbr, Rate and Timestamp.
"""
from currency_config import BASE, MODE, CL_KEY
from currency_config import DYNAMO_DB_TABLE
try:
cl_feed = CurrencyLayer(BASE, MODE, CL_KEY)
cl_feed.cl_validate()
except:
print('Unable to instantiate or validate currency_layer object')
raise Exception
else:
cl_rates = cl_feed.get_rates()
print('Call to Currency Layer Service was Successful')
print('Accessing DynamoDB Table...')
_db = boto3.resource('dynamodb')
cl_table = _db.Table(DYNAMO_DB_TABLE)
print("Table {} created: {}".format(DYNAMO_DB_TABLE, cl_table.creation_date_time))
print('Starting Batch update of DynamoDB Table...')
db_batch_update(cl_table, cl_rates)
print('All done!')
if __name__ == "__main__":
main()