Skip to content

Commit d14a5d9

Browse files
Merge pull request #35 from Evolutionary-Algorithms-On-Click/bo
Integrated BO and MOBO modules
2 parents 8cc8ad6 + 60a7530 commit d14a5d9

6 files changed

Lines changed: 2063 additions & 0 deletions

File tree

controller/bo.go

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package controller
2+
3+
import (
4+
"encoding/json"
5+
"evolve/db/connection"
6+
"evolve/modules"
7+
"evolve/util"
8+
"fmt"
9+
"net/http"
10+
"os"
11+
)
12+
13+
func CreateBO(res http.ResponseWriter, req *http.Request) {
14+
logger := util.NewLogger()
15+
logger.Info("CreateBO API called.")
16+
17+
// -----------------------------
18+
// AUTHENTICATE USER
19+
// -----------------------------
20+
user, err := modules.Auth(req)
21+
if err != nil {
22+
util.JSONResponse(res, http.StatusUnauthorized, err.Error(), nil)
23+
return
24+
}
25+
// user := map[string]any{
26+
// "email": "local@test.com",
27+
// "fullName": "Local Test User",
28+
// "id": "00000000-0000-0000-0000-000000000000",
29+
// "role": "user",
30+
// "userName": "localtester",
31+
// }
32+
logger.Info(fmt.Sprintf("User: %v", user))
33+
34+
// -----------------------------
35+
// PARSE JSON BODY
36+
// -----------------------------
37+
data, err := util.Body(req)
38+
if err != nil {
39+
util.JSONResponse(res, http.StatusBadRequest, err.Error(), nil)
40+
return
41+
}
42+
43+
bo, err := modules.BOFromJSON(data)
44+
if err != nil {
45+
util.JSONResponse(res, http.StatusBadRequest, err.Error(), nil)
46+
return
47+
}
48+
49+
// -----------------------------
50+
// GENERATE PYTHON CODE
51+
// -----------------------------
52+
code, err := bo.Code()
53+
if err != nil {
54+
util.JSONResponse(res, http.StatusBadRequest, err.Error(), nil)
55+
return
56+
}
57+
58+
// -----------------------------
59+
// CONNECT DB
60+
// -----------------------------
61+
db, err := connection.PoolConn(req.Context())
62+
if err != nil {
63+
logger.Error(fmt.Sprintf("CreateBO.PoolConn: %s", err.Error()))
64+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
65+
return
66+
}
67+
68+
// -----------------------------
69+
// INSERT RUN METADATA
70+
// -----------------------------
71+
runName := fmt.Sprintf("BO-%dD", len(bo.Bounds))
72+
73+
row := db.QueryRow(req.Context(), `
74+
INSERT INTO run (name, description, type, command, createdBy)
75+
VALUES ($1, $2, $3, $4, $5)
76+
RETURNING id
77+
`, runName, "Bayesian Optimization", "bo", "python code.py", user["id"])
78+
79+
var runID string
80+
err = row.Scan(&runID)
81+
if err != nil {
82+
logger.Error(fmt.Sprintf("CreateBO.row.Scan: %s", err.Error()))
83+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
84+
return
85+
}
86+
87+
logger.Info(fmt.Sprintf("RunID: %s", runID))
88+
89+
// -----------------------------
90+
// ACCESS TABLE ENTRY
91+
// -----------------------------
92+
_, err = db.Exec(req.Context(), `
93+
INSERT INTO access (runID, userID, mode)
94+
VALUES ($1, $2, $3)
95+
`, runID, user["id"], "write")
96+
97+
if err != nil {
98+
logger.Error(fmt.Sprintf("CreateBO.db.Exec: %s", err.Error()))
99+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
100+
return
101+
}
102+
103+
// -----------------------------
104+
// UPLOAD PYTHON CODE TO MINIO
105+
// -----------------------------
106+
os.Mkdir("code", 0755)
107+
pythonPath := fmt.Sprintf("code/%v.py", runID)
108+
109+
if err := os.WriteFile(pythonPath, []byte(code), 0644); err != nil {
110+
logger.Error(fmt.Sprintf("CreateBO.WriteFile: %s", err.Error()))
111+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
112+
return
113+
}
114+
if err := util.UploadFile(req.Context(), runID, "code", "py"); err != nil {
115+
util.JSONResponse(res, http.StatusInternalServerError, err.Error(), nil)
116+
return
117+
}
118+
119+
// -----------------------------
120+
// UPLOAD INPUT JSON
121+
// -----------------------------
122+
inputParams, err := json.Marshal(data)
123+
if err != nil {
124+
logger.Error(fmt.Sprintf("CreateBO.Marshal: %s", err.Error()))
125+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
126+
return
127+
}
128+
129+
os.Mkdir("input", 0755)
130+
inputPath := fmt.Sprintf("input/%v.json", runID)
131+
132+
if err := os.WriteFile(inputPath, inputParams, 0644); err != nil {
133+
logger.Error(fmt.Sprintf("CreateBO.WriteFile(input): %s", err.Error()))
134+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
135+
return
136+
}
137+
if err := util.UploadFile(req.Context(), runID, "input", "json"); err != nil {
138+
util.JSONResponse(res, http.StatusInternalServerError, err.Error(), nil)
139+
return
140+
}
141+
142+
// -----------------------------
143+
// CLEAN UP LOCAL FILES
144+
// -----------------------------
145+
os.Remove(pythonPath)
146+
os.Remove(inputPath)
147+
148+
// -----------------------------
149+
// PUSH TO REDIS QUEUE
150+
// -----------------------------
151+
if err := util.EnqueueRunRequest(req.Context(), runID, "code", "py"); err != nil {
152+
util.JSONResponse(res, http.StatusInternalServerError, err.Error(), nil)
153+
return
154+
}
155+
156+
// Attach runID to response
157+
data["runID"] = runID
158+
159+
util.JSONResponse(res, http.StatusOK, "BO Created Successfully 🎉", data)
160+
}

