I wrote a small aggregator app that aggregates values from a json http post request and outputs the aggregates values. Now the aggregator function is somewhat large but the output appears correct. 

I start it with gunicorn:

    $ gunicorn --workers 2 --threads 4 aggregator:api

I test it with curl :

    $ curl -X POST -d @aggregator.json http://localhost:8000/aggregate

It outputs the aggregated values. 


    import falcon
    import json
    from datetime import datetime
    from dateutil import tz
    import requests
    import time
    
    from_zone = tz.gettz('UTC')
    to_zone = tz.gettz('Europe/Stockholm')
    
    class DataService:
    
        def on_post(self, req, resp):
            data = json.loads(req.stream.read().decode('utf-8'))
            # output the data, we could write it to persistent storage here
            print(data)
    
    class AggregatorService:
    
        def zero_if_none(self, value):
            if value is not None:
                x = int(value)
            else:
                x = 0
            return x
    
        # return the start day of consumption e.g. 1 for 2014-12-01
        def get_day_start(self, hours):
            return int(datetime.fromtimestamp(
                int(hours[0][0])
            ).strftime('%d'))
    
        # return the month number e.g. 2 for February
        def get_month_start(self, hours):
            return int(datetime.fromtimestamp(
                int(hours[0][0])
            ).strftime('%m'))
    
        # return the day of month number e.g. 5 for 2015-01-05
        def get_day(self, hour):
            return int(datetime.fromtimestamp(
                    int(hour[0])
                ).strftime('%d'))
    
        # return the month number for a timestamp
        def get_month(self, hour):
            return int(datetime.fromtimestamp(
                    int(hour[0])
                ).strftime('%m'))
    
        def on_post(self, req, resp):
    
            data = json.loads(req.stream.read().decode('utf-8'))
            hours = data['hours']
    
            day_start = self.get_day_start(hours)
            month_start = self.get_month_start(hours)
    
            aggr_daily_wh = 0
            aggr_monthly_wh = 0
    
            aggr_daily_th = 0
            aggr_monthly_th = 0
            jdict = {}
    
            jdict['user'] = data['user']
    
            jhours = []
            jdays = []
            jmonths = []
    
            last_h = 0
            last_day_wh = 0
            last_day_th = 0
            last_month_wh = 0
            last_month_th = 0
    
            for hour in hours:
    
                day = self.get_day(hour)
                print("day %d" % day)
                month = self.get_month(hour)
                print("month %d" % month)
    
                utime = datetime.fromtimestamp(
                    int(hour[0])
                ).strftime('%Y-%m-%d %H:%M:%S')
    
                utc = datetime.strptime(utime, '%Y-%m-%d %H:%M:%S')
    
                # Tell the datetime object that it's in UTC time zone since
                # datetime objects are 'naive' by default
                utc = utc.replace(tzinfo=from_zone)
    
                # Convert time zone and change the timestamp
                tstamp = int(time.mktime(utc.astimezone(to_zone).timetuple()))
    
                # consumption is 0 if there is no value
                wh = self.zero_if_none(hour[1])
                th = self.zero_if_none(hour[2])
    
                # append hourly comsumption
                jhours.append([tstamp, wh, th])
    
                if day == day_start:  # aggregate daily comsumption
                    aggr_daily_wh += wh
                    aggr_daily_th += th
                else:  # new day
                    # append daily comsumption
                    jdays.append([tstamp, aggr_daily_wh, aggr_daily_th])
                    # begin new day
                    day_start = day
                    aggr_daily_wh = 0
                    aggr_daily_th = 0
                    aggr_daily_wh += wh
                    aggr_daily_th += th
    
                if month == month_start:  # aggregate monthly consumption
                    print("adding from month %d" % month)
                    aggr_monthly_wh += wh
                    aggr_monthly_th += th
                else:  # new month
                    # append monthly comsumption
                    jmonths.append([int(tstamp), aggr_monthly_wh, aggr_monthly_th])
                    # begin new month
                    month_start = month
                    aggr_monthly_wh = 0
                    aggr_monthly_th = 0
                    aggr_monthly_wh += wh
                    aggr_monthly_th += th
    
                # make the values from the last iteration visible outside the loop
                last_h = tstamp
                last_month_wh = aggr_monthly_wh
                last_month_th = aggr_monthly_th
                last_day_wh = aggr_daily_wh
                last_day_th = aggr_daily_th
    
            # append the last values
            jdays.append([last_h, last_day_wh, last_day_th])
            jmonths.append([last_h, last_month_wh, last_month_th])
    
            # create the json dictionary
            jdict['hours'] = jhours
            jdict['days'] = jdays
            jdict['months'] = jmonths
    
            r = requests.post('http://localhost:8000/store', json=jdict)
    
    api = falcon.API()
    api.add_route('/aggregate', AggregatorService())
    api.add_route('/store', DataService())

**aggregator.json**

    {
      "user": 42,
      "hours": [
        [
          1417392000,
          1,
          null
        ],
        [
          1417395600,
          2,
          3
        ],
        [
          1417647600,
          3,
          2
        ],
        [
          1417651200,
          null,
          6
        ],
        [
          1422835200,
          6,
          2
        ],
        [
          1423094400,
          4,
          3
        ]
      ]
    }