Skip to content

Instantly share code, notes, and snippets.

@dsuch
Last active December 18, 2015 13:39
Show Gist options
  • Save dsuch/5791526 to your computer and use it in GitHub Desktop.
Save dsuch/5791526 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
# stdlib
from datetime import datetime
from traceback import format_exc
# anyjson
from anyjson import loads
# lxml
from lxml import etree
# Zato
from zato.server.service import Service
class GetExchangeRateList(Service):
class SimpleIO:
response_elem = 'rates'
input_required = ('from', 'to')
output_required = ('provider', 'rate', 'ts')
output_repeated = True
def get_yahoo(self, from_, to):
# Response template
out = {'provider':'Yahoo! Finance', 'rate':None, 'ts':None}
# Grab a connection by its name
conn = self.outgoing.plain_http.get('Yahoo! Finance').conn
# Y! Finance needs a query string in that format
# ?s=HRKEUR=X&f=snl1d1t1ab
url_params = {'s':'{}{}=X'.format(from_, to), 'f':'snl1d1t1ab'}
# Invoking the .get method issues a GET request
response = conn.get(self.cid, url_params)
# Y! gives us a CSV response
response = response.text.split(',')
# The string we receive is something like
# u'"EURHRK=X","EUR to HRK",7.4608,"6/14/2013","5:55pm",7.4629,7.4588\r\n'
# and we need the 3rd item.
out['rate'] = response[2]
out['ts'] = datetime.utcnow().isoformat()
return out
def get_google(self, from_, to):
out = {'provider':'Google', 'rate':None, 'ts':None}
# Grab a connection by its name
conn = self.outgoing.plain_http.get('Google Calculator').conn
# Google needs a query string in that format
# ?q=1EUR=HRK
url_params = {'q': '1{}={}'.format(from_, to)}
# Invoking the .get method issues a GET request
response = conn.get(self.cid, url_params)
# Convert the pseudo-JSON from
# {lhs: "1 Euro",rhs: "7.46464923 Croatian kune",error: "",icc: true} ->
# {"lhs": "1 Euro","rhs": "7.46464923 Croatian kune","error": "","icc": true}
# so it can be parsed as JSON.
json = response.text
replace = ('lhs', 'rhs', 'error', 'icc')
for name in replace:
json = json.replace(name, '"{}"'.format(name))
rate = loads(json)['rhs'].split()[0]
out['rate'] = rate
out['ts'] = datetime.utcnow().isoformat()
return out
def get_ecb(self, from_, to):
out = {'provider':'European Central Bank', 'rate':None, 'ts':None}
# Grab a connection by its name
conn = self.outgoing.plain_http.get('European Central Bank').conn
response = conn.get(self.cid)
xml = etree.fromstring(response.text.encode('utf-8'))
ns = {'xref': 'http://www.ecb.int/vocabulary/2002-08-01/eurofxref'}
rate = xml.xpath(
"//xref:Cube[@currency='{}']/@rate".format(to), namespaces=ns)[0]
out['rate'] = rate
out['ts'] = datetime.utcnow().isoformat()
return out
def handle(self):
from_ = self.request.input.get('from')
to = self.request.input.to
for func in(self.get_yahoo, self.get_google, self.get_ecb):
try:
rate = func(from_, to)
except Exception, e:
self.logger.warn('Caught an exception {}'.format(format_exc(e)))
else:
self.response.payload.append(rate)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment