-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhousehold_api.py
More file actions
143 lines (109 loc) · 3.8 KB
/
Copy pathhousehold_api.py
File metadata and controls
143 lines (109 loc) · 3.8 KB
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import json
import os
import uuid
import redis
from flask import Flask, request, jsonify, abort
from schematics.exceptions import DataError
from schematics.models import Model
from schematics.types import IntType, StringType, FloatType
from schematics.types.compound import ModelType, ListType
app = Flask(__name__)
REDIS_HOST = os.environ.get('DB_PORT_6379_TCP_ADDR')
class User(Model):
age = IntType(required=True)
gender = StringType(required=True, choices=['male', 'female'])
class Household(Model):
members = ListType(ModelType(User), required=True, min_size=1)
income = FloatType(required=True)
def get_fpl_pct(income, members):
n = members - 1
fpl_guideline = 12140.0 + (n * 4320.0)
return income / fpl_guideline
def get_redis_connection():
return redis.StrictRedis(host=REDIS_HOST)
@app.route('/sample-household/', methods=['GET'])
def get_sample_household():
""" Retrieves a static, sample household object
This route exists to demonstrate the schema for a Household object.
It does not touch Redis.
"""
sample_household = Household({
'income': 50000,
'members': [
{'age': 45, 'gender': 'female'},
{'age': 40, 'gender': 'male'},
],
})
return jsonify(sample_household.to_primitive()), 200
@app.route('/')
def index():
return "Household API"
@app.route('/household/<hh_id>', methods=['GET'])
def get_household(hh_id):
""" Retrieves a created household object
The Household ID is specified in the URL. Invalid IDs will return a 400 response.
e.g. http://0.0.0.0:5000/household/194411f0-2afa-11e8-9e68-0242ac110003
"""
r = get_redis_connection()
try:
hh = json.loads(r.get(hh_id))
except TypeError:
abort(400)
return jsonify(hh), 200
@app.route('/household/', methods=['POST'])
def create_household():
""" Creates a Household object
Invalid payloads will return a 400 response.
:return: unique Household ID for later references to object.
{"household_id": "194411f0-2afa-11e8-9e68-0242ac110003"}
"""
if not request.json or 'income' not in request.json or 'members' not in request.json:
abort(400)
hh = {
'income': request.json['income'],
'members': request.json['members']
}
try:
Household(hh).validate()
except DataError:
abort(400)
uid = uuid.uuid1() # generate unique ID
r = get_redis_connection()
r.set(uid, json.dumps(Household(hh).to_primitive()))
return jsonify({'household_id': uid}), 200
@app.route('/fpl/<hh_id>', methods=['GET'])
def household_fpl(hh_id):
""" Calculates fpl percentage of specified Household
The Household ID is specified in the URL. Invalid IDs will return a 400 response.
eg. http://0.0.0.0:5000/fpl/194411f0-2afa-11e8-9e68-0242ac110003
:return: fpl percentage (float)
0.5 -> 50%
"""
r = get_redis_connection()
try:
hh = Household(json.loads(r.get(hh_id)))
except TypeError:
abort(400)
return jsonify(get_fpl_pct(hh.income, len(hh.members))), 200
@app.route('/household/<hh_id>', methods=['PUT'])
def update_household(hh_id):
if not request.json or 'income' not in request.json or 'members' not in request.json:
abort(400)
hh = {
'income': request.json['income'],
'members': request.json['members']
}
try:
Household(hh).validate()
except DataError:
abort(400)
r = get_redis_connection()
r.set(hh_id, json.dumps(Household(hh).to_primitive()))
return jsonify(Household(hh).to_primitive()), 200
@app.route('/household/<hh_id>', methods=['DELETE'])
def delete_household(hh_id):
r = get_redis_connection()
r.delete(hh_id)
return "{} deleted".format(hh_id), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)