controller/mobo.go

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package controller
2+
3+
import (
4+
"encoding/json"
5+
"evolve/db/connection"
6+
"evolve/modules"
7+
"evolve/util"
8+
"fmt"
9+
"net/http"
10+
"os"
11+
)
12+
13+
func CreateMOBO(res http.ResponseWriter, req *http.Request) {
14+
logger := util.NewLogger()
15+
logger.Info("CreateMOBO API called.")
16+
17+
// -----------------------------
18+
// AUTHENTICATE USER
19+
// -----------------------------
20+
user, err := modules.Auth(req)
21+
if err != nil {
22+
util.JSONResponse(res, http.StatusUnauthorized, err.Error(), nil)
23+
return
24+
}
25+
// For local testing:
26+
// user := map[string]any{
27+
// "email": "local@test.com",
28+
// "fullName": "Local Test User",
29+
// "id": "00000000-0000-0000-0000-000000000000",
30+
// "role": "user",
31+
// "userName": "localtester",
32+
// }
33+
logger.Info(fmt.Sprintf("User: %v", user))
34+
35+
// -----------------------------
36+
// PARSE JSON BODY
37+
// -----------------------------
38+
data, err := util.Body(req)
39+
if err != nil {
40+
util.JSONResponse(res, http.StatusBadRequest, err.Error(), nil)
41+
return
42+
}
43+
44+
mobo, err := modules.MOBOFromJSON(data)
45+
if err != nil {
46+
util.JSONResponse(res, http.StatusBadRequest, err.Error(), nil)
47+
return
48+
}
49+
50+
// -----------------------------
51+
// GENERATE PYTHON CODE
52+
// -----------------------------
53+
code, err := mobo.Code()
54+
if err != nil {
55+
util.JSONResponse(res, http.StatusBadRequest, err.Error(), nil)
56+
return
57+
}
58+
59+
// -----------------------------
60+
// CONNECT DB
61+
// -----------------------------
62+
db, err := connection.PoolConn(req.Context())
63+
if err != nil {
64+
logger.Error(fmt.Sprintf("CreateMOBO.PoolConn: %s", err.Error()))
65+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
66+
return
67+
}
68+
69+
// -----------------------------
70+
// INSERT RUN METADATA
71+
// -----------------------------
72+
runName := fmt.Sprintf("MOBO-%s-%dD", mobo.Problem, len(mobo.Bounds))
73+
74+
row := db.QueryRow(req.Context(), `
75+
INSERT INTO run (name, description, type, command, createdBy)
76+
VALUES ($1, $2, $3, $4, $5)
77+
RETURNING id
78+
`, runName, "Multi-Objective Bayesian Optimization", "bo", "python mobo.py", user["id"])
79+
80+
var runID string
81+
err = row.Scan(&runID)
82+
if err != nil {
83+
logger.Error(fmt.Sprintf("CreateMOBO.row.Scan: %s", err.Error()))
84+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
85+
return
86+
}
87+
88+
logger.Info(fmt.Sprintf("MOBO RunID: %s", runID))
89+
90+
// -----------------------------
91+
// ACCESS TABLE ENTRY
92+
// -----------------------------
93+
_, err = db.Exec(req.Context(), `
94+
INSERT INTO access (runID, userID, mode)
95+
VALUES ($1, $2, $3)
96+
`, runID, user["id"], "write")
97+
98+
if err != nil {
99+
logger.Error(fmt.Sprintf("CreateMOBO.db.Exec: %s", err.Error()))
100+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
101+
return
102+
}
103+
104+
// -----------------------------
105+
// UPLOAD PYTHON CODE TO MINIO
106+
// -----------------------------
107+
os.Mkdir("mobo", 0755)
108+
pythonPath := fmt.Sprintf("mobo/%v.py", runID)
109+
110+
if err := os.WriteFile(pythonPath, []byte(code), 0644); err != nil {
111+
logger.Error(fmt.Sprintf("CreateMOBO.WriteFile: %s", err.Error()))
112+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
113+
return
114+
}
115+
if err := util.UploadFile(req.Context(), runID, "mobo", "py"); err != nil {
116+
util.JSONResponse(res, http.StatusInternalServerError, err.Error(), nil)
117+
return
118+
}
119+
120+
// -----------------------------
121+
// UPLOAD INPUT JSON
122+
// -----------------------------
123+
inputParams, err := json.Marshal(data)
124+
if err != nil {
125+
logger.Error(fmt.Sprintf("CreateMOBO.Marshal: %s", err.Error()))
126+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
127+
return
128+
}
129+
130+
os.Mkdir("input", 0755)
131+
inputPath := fmt.Sprintf("input/%v.json", runID)
132+
133+
if err := os.WriteFile(inputPath, inputParams, 0644); err != nil {
134+
logger.Error(fmt.Sprintf("CreateMOBO.WriteFile(input): %s", err.Error()))
135+
util.JSONResponse(res, http.StatusInternalServerError, "something went wrong", nil)
136+
return
137+
}
138+
if err := util.UploadFile(req.Context(), runID, "input", "json"); err != nil {
139+
util.JSONResponse(res, http.StatusInternalServerError, err.Error(), nil)
140+
return
141+
}
142+
143+
// -----------------------------
144+
// CLEAN UP LOCAL FILES
145+
// -----------------------------
146+
os.Remove(pythonPath)
147+
os.Remove(inputPath)
148+
149+
// -----------------------------
150+
// PUSH TO REDIS QUEUE
151+
// -----------------------------
152+
if err := util.EnqueueRunRequest(req.Context(), runID, "mobo", "py"); err != nil {
153+
util.JSONResponse(res, http.StatusInternalServerError, err.Error(), nil)
154+
return
155+
}
156+
157+
// Attach runID to response
158+
data["runID"] = runID
159+
160+
util.JSONResponse(res, http.StatusOK, "MOBO Created Successfully 🎉", data)
161+
}

main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ func main() {
5454
mux.HandleFunc(routes.GP, controller.CreateGP)
5555
mux.HandleFunc(routes.ML, controller.CreateML)
5656
mux.HandleFunc(routes.PSO, controller.CreatePSO)
57+
mux.HandleFunc(routes.BO, controller.CreateBO)
58+
mux.HandleFunc(routes.MOBO, controller.CreateMOBO)
5759
mux.HandleFunc(routes.RUNS, controller.UserRuns)
5860
mux.HandleFunc(routes.SHARE_RUN, controller.ShareRun)
5961
mux.HandleFunc(routes.RUN, controller.UserRun)

0 commit comments

Comments
 (0)