From 6270afb09d64ec26b77b22056e159469aa5bb82f Mon Sep 17 00:00:00 2001 From: David Eliahu Date: Mon, 16 Sep 2019 16:40:07 -0700 Subject: [PATCH 1/2] Support "None" dims in model signatures --- cli/cmd/get.go | 17 +++++++++-------- pkg/lib/cast/interface.go | 24 ++++++++++++++++++++++++ pkg/lib/json/json.go | 4 ++-- pkg/operator/api/schema/schema.go | 4 ++-- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/cli/cmd/get.go b/cli/cmd/get.go index 5060726bb4..9500fa197a 100644 --- a/cli/cmd/get.go +++ b/cli/cmd/get.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cobra" "github.com/cortexlabs/cortex/pkg/consts" + "github.com/cortexlabs/cortex/pkg/lib/cast" "github.com/cortexlabs/cortex/pkg/lib/console" "github.com/cortexlabs/cortex/pkg/lib/errors" "github.com/cortexlabs/cortex/pkg/lib/json" @@ -417,12 +418,12 @@ func classificationMetricsTable(apiMetrics *schema.APIMetrics) string { func describeModelInput(groupStatus *resource.APIGroupStatus, apiEndpoint string) string { if groupStatus.Available() == 0 { - return "waiting for api to be ready" + return "the model's input schema will be available when the API is live" } modelInput, err := getModelInput(urls.Join(apiEndpoint, "signature")) if err != nil { - return "waiting for api to be ready" + return "error retreiving the model's input schema: " + err.Error() } rows := make([][]interface{}, len(modelInput.Signature)) @@ -430,11 +431,7 @@ func describeModelInput(groupStatus *resource.APIGroupStatus, apiEndpoint string for inputName, featureSignature := range modelInput.Signature { shapeStr := make([]string, len(featureSignature.Shape)) for idx, dim := range featureSignature.Shape { - if dim == 0 { - shapeStr[idx] = "?" - } else { - shapeStr[idx] = s.Int(dim) - } + shapeStr[idx] = s.ObjFlatNoQuotes(dim) } rows[rowNum] = []interface{}{ inputName, @@ -468,11 +465,15 @@ func getModelInput(infoAPIPath string) (*schema.ModelInput, error) { } var modelInput schema.ModelInput - err = json.Unmarshal(response, &modelInput) + err = json.DecodeWithNumber(response, &modelInput) if err != nil { return nil, errors.Wrap(err, "unable to parse model input response") } + for _, featureSignature := range modelInput.Signature { + featureSignature.Shape = cast.CastJSONNumbers(featureSignature.Shape) + } + return &modelInput, nil } diff --git a/pkg/lib/cast/interface.go b/pkg/lib/cast/interface.go index 4d981a8770..445372049d 100644 --- a/pkg/lib/cast/interface.go +++ b/pkg/lib/cast/interface.go @@ -391,6 +391,30 @@ func JSONNumberToIntOrFloat(in interface{}) (interface{}, bool) { return nil, false } +func CastJSONNumber(in interface{}) interface{} { + number, ok := in.(json.Number) + if !ok { + return in + } + inInt, err := number.Int64() + if err == nil { + return inInt + } + inFloat, err := number.Float64() + if err == nil { + return inFloat + } + return in // unexpected +} + +func CastJSONNumbers(in []interface{}) []interface{} { + casted := make([]interface{}, len(in)) + for i, element := range in { + casted[i] = CastJSONNumber(element) + } + return casted +} + func InterfaceToInterfaceSlice(in interface{}) ([]interface{}, bool) { if in == nil { return nil, true diff --git a/pkg/lib/json/json.go b/pkg/lib/json/json.go index c7ed13a493..61d10d368e 100644 --- a/pkg/lib/json/json.go +++ b/pkg/lib/json/json.go @@ -34,8 +34,8 @@ func Marshal(obj interface{}) ([]byte, error) { return jsonBytes, nil } -func Unmarshal(data []byte, dst interface{}) error { - if err := json.Unmarshal(data, dst); err != nil { +func Unmarshal(jsonBytes []byte, dst interface{}) error { + if err := json.Unmarshal(jsonBytes, dst); err != nil { return errors.Wrap(err, errStrUnmarshalJSON) } return nil diff --git a/pkg/operator/api/schema/schema.go b/pkg/operator/api/schema/schema.go index e28e80bc53..1ded820ae0 100644 --- a/pkg/operator/api/schema/schema.go +++ b/pkg/operator/api/schema/schema.go @@ -54,8 +54,8 @@ type GetDeploymentsResponse struct { } type FeatureSignature struct { - Shape []int `json:"shape"` - Type string `json:"type"` + Shape []interface{} `json:"shape"` + Type string `json:"type"` } type ModelInput struct { From afb4972f01d2d2e06696561b7a42a97647575fc1 Mon Sep 17 00:00:00 2001 From: David Eliahu Date: Mon, 16 Sep 2019 16:42:31 -0700 Subject: [PATCH 2/2] Rename CastJSONNumber --- cli/cmd/get.go | 2 +- pkg/lib/cast/interface.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/cmd/get.go b/cli/cmd/get.go index 9500fa197a..38abcf90a9 100644 --- a/cli/cmd/get.go +++ b/cli/cmd/get.go @@ -471,7 +471,7 @@ func getModelInput(infoAPIPath string) (*schema.ModelInput, error) { } for _, featureSignature := range modelInput.Signature { - featureSignature.Shape = cast.CastJSONNumbers(featureSignature.Shape) + featureSignature.Shape = cast.JSONNumbers(featureSignature.Shape) } return &modelInput, nil diff --git a/pkg/lib/cast/interface.go b/pkg/lib/cast/interface.go index 445372049d..dab3ea9d42 100644 --- a/pkg/lib/cast/interface.go +++ b/pkg/lib/cast/interface.go @@ -391,7 +391,7 @@ func JSONNumberToIntOrFloat(in interface{}) (interface{}, bool) { return nil, false } -func CastJSONNumber(in interface{}) interface{} { +func JSONNumber(in interface{}) interface{} { number, ok := in.(json.Number) if !ok { return in @@ -407,10 +407,10 @@ func CastJSONNumber(in interface{}) interface{} { return in // unexpected } -func CastJSONNumbers(in []interface{}) []interface{} { +func JSONNumbers(in []interface{}) []interface{} { casted := make([]interface{}, len(in)) for i, element := range in { - casted[i] = CastJSONNumber(element) + casted[i] = JSONNumber(element) } return casted }