-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.py
141 lines (99 loc) · 4.86 KB
/
api.py
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
import os
import sys
import pdb
import json
from flask import request, session, url_for, jsonify, make_response, _app_ctx_stack, Blueprint
from models.arm import Arm
from models.bandit import Bandit
from algorithms.epsilon_greedy import EpsilonGreedy
from algorithms.softmax import Softmax
from lib import validations
api = Blueprint('api', __name__)
@api.route("/api/v1.0/bandits", methods = ['POST'])
def create_bandit():
''' Create a new bandit experiment '''
# if not a json request throw a 400 error
validations.json_request(request)
# if params not given or improper, throw a 401 error
validations.create_params(request)
# initialize and store the bandit in redis
bandit = Bandit(request)
return jsonify( {"bandit_id" : bandit.id, "name" : bandit.name, "arm_ids" : bandit.arms.keys()} ), 201
@api.route("/api/v1.0/bandits/<int:bandit_id>", methods = ['GET'])
def get_bandit(bandit_id):
''' Lookup a bandit by its ID '''
# if bandit exists, find it
if validations.bandit_exists(bandit_id):
bandit_dict = Bandit.get_bandit(bandit_id)
return jsonify( { "bandit_id" : bandit_id, 'name' : bandit_dict['name'], 'total_reward' : bandit_dict['total_reward'], \
'total_count' : bandit_dict['total_count'], 'regret' : bandit_dict['regret']} )
@api.route("/api/v1.0/bandits/<int:bandit_id>/arms/current", methods = ['GET'])
def get_current_arm(bandit_id):
''' Get the bandit's "best" arm '''
# if bandit exists, find it
if validations.bandit_exists(bandit_id):
bandit_dict = Bandit.get_bandit(bandit_id)
# initialize the bandit class object and find the "best" arm
current_arm = _start_algo(bandit_dict).select_arm()
return jsonify( { 'bandit_id' : bandit_id, 'current_arm' : current_arm } )
@api.route("/api/v1.0/bandits/<int:bandit_id>", methods = ['PUT'])
def update_bandit(bandit_id):
''' Update a bandit's name, algo_type, budget_type, budget, epsilon, reward_type, or max_reward '''
# if not a json request throw a 400 error
validations.json_request(request)
# if bandit exists, find it
if validations.bandit_exists(bandit_id):
bandit_dict = Bandit.get_bandit(bandit_id)
# update these fields if provided
bandit_dict['name'] = request.json.get('name', bandit_dict['name'])
bandit_dict['algo_type'] = request.json.get('algo_type', bandit_dict['algo_type'])
bandit_dict['budget_type'] = request.json.get('budget_type', bandit_dict['budget_type'])
bandit_dict['budget'] = request.json.get('budget', bandit_dict['budget'])
bandit_dict['epsilon'] = request.json.get('epsilon', bandit_dict['epsilon'])
bandit_dict['reward_type'] = request.json.get('reward_type', bandit_dict['reward_type'])
bandit_dict['max_reward'] = request.json.get('max_reward', bandit_dict['max_reward'])
Bandit.set_bandit(bandit_id, bandit_dict)
# TODO: add some other stuff here
return jsonify( {"bandit_id" : bandit_id, "name" : bandit_dict['name'], "algo_type" : bandit_dict['algo_type'], \
"budget_type" : bandit_dict['budget_type'], "budget" : bandit_dict["budget"], "epsilon" : bandit_dict["epsilon"], \
"reward_type" : bandit_dict["reward_type"], "max_reward" : bandit_dict["max_reward"]} )
@api.route("/api/v1.0/bandits/<int:bandit_id>/arms/<int:arm_id>", methods = ['PUT'])
def update_arm(bandit_id, arm_id):
# if not a json request throw a 400 error
validations.json_request(request)
# if params not give throw 401 error
validations.update_arm_params(request)
# pdb.set_trace()
if validations.bandit_exists(bandit_id):
bandit_dict = Bandit.get_bandit(bandit_id)
validations.arm_exists(arm_id, bandit_dict)
# initialize the bandit algo class object and call update
bandit = _start_algo(bandit_dict)
bandit.update(arm_id, request.json['reward'])
# update the bandit's arm with the values update returns
bandit_dict['arms'][arm_id]['count'] = bandit.counts[long(arm_id)]
bandit_dict['arms'][arm_id]['value'] = bandit.values[long(arm_id)]
bandit_dict['regret'] = bandit.regret
bandit_dict['total_reward'] = bandit.total_reward
bandit_dict['total_count'] = bandit.total_count
Bandit.set_bandit(bandit_id, bandit_dict)
# TODO: add some other stuff here
return jsonify( { "bandit_id" : bandit_id, "regret" : bandit_dict['regret'], "total_reward" : bandit_dict["total_reward"], \
"total_count" : bandit_dict['total_count'], "arms": bandit_dict['arms'] } )
@api.route("/api/v1.0/bandits/<int:bandit_id>", methods = ['DELETE'])
def delete_bandit(bandit_id):
# if bandit exists, find it
if validations.bandit_exists(bandit_id):
bandit_dict = Bandit.get_bandit(bandit_id)
Bandit.delete_bandit(bandit_id)
# TODO: add some other stuff here
return jsonify( { 'result': True } )
#---------------------------------------------
# algo class methods
# --------------------------------------------
def _start_algo(bandit):
# helper method to initialize the correct bandit class object
return {
'egreedy' : EpsilonGreedy(bandit),
'softmax' : Softmax(bandit)
}[bandit['algo_type']]