From a1329e6db859c48cf6ca1202a41f3a168df64304 Mon Sep 17 00:00:00 2001 From: machakux Date: Sat, 4 Oct 2014 10:42:58 +0300 Subject: [PATCH 1/6] Add distinct values endpoint --- taarifa_api/taarifa_api.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/taarifa_api/taarifa_api.py b/taarifa_api/taarifa_api.py index e6c3836..f9586cc 100644 --- a/taarifa_api/taarifa_api.py +++ b/taarifa_api/taarifa_api.py @@ -4,8 +4,9 @@ from eve.io.mongo import Validator from eve.methods.delete import delete, deleteitem from eve.methods.post import post +from eve.render import send_response -from flask import current_app as app +from flask import request, current_app as app from flask.ext.bootstrap import Bootstrap from flask.ext.compress import Compress from eve_docs import eve_docs @@ -134,6 +135,16 @@ def add_facilities(): add_facilities() +@api.route('/' + api.config['URL_PREFIX'] + '//values/') +def resource_values(facility_code, field): + """Return the unique values for the specified resource field.""" + query = dict(request.args.items()) + query['facility_code'] = facility_code + resources = app.data.driver.db['resources'].find(query) + return send_response('resources', + (sorted(resources.distinct(field)),)) + + def main(): # Heroku support: bind to PORT if defined, otherwise default to 5000. if 'PORT' in environ: From 9cf5f2dc6252ec8ecc4a54cbac9fca8309628a0d Mon Sep 17 00:00:00 2001 From: machakux Date: Sat, 4 Oct 2014 10:55:40 +0300 Subject: [PATCH 2/6] Add endpoint for retrieving resource counts by field --- taarifa_api/taarifa_api.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/taarifa_api/taarifa_api.py b/taarifa_api/taarifa_api.py index f9586cc..aedf149 100644 --- a/taarifa_api/taarifa_api.py +++ b/taarifa_api/taarifa_api.py @@ -145,6 +145,17 @@ def resource_values(facility_code, field): (sorted(resources.distinct(field)),)) +@api.route('/' + api.config['URL_PREFIX'] + '//count/') +def resource_count(facility_code, field): + """Return number of resources grouped a given field.""" + query = dict(request.args.items()) + query['facility_code'] = facility_code + data = app.data.driver.db['resources'].group( + field.split(','), query, initial={'count': 0}, + reduce="function(curr, result) {result.count++;}") + return send_response('resources', [data]) + + def main(): # Heroku support: bind to PORT if defined, otherwise default to 5000. if 'PORT' in environ: From b412b530b836abbf44957aac02e7d67deb8ce970 Mon Sep 17 00:00:00 2001 From: machakux Date: Sat, 4 Oct 2014 11:19:23 +0300 Subject: [PATCH 3/6] Add endpoint for getting group sum of a given field --- taarifa_api/taarifa_api.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/taarifa_api/taarifa_api.py b/taarifa_api/taarifa_api.py index aedf149..4014b06 100644 --- a/taarifa_api/taarifa_api.py +++ b/taarifa_api/taarifa_api.py @@ -137,7 +137,7 @@ def add_facilities(): @api.route('/' + api.config['URL_PREFIX'] + '//values/') def resource_values(facility_code, field): - """Return the unique values for the specified resource field.""" + """Get unique values for the specified resource field.""" query = dict(request.args.items()) query['facility_code'] = facility_code resources = app.data.driver.db['resources'].find(query) @@ -147,7 +147,7 @@ def resource_values(facility_code, field): @api.route('/' + api.config['URL_PREFIX'] + '//count/') def resource_count(facility_code, field): - """Return number of resources grouped a given field.""" + """Get number of resources grouped a given field.""" query = dict(request.args.items()) query['facility_code'] = facility_code data = app.data.driver.db['resources'].group( @@ -156,6 +156,26 @@ def resource_count(facility_code, field): return send_response('resources', [data]) +@api.route('/' + api.config['URL_PREFIX'] + '//sum//') +def resource_sum(facility_code, group, field): + """Get group sum of a given field.""" + fields = field.split(',') + query = dict(request.args.items()) + query['facility_code'] = facility_code + data = app.data.driver.db['resources'].aggregate([ + { + "$match": query + }, + { + "$group": { + "_id": '$' + group, + "sum": {'$sum': {'$add': ['$' + f for f in fields] }}, + } + }, + {"$sort": {group: 1}}])['result'] + return send_response('resources', [data]) + + def main(): # Heroku support: bind to PORT if defined, otherwise default to 5000. if 'PORT' in environ: From 3b59a1d046602a85def906d26ab51b84d1322172 Mon Sep 17 00:00:00 2001 From: machakux Date: Sat, 11 Oct 2014 13:00:32 +0300 Subject: [PATCH 4/6] Add endpoint for retrieving group difference in sum of two fields --- taarifa_api/taarifa_api.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/taarifa_api/taarifa_api.py b/taarifa_api/taarifa_api.py index 4014b06..e36b863 100644 --- a/taarifa_api/taarifa_api.py +++ b/taarifa_api/taarifa_api.py @@ -176,6 +176,36 @@ def resource_sum(facility_code, group, field): return send_response('resources', [data]) +@api.route('/' + api.config['URL_PREFIX'] + '//diff///') +def resource_diff(facility_code, group, field_a, field_b): + """Get group difference in sum of two fields.""" + subtrahends = field_a.split(',') + minuends = field_b.split(',') + query = dict(request.args.items()) + query['facility_code'] = facility_code + data = app.data.driver.db['resources'].aggregate([ + { + '$match': query + }, + { + '$group': { + '_id': '$' + group, + 'sum_subtrahend': {'$sum': {'$add': ['$' + f for f in subtrahends] }}, + 'sum_minuend': {'$sum': {'$add': ['$' + f for f in minuends] }} + } + }, + { + '$project': { + '_id': 1, + 'sum_subtrahend': 1, + 'sum_minuend': 1, + 'difference': {'$subtract': ['$sum_subtrahend', '$sum_minuend']} + } + }, + {'$sort': {group: 1}}])['result'] + return send_response('resources', [data]) + + def main(): # Heroku support: bind to PORT if defined, otherwise default to 5000. if 'PORT' in environ: From ca9ae4a054b7e2623f7990b8b625dedd366a447d Mon Sep 17 00:00:00 2001 From: machakux Date: Sat, 11 Oct 2014 13:10:10 +0300 Subject: [PATCH 5/6] Add endpoint for retrieving group ratio of two fields --- taarifa_api/taarifa_api.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/taarifa_api/taarifa_api.py b/taarifa_api/taarifa_api.py index e36b863..085d284 100644 --- a/taarifa_api/taarifa_api.py +++ b/taarifa_api/taarifa_api.py @@ -206,6 +206,36 @@ def resource_diff(facility_code, group, field_a, field_b): return send_response('resources', [data]) +@api.route('/' + api.config['URL_PREFIX'] + '//ratio///') +def resource_ratio(facility_code, group, field_a, field_b): + """Get group ratio of sum of two fields.""" + dividends = field_a.split(',') + divisors = field_b.split(',') + query = dict(request.args.items()) + query['facility_code'] = facility_code + data = app.data.driver.db['resources'].aggregate([ + { + '$match': query + }, + { + '$group': { + '_id': '$' + group, + 'sum_dividend': {'$sum': {'$add': ['$' + f for f in dividends] }}, + 'sum_divisor': {'$sum': {'$add': ['$' + f for f in divisors] }} + } + }, + { + '$project': { + '_id': 1, + 'sum_dividend': 1, + 'sum_divisor': 1, + 'ratio': {'$divide': ['$sum_dividend', '$sum_divisor']} + } + }, + {'$sort': {group: 1}}])['result'] + return send_response('resources', [data]) + + def main(): # Heroku support: bind to PORT if defined, otherwise default to 5000. if 'PORT' in environ: From 22dfaf49eb556e3b31cebcdb05d29ceff56ee9b2 Mon Sep 17 00:00:00 2001 From: machakux Date: Sat, 11 Oct 2014 13:54:24 +0300 Subject: [PATCH 6/6] Add endpoint for retrieving sum of product of two fields --- taarifa_api/taarifa_api.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/taarifa_api/taarifa_api.py b/taarifa_api/taarifa_api.py index 085d284..1c33085 100644 --- a/taarifa_api/taarifa_api.py +++ b/taarifa_api/taarifa_api.py @@ -236,6 +236,34 @@ def resource_ratio(facility_code, group, field_a, field_b): return send_response('resources', [data]) +@api.route('/' + api.config['URL_PREFIX'] + '//product_sum///') +def resource_product_sum(facility_code, group, field_a, field_b): + """Get group sum of product of two fields.""" + multiplicands = field_a.split(',') + multipliers = field_b.split(',') + query = dict(request.args.items()) + query['facility_code'] = facility_code + data = app.data.driver.db['resources'].aggregate([ + { + '$match': query + }, + { + '$group': { + '_id': '$' + group, + 'product_sum': { + '$sum': { + '$multiply': [ + {'$add': ['$' + f for f in multiplicands]}, + {'$add': ['$' + f for f in multipliers]} + ] + } + } + } + }, + {'$sort': {group: 1}}])['result'] + return send_response('resources', [data]) + + def main(): # Heroku support: bind to PORT if defined, otherwise default to 5000. if 'PORT' in environ: