Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions ml.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package lytics

import (
"time"
)

const (
mlEndpoint = "ml/:id"
mlListEndpoint = "ml"
)

// ML Struct
type ML struct {
Aid int `json:"aid"`
Config struct {
AutoTune bool `json:"auto_tune"`
BuildOnly bool `json:"build_only"`
Collect int `json:"collect"`
CustomSegmentIds interface{} `json:"custom_segment_ids"`
Internal bool `json:"internal"`
ModelType string `json:"model_type"`
ReRun bool `json:"re_run"`
TuneModel bool `json:"tune_model"`
UseContent bool `json:"use_content"`
UseEntStore bool `json:"use_ent_store"`
UseScores bool `json:"use_scores"`
} `json:"config"`
Created time.Time `json:"created"`
ID string `json:"id"`
IsActive bool `json:"is_active"`
IsHealthy bool `json:"is_healthy"`
Label string `json:"label"`
Name string `json:"name"`
Source string `json:"source"`
State string `json:"state"`
Target string `json:"target"`
Type string `json:"type"`
Updated time.Time `json:"updated"`
WorkIds []string `json:"work_ids"`
}

// GetMLModel returns the details for a single ML Model based on id
// https://learn.lytics.com/documentation/developer/api-docs/ml
func (l *Client) GetMLModel(id string) (ML, error) {
res := ApiResp{}
data := ML{}

// make the request
err := l.Get(parseLyticsURL(mlEndpoint, map[string]string{"id": id}), nil, nil, &res, &data)
if err != nil {
return ML{}, err
}
return data, nil
}

// GetMLModels returns all ML models for the account
// https://learn.lytics.com/documentation/developer/api-docs/ml
func (l *Client) GetMLModels() ([]ML, error) {
res := ApiResp{}
data := []ML{}

// make the request
err := l.Get(mlListEndpoint, nil, nil, &res, &data)
if err != nil {
return data, err
}

return data, nil
}

// Headers returns headers for tablewriter
func (m ML) Headers() []interface{} {
return []interface{}{
"Name", "ID", "Source", "Target", "Type", "Active", "Healthy",
}
}

// Row returns a row for tablewriter
func (m ML) Row() []interface{} {
// c := m.Config
return []interface{}{
m.Name, m.ID, m.Source, m.Target, m.Type, m.IsActive, m.IsHealthy,
}
}
44 changes: 44 additions & 0 deletions ml_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package lytics

import (
"testing"

"github.com/bmizerany/assert"
"github.com/jarcoal/httpmock"
"github.com/lytics/go-lytics/mock"
)

func TestGetMLModel(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
mock.RegisterMLMocks()

client := NewLytics(mock.MockApiKey, nil)
model, err := client.GetMLModel(mock.MockMLID)

assert.Equal(t, err, nil)
assert.Equal(t, model.ID, mock.MockMLID)
assert.Equal(t, model.Config.AutoTune, false)
}

