Last active
September 4, 2016 15:39
-
-
Save eskilandreen/5807d559f47003bb24add5dc64558dd6 to your computer and use it in GitHub Desktop.
Better python service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' Responsible for querying remote services and validating the result. ''' | |
from simplejson import JSONDecodeError | |
import requests | |
# Exceptions | |
class ValidationError(Exception): pass | |
class RequestError(Exception): pass | |
# Types for representing results from backend services. | |
# Data from the backend service will be passed to the constructor | |
# using dictionary unpacking (the ** operator). Any parameters | |
# specified in the constructor will be captured and any others | |
# will end up in the ignored dictionary, which will be ignored. | |
# This means that we only need to handle those parts of the data | |
# that we care about. Besides saving some keystrokes, it also makes | |
# our code less brittle if somebody wants to make changes to what | |
# fields the other service exposes. | |
class Bill(object): | |
def __init__(self, amount, **ignored): | |
self.amount = amount | |
class Merchant(object): | |
def __init__(self, name, **ignored): | |
self.name = name | |
# Fetching and validation. | |
def get_merchant(merchant_id): | |
data = _query('http://merchant/merchant/' + merchant_id) | |
try: | |
return Merchant(**data) | |
except: | |
raise ValidationError('Could not validate Merchant') | |
def get_billing(merchant_id): | |
data = _query('http://billing/merchant/' + merchant_id) | |
try: | |
return [Bill(**item) for item in data] | |
except: | |
raise ValidationError('Could not validate Bills') | |
# Helper for making the request and checking the status code. | |
def _query(url): | |
res = requests.get(url) | |
if res.status_code != 200: | |
raise RequestError('Status code != 200') | |
try: | |
return res.json() | |
except JSONDecodeError: | |
raise RequestError('Could not decode JSON') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from bottle import route, run | |
from mako.template import Template | |
import query | |
template = Template(''' | |
<dl> | |
<dd>Name</dd> | |
<dt>${merchant.name}</dt> | |
<dd>Number of bills</dd> | |
<dt>${merchant.number_of_bills}</dt> | |
<dd>Total of bills</dd> | |
<dt>${merchant.total_of_bills}</dt> | |
</div> | |
''') | |
class MerchantWithBilling(object): | |
def __init__(self, merchant, bills): | |
self.name = merchant.name | |
self.number_of_bills = len(bills) | |
self.total_of_bills = sum(x.amount for x in bills) | |
@route('/merchants/<merchant_id>') | |
def get_merchant(merchant_id): | |
query = Query() | |
merchant = query.get_merchant(merchant_id) | |
billing = query.get_billing(merchant_id) | |
aggregate = MerchantWithBilling(merchant, billing) | |
return template.render(merchant=aggregate) | |
if __name__ == '__main__': | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment