-
Notifications
You must be signed in to change notification settings - Fork 0
/
update_exchange_rates.py
83 lines (66 loc) · 2.92 KB
/
update_exchange_rates.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
#!/usr/bin/env python
"""A script to update the exchange rates for 1 EUR in SEK and 1 USD om SEK.
"""
import argparse
import yaml
from couchdb import Server
import datetime
from forex_python.converter import CurrencyRates
def get_current(db, view):
rows = db.view("by_date/{}".format(view), descending=True, limit=1).rows
if len(rows) != 0:
value = rows[0].value
return value
return None
def check_financial_crisis(current_val, new_val, currency):
if current_val is not None:
rel_change = (new_val-current_val)/current_val
print("INFO: Change in {} "
"exchange rate: {:.3f}%".format(currency, 100*(rel_change)))
if abs(rel_change) > 0.20:
raise Exception("Financial crisis or rather; something is likely wrong!")
def main(config, push_to_server=False):
c = CurrencyRates()
# Will raise RatesNotAvailableError if not able to fetch from the api
usd_to_sek = c.get_rate('USD', 'SEK')
eur_to_sek = c.get_rate('EUR', 'SEK')
# Create the doc that will be uploaded
doc = {}
doc['Issued at'] = datetime.datetime.now().isoformat()
# I know it's bad practice to call the _source_url method,
# but if it breaks it breaks.
doc['Data source'] = "forex_python ({})".format(c._source_url())
doc['USD_in_SEK'] = usd_to_sek
doc['EUR_in_SEK'] = eur_to_sek
# Load the statusdb database
with open(config) as settings_file:
server_settings = yaml.load(settings_file)
couch = Server(server_settings.get("couch_server", None))
db = couch['pricing_exchange_rates']
# Check that new is not too strange compared to current.
# This is a safety measure so that we have lower risk of having erroneus
# exchange rates in the db.
current_usd = get_current(db, 'usd_to_sek')
current_eur = get_current(db, 'eur_to_sek')
check_financial_crisis(current_usd, usd_to_sek, 'USD')
check_financial_crisis(current_eur, eur_to_sek, 'EUR')
# Completely conserved currencies are also strange.
if (current_eur is not None) and (current_usd is not None):
# This assumes the script is not ran too often
# (api udpates once per day)
small_number = 0.0000000001
if (abs(current_usd - usd_to_sek) < small_number) and \
(abs(current_eur - eur_to_sek) < small_number):
raise Exception("Super stable currencies? Stale api would be my guess.")
if push_to_server:
db.save(doc)
else:
print(doc)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--statusdb_config', required=True,
help='The genomics-status settings.yaml file.')
parser.add_argument('--push', action='store_true', help='Use this tag to '
"make the script push the changes to statusdb")
args = parser.parse_args()
main(args.statusdb_config, push_to_server=args.push)