func TestGetMLModels(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
mock.RegisterMLMocks()

client := NewLytics(mock.MockApiKey, nil)
models, err := client.GetMLModels()

assert.Equal(t, err, nil)
assert.Equal(t, len(models), 2)

first := models[0]

assert.Equal(t, first.IsActive, false)
assert.Equal(t, first.Name, "all::ly_binge_user")

second := models[1]

assert.Equal(t, second.Name, "all::ly_infrequent_user")
assert.Equal(t, second.IsHealthy, true)
}
34 changes: 34 additions & 0 deletions mock/json/get_ml_model.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"data": {
"aid": 1,
"config": {
"auto_tune": false,
"build_only": false,
"collect": 0,
"custom_segment_ids": null,
"internal": false,
"model_type": "",
"re_run": false,
"tune_model": false,
"use_content": false,
"use_ent_store": false,
"use_scores": false
},
"created": "2020-10-24T00:11:22.842Z",
"id": "d3df420e45ed9ce36d95d5ad89b0ff37",
"is_active": false,
"is_healthy": false,
"label": "",
"name": "test01",
"source": "0d560ecb1d6024ceb0d738d114a6bc1a",
"state": "building",
"target": "c15f12e27b791652845c05458c95e5a3",
"type": "",
"updated": "2020-10-24T04:27:24.827Z",
"work_ids": [
"829c1088092e59189c4c4f52488b3fc4"
]
},
"message": "success",
"status": 200
}
69 changes: 69 additions & 0 deletions mock/json/get_ml_models.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"data": [{
"aid": 1,
"config": {
"auto_tune": false,
"build_only": true,
"collect": 0,
"custom_segment_ids": null,
"internal": false,
"model_type": "",
"re_run": false,
"tune_model": false,
"use_content": false,
"use_ent_store": false,
"use_scores": false
},
"created": "2020-10-23T22:06:45.972Z",
"id": "3a539197927ed11b0124d7d34a642174",
"is_active": false,
"is_healthy": true,
"label": "",
"name": "all::ly_binge_user",
"source": "757157f2b33143c04a247d93e71e390b",
"state": "complete",
"target": "22188a35b22888715066812682af8d3c",
"type": "",
"updated": "2020-10-23T22:55:36.755Z",
"work_ids": [
"6db152e9b673cb50192b428fd5fe3377",
"7830f8ace7ae7b0d7d6e995a7825b189",
"e196086c3245fcc826d5ef03b6e2d20b"
]
},
{
"aid": 1,
"config": {
"auto_tune": false,
"build_only": true,
"collect": 0,
"custom_segment_ids": null,
"internal": false,
"model_type": "",
"re_run": false,
"tune_model": false,
"use_content": false,
"use_ent_store": false,
"use_scores": false
},
"created": "2020-10-23T22:07:00.753Z",
"id": "05e49527930663222458428f3ebc9775",
"is_active": false,
"is_healthy": true,
"label": "",
"name": "all::ly_infrequent_user",
"source": "757157f2b33143c04a247d93e71e390b",
"state": "complete",
"target": "0d560ecb1d6024ceb0d738d114a6bc1a",
"type": "",
"updated": "2020-10-23T23:34:04.836Z",
"work_ids": [
"17951e000baae7e6e39a1971a1eb5f31",
"5b0e6b75dde8df02e1501aca0675a9be",
"7715f7964f766f556d11324b864f94ca"
]
}
],
"message": "success",
"status": 200
}
1 change: 1 addition & 0 deletions mock/lytics_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
MockSegmentCollection = "92630989bbea40f7b830f2"
MockCampaignID = "4a5984e1138646bb9d692c"
MockVariationID = "572d930921c447348ed424"
MockMLID = "d3df420e45ed9ce36d95d5ad89b0ff37"
MockSegmentMLID = "default_anon_seg::ly_binge_user"
MockTopicID = "mock"
)
Expand Down
51 changes: 51 additions & 0 deletions mock/ml_mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package mock

import (
"net/http"

"github.com/jarcoal/httpmock"
)

func RegisterMLMocks() {
// *******************************************************
// GET SINGLE ML MODEL
// *******************************************************
httpmock.RegisterResponder("GET", "https://api.lytics.io/api/ml/"+MockMLID,
func(req *http.Request) (*http.Response, error) {
var fail bool

queries := req.URL.Query()

if queries.Get("key") != MockApiKey {
fail = true
}

if fail {
return httpmock.NewStringResponse(401, readJsonFile("get_error")), nil
}

return httpmock.NewStringResponse(200, readJsonFile("get_ml_model")), nil
},
)

// *******************************************************
// GET ALL ML MODELS
// *******************************************************
httpmock.RegisterResponder("GET", "https://api.lytics.io/api/ml",
func(req *http.Request) (*http.Response, error) {
var fail bool

queries := req.URL.Query()

if queries.Get("key") != MockApiKey {
fail = true
}

if fail {
return httpmock.NewStringResponse(401, readJsonFile("get_error")), nil
}

return httpmock.NewStringResponse(200, readJsonFile("get_ml_models")), nil
},
)
}